Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Layout doesn't work with Sprite? — Gideros Forum

Layout doesn't work with Sprite?

rrraptorrrraptor Member
edited November 2019 in General questions
First, anchor parameter does nothing, second, if fill parameter is not LAYOUT_FILL_BOTH, the sprite always be in top left corner of the holder (otherwise in top left corner of the assigned cell).
Maybe its me not understanding how it all works?

application:setBackgroundColor(0x323232)
 
foo = Core.class(Sprite)
 
function foo:init(w,h)
	self.px = Pixel.new(0xff0000, 0.5, w, h)
	self.px:setAnchorPoint(.5,.5)
	self:addChild(self.px)
end
 
local myholder = Pixel.new(0x0, 0.5, 96, 96)
myholder:setPosition(8, 8)
myholder:setLayoutParameters({
	columnWeights = {1, 1, 1},
	rowWeights = {1, 1, 1}, 
	columnWidths = {64, 64, 64}, 
	rowHeights = {64, 64, 64},
})
 
local mybtn1 = foo.new(4, 4)
mybtn1:setLayoutConstraints({
	gridx = 1,
	gridy = 0,
	gridwidth = 1,
	gridheight = 1,
	anchor = Sprite.LAYOUT_ANCHOR_CENTER,
	fill = Sprite.LAYOUT_FILL_BOTH,
})
myholder:addChild(mybtn1)
 
local mybtn2 = Pixel.new(0x00ff00, 0.3, 2, 2)
mybtn2:setAnchorPoint(.5,.5)
mybtn2:setLayoutConstraints({
	gridx = 1,
	gridy = 1,
	gridwidth = 1,
	gridheight = 1,
	anchor = Sprite.LAYOUT_ANCHOR_CENTER,
	fill = Sprite.LAYOUT_FILL_BOTH,
})
myholder:addChild(mybtn2)
 
local rt = RenderTarget.new(32,32)
rt:clear(0x00ffff, 0.3)
local mybtn3 = Bitmap.new(rt)
mybtn3:setAnchorPoint(.5,.5)
mybtn3:setLayoutConstraints({
	gridx = 2,
	gridy = 2,
	gridwidth = 1,
	gridheight = 1,
	anchor = Sprite.LAYOUT_ANCHOR_CENTER,
	fill = Sprite.LAYOUT_FILL_BOTH,
})
myholder:addChild(mybtn3)

Comments

  • hgy29hgy29 Maintainer
    Can you post of screenshot of it gives and what you would have expected ?
  • rrraptorrrraptor Member
    edited November 2019
    @hgy29 I have this:
    application:setBackgroundColor(0x323232)
     
    foo = Core.class(Sprite)
     
    function foo:init(w,h)
    	self.px = Pixel.new(0xff0000, 0.5, w, h)
    	self.px:setAnchorPoint(.5,.5)
    	self:addChild(self.px)
    end
     
    local myholder = Pixel.new(0x0, 0.5, 192, 192)
    myholder:setPosition(8, 8)
    myholder:setLayoutParameters({
    	columnWeights = {1, 1, 1},
    	rowWeights = {1, 1, 1}, 
    	columnWidths = {64, 64, 64}, 
    	rowHeights = {64, 64, 64},
    })
     
    local mybtn1 = foo.new(10, 10)
    mybtn1:setLayoutConstraints({
    	gridx = 1,
    	gridy = 0,
    	gridwidth = 1,
    	gridheight = 1,
    	anchor = Sprite.LAYOUT_ANCHOR_CENTER,
    	fill = Sprite.LAYOUT_FILL_BOTH,
    })
    myholder:addChild(mybtn1)
    myholder:setPosition(50, 50)
    stage:addChild(myholder)


    When I run code, Im getting this:

    First, if I remove fill property from "mybtn1", it will appear in top left corner of the "myholder", second, I set anchor to center, so I assume, that my sprite object will be in the center of the cell like this:

    But, it's not happening for some reason...
    test.jpg
    297 x 305 - 8K
    test2.jpg
    288 x 285 - 8K
  • rrraptorrrraptor Member
    edited November 2019
    Actually, I made my own system, that is more flexible I think :blush:

    Result of this code
    application:setBackgroundColor(0x323232)
     
    local font = TTFont.new("18VAG_Rounded_M_Bold.ttf", 12, "", 1)
     
    local function tf(text, ax, ay)
    	ax = ax or 0
    	ay = ay or 0
    	local p = TextField.new(font, text, "|")
    	p:setTextColor(0x151515)
    	p:setScale(1.2)
    	p:setAnchorPoint(ax,ay)
    	return p
    end
     
    local win = GWindow.new(500, 400)
    win:setPosition(50, 50)
     
    -- split main window on 4 subsections where width (or height, depending on direction 
    -- (horizontal or vertical)) defined by % of the root section (in this situation it will be 
    -- 500x400)
    -- you can also set absolute size, using "px" instead of "%"
    local p1 = win:split(4, "horizontal", {10, 15, 60, 15}, "%")
     
    -- split first line on 3 subsection vertically
    local l1 = p1:split(1, 3, "vertical", {15, 70, 15}, "%")
    -- if size table is not set, sections will be equally divided
    local l2 = p1:split(2, 3, "vertical")
    local l4 = p1:split(4, 2, "vertical")
     
    -- add to first cell of first line at center a text field with anchor in center
    l1:add(1, tf("Top left", 0.5, 0.5), 0.5, 0.5)
    l1:add(3, tf("Top right", 0.5, 0.5), 0.5, 0.5)
     
    l2:add(1, tf("Second line left", 1, 1), 1, 1)
    l2:add(2, tf("Second line mid", 0, 0), 0, 0.05)
    l2:add(3, tf("Second line right", 1, 0.5), 1, 0.5)
     
    p1:add(3, tf("Body?"), 0.5, 0.5)
     
    l4:add(1, tf("Bottom left", 0, 1), 0, 1)
    l4:add(2, tf("Bottom right", 1, 0), 1, 0.05)
     
    stage:addChild(win)

    Will be this:


    P.S. if someone need this, I can share source code. But, it does not support size change yet.
    asd.jpg
    728 x 582 - 36K

    Likes: MoKaLux, antix

    asd.jpg 35.9K
    +1 -1 (+2 / -0 )Share on Facebook
  • And resize is done. The last thing, need to add absolute values support when resizing window, cuz right now its basically just handmade scale :smiley:
    function Frame:setSize(w, h)
    	local factorX = w / self.w
    	local factorY = h / self.h
    	self.w = w
    	self.h = h
    	-- if cell was subdivided and had childs, change their positions
    	reposItems(self, factorX, factorY)
     
    	for i, cell in ipairs(self.cells) do 
    		-- no subdivision
    		if (#cell.cells == 0) then
    			local v = self.t[i] -- < self.t contains absolute or % values of widths/heights
    			cell.x *= factorX
    			cell.y *= factorY
    			cell.w *= factorX
    			cell.h *= factorY
    			if (DEBUG_DRAW) then 
    				-- black bg to see the area
    				cell.__bg:setDimensions(cell.w - DEBUG_OFFSET, cell.h - DEBUG_OFFSET)
    				cell.__bg:setPosition(cell.x + DEBUG_OFFSET/2, cell.y + DEBUG_OFFSET/2)
    			end
     
    			-- reposition childs
    			reposItems(cell, factorX, factorY)
    		else
    			cell:setSize(cell.w*factorX,cell.h*factorY)
    		end
    	end
    end


    GIF:

    test.gif
    689 x 368 - 299K
    test.gif 299.2K
    +1 -1 (+4 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    Accepted Answer
    @rraptor,
    I finally got time to try your code and it turns out that yes, layout doesn't work with just Sprite. Builtin layout need to be able to set the size of its content, which is not possible with simple sprites. It works for Pixel and Textfield, but anything else is problematic. I think this is a bug though, since anyhow built in layout should try to make his best to handle Sprite. I will look into it.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • Damn, I spent whole week trying to add absolute values support after resize, and finally I made it. There is still one bug (at least I know only 1 and you can see it on a gif), but its nothing compared to what I had before.

    GIF:

    test2.gif
    786 x 439 - 261K

    Likes: oleg, MoKaLux

    +1 -1 (+2 / -0 )Share on Facebook
  • @rrraptor that's very cool man! It seems that we are both working on the same kind of project, but in different ways.

    Whilst you are going for the full on "auto layout approach", I'm taking a more traditional "absolute positioning" approach.

    Is your solution created entirely in Gideros?

    I'm currently using Electron, which gives HTML pages using JavaScript the ability to load and save files on the local hard drive.
  • rrraptorrrraptor Member
    edited November 2019
    antix said:

    @rrraptor that's very cool man! It seems that we are both working on the same kind of project, but in different ways.

    My goal is to create a system where you can easily create forms FROM CODE. At first, I thought maybe it would be good to create some sort of form editor with absolute positioning, but it requires a lot more time AND UI elements.
    A quick example:
    local win = Frame.new(400, 200) 
    win:addRows{
     {type="px", value=50}, 
     {type="%", value=50}, 
     {type="%", value=50}, 
     {type="px", value=30}, 
    }
    Create window with 4 rows, 1st is 50 pixels, 4th is 30, 2 and 3 is 50% of 200-(50+30) which is 60 pixels.
    local body = win:addSubCols(2, {
     {type="%", value=100}, 
     {type="px", value=80}, 
     {type="px", value=80}, 
    })
    Add subframe with 3 columns to 2d row.
    Then you can add any item you want using "add" method. It will be inserted right after (below or to the right, depending on your needs) previously added item.
    antix said:


    Is your solution created entirely in Gideros?

    Yes :smile:
  • hgy29hgy29 Maintainer
    Great to see that we have several UI projects being developed, this will give more choices to the community. Mine is almost done, but needs to be put into action in real projects to see how fit it could be in reality.

    Likes: MoKaLux, antix

    +1 -1 (+2 / -0 )Share on Facebook
  • olegoleg Member
    edited November 2019
    rrraptor said:

    local win = Frame.new(400, 200) 
    win:addRows{
     {type="px", value=50}, 
     {type="%", value=50}, 
     {type="%", value=50}, 
     {type="px", value=30}, 
    }
    There is another variant of positioning - binding to the screen grid
    Multiple grids of different sizes are created for the screen
    Then some elements are tied to a larger grid and others to a smaller grid
    When changing screen proportions this way is better.
    {type="grid", value=screenW/sizeGrid*numRow+posX},

    Likes: MoKaLux

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 )Share on Facebook
  • @rrraptor very cool for being 100% Gideros! You will still need buttons, sliders, and al that jazz though won't you?
Sign In or Register to comment.