Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Gideros UI and layouts (WidgetKit) Thread — Gideros Forum

Gideros UI and layouts (WidgetKit) Thread


Hello everyone, while working on UI/UX for games, I stumbled upon the "Library/ui" folder which contains a variety of components like Buttons, Text, ScrollList, DropDown, and even a Calendar. So, I'm starting this thread hoping to engage with you all about Gideros' GUI system. I believe many of you might be interested as well. Please share any examples and questions related to this built-in UI and Layout system. I find its architecture and code quite lightweight, and with comprehensive documentation and examples, it has great potential!

@hgy29 I hope that when you have the time, you will post some small examples and tutorials about this system so that everyone can use it and make it more popular!
I now start reading setLayouttConstraints/ setLayoutParameters in https://wiki.gideros.rocks/index.php/Sprite:setLayoutConstraints

Likes: MoKaLux

Coming soon
+1 -1 (+1 / -0 )Share on Facebook
«1

Comments

  • hgy29hgy29 Maintainer
    Hi, here is the test code I use to ensure everything works correctly when I update the widget kit. This demo doesn't show all the features of this UI kit, but most of it.
    zip
    zip
    UIDemo.zip
    235K
    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    I wanted to write a few snippets about Gideros UI library, but I don't have access to the wiki currently so I write them here.

    First of all, in order to use Gideros UI Library (GUIL ?) you have to link two folders to your project: Library/ui and Library/luashaders from your Gideros installation (GUIL depends on luashaders).

    Now a first example to make a very simple Button:
    local button=UI.Button.new()
    button:setDimensions(200,50)
    button:setPosition(50,50)
    button:setText("Click me!")
     
    function button:onWidgetAction()
    	print("Hello UI World!")
    end
     
    stage:addChild(button)
    Straightforward, right ?
    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    New with two buttons, introducing the events system:
    local buttonA=UI.Button.new()
    buttonA:setDimensions(200,50)
    buttonA:setPosition(50,50)
    buttonA:setText("Click me!")
     
    local buttonB=UI.Button.new()
    buttonB:setDimensions(200,50)
    buttonB:setPosition(50,150)
    buttonB:setText("Don't click me!")
     
    stage:addChild(buttonA)
    stage:addChild(buttonB)
     
    --Here we put the WidgetAction listener on stage. 
    --It will be propagated from each button up to stage through the sprite tree
    --First parameter of event listeners are always the source widget of the event
    function stage:onWidgetAction(w)
    	if w==buttonA then
    		print("Yes that's it")
    	elseif w==buttonB then
    		print("You a rebel!")
    	end
    end
    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    Another example with Sliders this time:
    --Sliders give value from 0 to 1
    local sliderA=UI.Slider.new()
    sliderA:setDimensions(200,50)
    sliderA:setPosition(50,50)
    sliderA.name="Slider A"
     
    local sliderB=UI.Slider.new()
    sliderB:setDimensions(200,50)
    sliderB:setPosition(50,150)
    --This slider center is in the middle of the range
    sliderB:setCenter(.5)
    --Initial value is .6
    sliderB:setKnobPosition(.6)
    --Discrete steps of .1
    sliderB:setResolution(.1)
    sliderB.name="Slider B"
     
    stage:addChild(sliderA)
    stage:addChild(sliderB)
     
    --Here we put the WidgetAction listener on stage. 
    --It will be propagated from each button up to stage through the sprite tree
    --First parameter of event listeners are always the source widget of the event
    function stage:onWidgetChange(w,v)
    	print(w.name.." value is "..v)
    end
    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    Now a demo with two new widgets: a label (a simple non editable text widget), and a viewport (scrollable area):
    local label=UI.Label.new([[
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
     
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    ]],{ flags=FontBase.TLF_BREAKWORDS|FontBase.TLF_REF_LINETOP})
    label:setLayoutConstraints({fill=1})
     
    local viewport=UI.Viewport.new()
    viewport:setDimensions(application:getContentWidth(),application:getContentHeight())
    viewport:setContent(label)
    viewport:setScrollbar({UI.Viewport.SCROLLBAR.AUTO,UI.Viewport.SCROLLBAR.AUTO})
    stage:addChild(viewport)
    +1 -1 (+3 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    A last one for this evening: a textfield demo.
    For this to work you'll have to use a TTF font (it doesn't work well with gideros embedded font).

    In init.lua:
    UI={ 
    	Default={
    		TTF="OpenSans.ttf",
    	}
    }
    Then in main.lua:
    local tf=UI.TextField.new()
    tf:setDimensions(200,50)
    tf:setPosition(50,50)
    tf:setTipText("Enter your name and press enter")
     
    function tf:onTextValid(w,txt)
    	print("Hello "..txt)
    end
     
    stage:addChild(tf)
    +1 -1 (+3 / -0 )Share on Facebook
  • please allow me some time to test and document awesome GUIL GUI (Gideros UI) in the wiki.

    I am looking for a widget I may need for an app and I am testing all the options available through Gideros (ImGui, GUI, pure code, ...) and why not document it at the same time :p

    So I will start with the examples from hgy29 above and will try to add ALL of them God's willing ;)

    The wiki front page needs some more colors so I am looking into redesigning the front page as well :D

    Viva Gideros <3
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+2 / -0 )Share on Facebook
  • @MoKaLux
    I just saw a recent commit
    https://github.com/gideros/gideros/commit/2debc5adc414b0722540d6954fbe4905375c8cfd
    and it looks like we might be having some significant and amazing changes soon.
    Coming soon
  • MoKaLuxMoKaLux Member
    edited November 2023
    @vitalitymobile yes I am already using those ;)
    This is some serious stuff, started the wiki but not finished yet https://wiki.gideros.rocks/index.php/UI

    I tried getting the Accordion working with no luck, I will try another day, another time :p
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    edited October 2023
    @MoKaLux,

    Here is an Accordion example:
    local values={
    { title="Alice's Adventures in Wonderland",
    book=[[
    Alice's Adventures in Wonderland (commonly Alice in Wonderland) is an 1865 English children's novel by Lewis Carroll, a mathematics don at Oxford University. It details the story of a young girl named Alice who falls through a rabbit hole into a fantasy world of anthropomorphic creatures. It is seen as an example of the literary nonsense genre. The artist John Tenniel provided 42 wood-engraved illustrations for the book.
     
    It received positive reviews upon release and is now one of the best-known works of Victorian literature; its narrative, structure, characters and imagery have had a widespread influence on popular culture and literature, especially in the fantasy genre.[1][2] It is credited as helping end an era of didacticism in children's literature, inaugurating an era in which writing for children aimed to "delight or entertain".[3] The tale plays with logic, giving the story lasting popularity with adults as well as with children.[4] The titular character Alice shares her name with Alice Liddell, a girl Carroll knew.
     
    The book has never been out of print and has been translated into 174 languages. Its legacy covers adaptations for screen, radio, art, ballet, opera, musicals, theme parks, board games and video games.[5] Carroll published a sequel in 1871 entitled Through the Looking-Glass and a shortened version for young children, The Nursery "Alice" in 1890. ]]
    },
    { title="Peter and Wendy",
    book=[[
    Peter Pan; or, the Boy Who Wouldn't Grow Up, often known simply as Peter Pan, is a work by J. M. Barrie, in the form of a 1904 play and a 1911 novel titled Peter and Wendy, often extended in Peter Pan and Wendy. Both versions tell the story of Peter Pan, a mischievous little boy who can fly, and has many adventures on the island of Neverland that is inhabited by mermaids, fairies, Native Americans, and pirates. The Peter Pan stories also involve the characters Wendy Darling and her two brothers John and Michael, Peter's fairy Tinker Bell, the Lost Boys, and the pirate Captain Hook. The play and novel were inspired by Barrie's friendship with the Llewelyn Davies family.
     
    The play debuted at the Duke of York's Theatre in London on 27 December 1904 with Nina Boucicault, daughter of the playwright Dion Boucicault, in the title role. A Broadway production was mounted in 1905 starring Maude Adams. It was later revived with such actresses as Marilyn Miller and Eva Le Gallienne. Barrie continued to revise the play for years after its debut until publication of the play script in 1928, under the name Peter Pan; or, The Boy Who Would Not Grow Up.
     
    Prior to the publication of Barrie's novel, the play was first adapted into the 1907 novelisation The Peter Pan Picture Book, written by Daniel O'Connor and illustrated by Alice B. Woodward. This was also the first illustrated version of the story. The novel was first published in 1911 by Hodder & Stoughton in the UK, and Charles Scribner's Sons in the US. The original book contains a frontispiece and 11 half-tone plates by the artist F. D. Bedford (whose illustrations are still under copyright in the EU). The novel was first abridged by May Byron in 1915, with Barrie's permission, and published under the title Peter Pan and Wendy, the first time this form was used. This version was later illustrated by Mabel Lucie Attwell in 1921.
     
    Since its original production, the story has been adapted as a pantomime, a stage musical, a television special, a live themed ice-skating show in the mid--1970's, and several films, including a 1924 silent film, a 1953 Disney animated film, and a 2003 live action film. The play is now rarely performed in its original form on stage in the UK, whereas pantomime adaptations are frequently staged around Christmas. In the U.S., the original version has also been supplanted in popularity by the 1954 musical version, which became popular on television. In 1929, Barrie gave the copyright of the Peter Pan works to Great Ormond Street Hospital, a children's hospital in London. ]]
    }
    }
     
    local vp=UI.Viewport.new()
    vp:setDimensions(application:getContentWidth(),application:getContentHeight())
    vp:setScrollbar({UI.Viewport.SCROLLBAR.AUTO,UI.Viewport.SCROLLBAR.ALWAYS})
     
    local ac=UI.Accordion.new()
    vp:setContent(ac)
    ac:setLayoutConstraints({fill=1})
     
    local function builder(v)
    	local hdr=UI.Label.new(v.title)
    	hdr:setStyle({ font="font.bold", ["label.color"]="colHighlight", colWidgetBack="colHeader"})
    	local lb=UI.Label.new(v.book,{ flags=FontBase.TLF_BREAKWORDS|FontBase.TLF_REF_TOP })
    	-- Return header and content
    	return hdr,lb
    end
    ac:setData(values,builder) --builder function will be called for each value in the values table
     
    stage:addChild(vp)
    Text credits: Wikipedia

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited October 2023
    MoKaLux said:

    This is some serious stuff, started the wiki but not finished yet https://wiki.gideros.rocks/index.php/UI

    Done, I documented what I could figure out :s . hgy29 UI is like Dear ImGui, BIG.

    I tried getting UI.TabbedPane working with no luck, hgy29 do you have a sample code please? o:)

    EDIT: thank you hgy29 for the fast response below ;)

    Likes: pie

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    edited October 2023
    MoKaLux said:


    I tried getting UI.TabbedPane working with no luck, hgy29 do you have a sample code please? o:)

    You can use the accordion demo, they work almost the same.
    Just change
    --local ac=UI.Accordion.new()
    local ac=UI.TabbedPane.new()
    It will work but won't look good unless you also add:
    	lb:setLayoutConstraints({fill=1})
    after creating the second label in the builder function.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • piepie Member
    Hi, is there a native way to know how much space will be occupied by a specific string of the default font set in init.lua using gideros UI?

    I mean for example:
    UI.Default = {
    	TTF=fontfile,
    	Fonts={
    		["font"]={ ttf=fontfile, size=1.5 },
    		["font.small"]={ ttf=fontfile, size=0.5 },
    		["font.bold"]={ ttf=fontfilebold },
    	}
    }
    which will be the width and height of UI.Default.Fonts.font if I write "A00C"?

    thank you
  • Can you tell me what am I doing wrong here? I'd like to put this textfield at the bottom of the screen, but no matter what I use in setPosition, it always ends in the same position:



     
    UI.Style:setDefault(UI.Theme.PointCore_Base)
    application:setBackgroundColor(0x000000)
    --disable keyboards
    UI.Keyboard.NATIVE=false
    UI.Keyboard.VIRTUAL=false
     
    local minX, minY, maxX, maxY = application:getLogicalBounds()
     
    local screen=UI.Screen.new()
     
     
     
     
    local cf=UI.TextField.new("", { readonly=true })
    cf:setText(
    ""
    )
     
     
    cf:setPosition(0,maxY*0.9)
    cf:setLayoutConstraints({ width=maxX*0.9, })
    screen:ui(cf)


    Thank you
  • MoKaLuxMoKaLux Member
    edited November 2023
    @pie would this do?
    UI.Style:setDefault(UI.Theme.PointCore_Base)
    application:setBackgroundColor(0x000000)
    --disable keyboards
    UI.Keyboard.NATIVE=false
    UI.Keyboard.VIRTUAL=false
     
    local minX, minY, maxX, maxY = application:getLogicalBounds()
     
    local screen=UI.Screen.new()
     
    local cf=UI.TextField.new("", { readonly=true })
    cf:setDimensions(256, 96) -- ADD THIS
    cf:setText("XXX")
     
    cf:setPosition(0,maxY*0.9)
    --cf:setLayoutConstraints({ width=maxX*0.9, })
    screen:ui(cf)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    pie said:

    Can you tell me what am I doing wrong here? I'd like to put this textfield at the bottom of the screen, but no matter what I use in setPosition, it always ends in the same position

    What about this instead ?
    --cf:setPosition(0,maxY*0.9)
    cf:setLayoutConstraints({ fillx=0.9, anchory=1, })

    Likes: pie

    +1 -1 (+1 / -0 )Share on Facebook
  • Thank you!
    MoKaLux said:

    @pie would this do?

    It might work but using pixel sizes I would miss the relative size stuff :) hgy29 solution is the way to do it.



    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • How to set UI.Button (but I guess any element) properties?
    I mean stuff like color, font, padding etc.. is there a list somewhere?

    my first attempt gave me this :D



    I'd like the button to fit in the last 1/10of the screen at the bottom, and it's there, but its content clearly is fit inside a bigger rectangle.
    -- a Button
    local button=UI.Button.new()
     
    button:setLayoutConstraints( { filly=0.1, fillx = 1, anchory = 1, anchorx = 0 } )
    button:setText("Button")
     
    function button:onWidgetAction()
    	print("Hello Gideros UI")
    end
     
     
    screen:ui(button)


    As a side question: why UI.screen is visible even if it's not explicitly added to stage? I found that adding it to stage is better for me because I know at which z-layer it is. Is there any side effect in this choice?

    I am still trying to understand how this UI works, please bear with me :)

    Thank you

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    pie said:

    Hi, is there a native way to know how much space will be occupied by a specific string of the default font set in init.lua using gideros UI?

    You can use FontBase:getBounds or FontBase:layoutText

    Likes: pie

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    pie said:

    How to set UI.Button (but I guess any element) properties?
    I mean stuff like color, font, padding etc.. is there a list somewhere?

    There is a definition table for each UI component, for example UI.Button.Definition. You can see it in the appropriate source file (here : https://github.com/gideros/gideros/blob/2023.11/Library/ui/uibutton.lua#L21). Each component inherits proprties from its base component, ultimately UI.Panel (https://github.com/gideros/gideros/blob/2023.11/Library/ui/uipanel.lua#L337).
    But if you are after visual properties, they should all be handled in style sheets. Have a look at uistyle.lua and if you are using a theme, the corresponding theme code.
    You can always apply a specific style to an UI Component, through UI.Panel:setStyle().
    pie said:

    As a side question: why UI.screen is visible even if it's not explicitly added to stage?

    Because it is so common to add it to the stage that creating it automatically does that. About side effects of not adding it directly, it may break automatic response to screen dimension changes.
    Note that UI.Screen already handle several layers by itself: it has a fullscreen() layer covering all the device screen, then an ui() screen above excluding notch and round corners. If you need more, you can add other layers before or after you UI.Screen in stage.
    +1 -1 (+2 / -0 )Share on Facebook
  • Thank you as always @hgy29 :)
    I now noticed that you also built a UI.Builder, which seems to provide a much cleaner approach to this UI.
    Does it do the same thing as writing each element by hand or there are certain situations where one approach is better than the other?

    I had a look to the styles now and I was wondering what does the "s" after the value mean in
    ["buttontextfield.szInset"]="0.25s",
    ["buttontextfield.szMargin"]="0.5s",


    I think I understood that fill is applied on UI.Panel, while inside a panel we must use weight: one of the things I still don't understand is why my button is completely messed up, as if it is was placed inside a bigger panel that goes out of the screen:



    local startui=UI.Builder({
    	class="UI.Panel",
    	layoutModel=UI.Layout.Vertical,
    	layout={ fill=1},
    	children={
    		{ class="UI.TextField", 
    		  name="sourcetext", 
    		  layout={weighty=2, insets = 20},
    		  Flags={
    				readonly=true, 
    				selectable=true
    				},
     
    		  TextLayout={
    			  flags=FontBase.TLF_JUSTIFIED|FontBase.TLF_VCENTER|FontBase.TLF_REF_LINETOP|FontBase.TLF_BREAKWORDS, 
    			  multiline=true 
    			  },  
    		  Style={ font=TTFont.new("fonts/RetroGaming.ttf",40,"")}, 
    		  Color=0xFFFFFF
    		  },
    		{ class="UI.Button", 
    			Text="Button:", 
    			Color=0x0000aa, 
    			layout={weighty=0.5},
    			Style={ font=TTFont.new("fonts/RetroGaming.ttf",40,"")},
    		}
     
     
     
    	}
    })



  • hgy29hgy29 Maintainer
    pie said:


    I now noticed that you also built a UI.Builder, which seems to provide a much cleaner approach to this UI.
    Does it do the same thing as writing each element by hand or there are certain situations where one approach is better than the other?

    UI.Builder internallys create widgets as you would have done 'by hand', but the description table is more compact so sometimes easier to read and maintain. It comes at the cost of sometimes unnecessary code, depending on your use case.
    pie said:


    I had a look to the styles now and I was wondering what does the "s" after the value mean in
    ["buttontextfield.szInset"]="0.25s",
    ["buttontextfield.szMargin"]="0.5s",

    Styling rules support a few units after numbers, they are:
    - 's': unit dependent on font scale computed by the UI based on screen DPI
    - 'is': similar as 's' but used for 'icons', more precisely for objects that should be touch-able. They are the same on desktop, but is is typically bigger on phones.
    - 'em': unit based on current font size, typically to size things in 'number of characters'
    pie said:


    I still don't understand is why my button is completely messed up, as if it is was placed inside a bigger panel that goes out of the screen:

    Yes, button text is nested inside a UIImageText component, I will have a look at what is happening here.

    Likes: MoKaLux, pie

    +1 -1 (+2 / -0 )Share on Facebook
  • Thank you for the explanations :)
    hgy29 said:


    Yes, button text is nested inside a UIImageText component, I will have a look at what is happening here.

    If this may help I noticed that commenting the line
    UI.Style:setDefault(UI.Theme.PointCore_Base)
    the button behaves correctly.


    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • I am sorry I have another question: is it possible to know the bounds (x,y,w,h) against stage of an UI element built through UI.builder since its size and position may be different on different resolutions, fills and weights?

    I tried using stage:getBounds(myui.myelement) but I don't understand why the resulting y coordinate always results negative, and the width and height always exceed the logical bounds of my screen.

    Thank you :)

  • hgy29hgy29 Maintainer
    pie said:


    I tried using stage:getBounds(myui.myelement) but I don't understand why the resulting y coordinate always results negative, and the width and height always exceed the logical bounds of my screen.

    Didn't you want to do
    myui.myelement:getBounds(stage)
    instead, that is get the bounds of 'myelement' in the context of 'stage' ?

  • hgy29 said:


    Didn't you want to do

    myui.myelement:getBounds(stage)
    instead, that is get the bounds of 'myelement' in the context of 'stage' ?

    Yes, I tried that too but since my tests didn't work out as I was expecting I tried both on desperation :smiley:

    Can you please take a look and see what I am missing here?


    I think that the following code should build an UI and overlap each UI element with a colored shape, but this is the outcome: the project is set to PixelPerfect, if this could make a difference.





    --UI.Style:setDefault(UI.Theme.PointCore_Base)
    application:setBackgroundColor(0xFFFFFF)
    --disable keyboards
    UI.Keyboard.NATIVE=false
    UI.Keyboard.VIRTUAL=false
     
     
     
     
    local function drawRect(x1, y1, x2,y2, label, n)
     
    	local function getRdnCol(m)
    		local colors = {0xff0000, 0x0000ff, 0x00ff00, 0xdddddd, 0x000000}
    		return colors[m]
    	end
     
    	local shape = Shape.new()
    	shape:setFillStyle(Shape.SOLID, getRdnCol(n), 0.2)
    	shape:beginPath()
    	shape:moveTo(x1, y1)
    	shape:lineTo(x2, y1)
    	shape:lineTo(x2,y2)
    	shape:lineTo(x1, y2)
    	shape:lineTo(x1, y1)
    	shape:endPath()
     
    	if label then
    		local txt = "\e[color=#f0f]"..label.."\e[color]"
    		local l = TextField.new(nil, txt)
    		l:setScale(4)
    		l:setAnchorPoint(.5,.5)
    		shape:addChild(l)
    		l:setPosition((x1+x2)*.5, (y1+y2)*.5)
    	end
     
     
    	return shape
    end
     
     
    local screen=UI.Screen.new()
     
     
     
     
     
    local test = ([[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 
    ]])
     
     
     
     
     
    startui=UI.Builder({
    		class="UI.Panel",
    		layoutModel=UI.Layout.Vertical,
    		layout={ fill=0.5},
    		children={
    			{ class="UI.TextField", 
    			  name="textfield", 
    			  layout={weighty=2, insets = 20},
    			  --colText=
    			  Flags={
    					readonly=true, 
    					selectable=true
    					},
     
    			  TextLayout={
    				  flags=FontBase.TLF_JUSTIFIED|FontBase.TLF_REF_LINETOP|FontBase.TLF_BREAKWORDS, 
    				  multiline=true 
    				  },  
    			  Style={ font=TTFont.new("fonts/myfont.ttf",50,"")}, 
     
    			  },
    			{ class="UI.Button", 
    				name = "button",
    				Text="Button:", 
    				Color=0xCCCCCC, 
    				layout={weighty=0.5},
    				Style={ font=TTFont.new("fonts/myfont.ttf",80,"")},
    			}
     
     
     
    		}
    	})
     
     
    	startui.textfield:setText(test)
    	-- ui screen
     
    	screen=UI.Screen.new()
    	screen:ui(startui)
     
     
    	stage:addChild(screen)
     
     
    	function startui.button.onWidgetAction()
    		print("hello")
    	end
     
     
    	print("GETBOUNDS SCR ", screen:getBounds(stage))
    	print("GETBOUNDS UI ", startui:getBounds(stage) )
    	print("GETBOUNDS BTN ", startui.button:getBounds(stage) )
    	print("LogicalBounds", application:getLogicalBounds() )
    	print("CONTENTW CONH", application:getContentWidth(), application:getContentHeight() )
    	print("DEVICEW  DEVH", application:getDeviceWidth(), application:getDeviceHeight() )
     
     
    testtab = {
    	--{"SCR TO STG", screen, stage},
    	{"UI  TO STG", startui, stage},
    	{"BTN TO STG", startui.button, stage},
    	{"BTN TO UI", startui.textfield, startui},
    	{"TXT TO UI", startui.textfield, startui},
    	{"TXT TO STG", startui.textfield, stage},
    	}
     
    for i,v in ipairs(testtab) do 
    	local fx, fy, fw, fh =  v[2]:getBounds(v[3])
    	print(v[1], "X", fx, "Y", fy, "W", fw, "H", fh)
    	local area = drawRect( fx, fy, fw, fh, v[1], i)
    	stage:addChild(area)
    end 
     
     
    stage:addEventListener(Event.MOUSE_DOWN, function(event) 
    										local x,y = stage:localToGlobal(event.x, event.y)
    										print("eventX", event.x,"eventY", event.y, "GlobalX", x, "GlobalY", y)
    										end)


    Thank you :smile:
  • hgy29hgy29 Maintainer
    @pie, try to wait a frame so that layout have a chance to be computed before querying ui element positions

    Likes: pie

    +1 -1 (+1 / -0 )Share on Facebook
  • Ok delaying for 3 secs made something change, but I won't say it works as I expected. :smiley:

    The screenshot reflects this change in code


    testtab = {
    	--{"SCR TO STG", screen, stage},
    	{"UI  TO STG", startui, stage},
    	{"BTN TO STG", startui.button, stage},
    	--{"BTN TO UI", startui.textfield, startui},
    	--{"TXT TO UI", startui.textfield, startui},
    	{"TXT TO STG", startui.textfield, stage},
    	}
     
    Timer.delayedCall(3000, function()
    for i,v in ipairs(testtab) do 
    	local fx, fy, fw, fh =  v[2]:getBounds(v[3])
    	print(v[1], "X", fx, "Y", fy, "W", fw, "H", fh)
    	local area = drawRect( fx, fy, fw, fh, v[1], i)
    	stage:addChild(area)
    end 
    end)

  • hgy29hgy29 Maintainer
    Oh, I forgot to say that I had to change your code a bit: your drawRect function takes two coordinates while you call it with origin and width and height

    Likes: MoKaLux, pie

    +1 -1 (+2 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited November 2023
    at pie, I don't know if that would help but commenting out UI.Style will show the shapes beneath each UI.
    --UI.Style:setDefault(UI.Theme.PointCore_Base)
    --UI.Style:setDefault(UI.Theme.PointCore_Red)
    --UI.Style:setDefault(UI.Theme.PointCore_Pink)
     
    application:setBackgroundColor(0x6c6c6c)
    UI.Keyboard.NATIVE=false
    UI.Keyboard.VIRTUAL=false
     
    local test = ([[
    	Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     
    	Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     
    	Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    ]])
     
    startui = UI.Builder({
    	class = "UI.Panel",
    	layoutModel = UI.Layout.Vertical,
    	layout = { anchorx=0.5, anchory=0, fillx=0.8, filly=0.5, weighty=1, insets=0 }, -- UI Panel x, y, width, height
    	children = {
    		{
    			class = "UI.TextField",
    			name = "textfield",
    			Text = test,
    			Flags = { readonly=true, selectable=true },
    			TextLayout = {
    				flags = FontBase.TLF_JUSTIFIED|FontBase.TLF_REF_LINETOP|FontBase.TLF_BREAKWORDS,
    				multiline = true,
    			},
    			Style = { font=TTFont.new("fonts/OpenSans-Regular.ttf", 16, "") },
    			layout = { anchorx=0, anchory=0, fillx=0.7, filly=1, weighty=1, insets=0 },
    		},
    		{
    			class = "UI.Button",
    			name = "buttonh",
    			Text = "Hello",
    			Color = 0xCC00CC,
    			Style = { font=TTFont.new("fonts/OpenSans-Bold.ttf", 13, "") },
    			layout = { anchorx=1, anchory=0, fillx=0, filly=0, weighty=0, insets=0 },
    		},
    	}
    })
     
    -- ui screen
    screen = UI.Screen.new()
    screen:ui(startui)
    stage:addChild(screen)
     
    function startui.buttonh.onWidgetAction()
    	print("hello")
    end
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
Sign In or Register to comment.