Page 2 of 2

Re: yui - declarative GUI library for LÖVE

Posted: Mon Nov 13, 2023 6:12 pm
by 1414codeforge
Hi, glad to see Yui is being used :ultraglee:
What is the best way to build a custom widget? Just copy paste code out of an existing one, and change it?
Yes, I'd say that's the most straightforward way.

Pick a relatively simple one (like Button, Label or Checkbox) and tweak from there.
It'll help you to understand how it works, then you'll be able to gradually create more complex ones like Input and Slider.
Is there a way to get a label to change it's text field dynamically? Because this doesn't work, as far as I can tell: [...]
I've replied to this on codeberg, thanks for submitting the issue!

Re: yui - declarative GUI library for LÖVE

Posted: Tue Nov 14, 2023 1:50 am
by lakotajames
Thanks! Is it better to contact you in this thread, or on codeburg?

Re: yui - declarative GUI library for LÖVE

Posted: Tue Nov 14, 2023 11:35 am
by 1414codeforge
Depends on the subject, for general discussion and questions, the forum is the better, so more people can join the discussion and give their ideas.
For bugs and feature requests, codeberg is better, so development can be tracked more efficiently.

Re: yui - declarative GUI library for LÖVE

Posted: Fri Nov 17, 2023 4:14 am
by lakotajames
So, I was able to make a custom "choiceButton" widget by copying choice widget and adding the toHit stuff from button, then changing every occurrence of "Choice" to ChoiceButton". I added it to the lib folder and added the require to the init.lua. Everything works!

However, if there's a way to keep my custom stuff out of the library itself so that I can just download and replace the library to update it, that'd be ideal.

I presume I'd need to change something about the BASE line to move the file, then just require it manually where I'm requiring yui. Can you point me in the right direction?

Re: yui - declarative GUI library for LÖVE

Posted: Tue Nov 21, 2023 2:49 pm
by 1414codeforge
lakotajames wrote: Fri Nov 17, 2023 4:14 am So, I was able to make a custom "choiceButton" widget by copying choice widget and adding the toHit stuff from button, then changing every occurrence of "Choice" to ChoiceButton". I added it to the lib folder and added the require to the init.lua. Everything works!
Nice :ultraglee:
However, if there's a way to keep my custom stuff out of the library itself so that I can just download and replace the library to update it, that'd be ideal.

I presume I'd need to change something about the BASE line to move the file, then just require it manually where I'm requiring yui. Can you point me in the right direction?
In my projects, I usually keep all third-party libs under a lib subdirectory.
So, for example, if I had to use yui I'd keep it under lib/yui.
Assuming you want to store all your custom widgets under a widgets folder, you'd end up with the following layout:
  • lib/yui, the yui module.
  • widgets, your custom widgets folder.
So, you could create a widgets/mybutton.lua widget, and you'd require the necessary modules like this.

Code: Select all

local Widget = require 'lib.yui.widget'
local core = require 'lib.yui.core'

local MyButton = setmetatable({
    __call = function(cls, args) return cls:new(args) end
}, Widget)

-- ...

return MyButton
You could then import your widgets anywhere in your project, like this:

Code: Select all

local MyButton = require 'widgets.mybutton'

-- ...
And use it like any other yui "standard" widget to create your ui.

This is just my way to organize projects, not necessarily the best.

Re: yui - declarative GUI library for LÖVE

Posted: Thu Dec 14, 2023 8:36 pm
by Azzla
Is it possible to programmatically determine widgets for the template? I don't mean dynamic widget state during runtime, but rather template generation at runtime. Something like:

Code: Select all

return Yui.Ui:new{
	x = x, y = y,
	Yui.Rows{
		--widgets by iteration
		for i,v in ipairs(extern_values) do Yui.Button{ ... } end

		--conditional widgets
		if extern_flag then
			Yui.Slider{ ... }
		else
			Yui.Checkbox{ ... }
		end

		--widgets as return values
		generateButton(extern_options) --inlines 'Yui.Button{ ... }'
	}
}
These obviously throw syntax errors but it shows the idea. I really like Yui's declarative approach to UI but I feel I'm missing some critical flexibility with the templating. Is there a way to accomplish something like the above?

EDIT: I thought of another question here, sorry! Is it possible to query properties of the template at runtime? Say for example, I want to make my own draw calls on top of Yui's, while still utilizing its layout:

Code: Select all

local ui = Yui.Ui:new{ ... }
local img = love.graphics.newImage(some_path)

function love.draw()
	ui:draw()
	love.graphics.draw(img, ui.rows[1].x, ui.rows[1].y)
end
Thanks.

Re: yui - declarative GUI library for LÖVE

Posted: Sun Jan 14, 2024 5:37 pm
by 1414codeforge
Hello, about question 1, widget by iteration, in theory you could create a function returning the appropriate widget array, and then unpack it:

Code: Select all

function generateLayout()
	local widgets = {}
	for i,v in ipairs(...) do
	    widgets[i] = ...
	end
	return widgets
end

return yui.Ui:new {
    ...
    unpack(generateLayout()),
    ...
}
Conditional widgets can be achieved in much of the same way:

Code: Select all

function conditional(clause)
    return clause and widget1 or widget2
end

return yui.Ui:new {
    ...
    conditional(extern_flag),
    ...
}
About your second question, it is not very clean, but, in principle, you can do it. You'll notice that pretty much every widget uses a common set of properties storing their position, width, etc...
So you could query them and use them, Lua doesn't provide much encapsulation anyway.

Moreover, you can iterate widgets in a Ui pretty easily, in fact, widgets are stored in the table array portion, so you can use ipairs() with a regular for. You can have either a Container widget (a widget containing another widget), or any other "leaf" widget, such as buttons, sliders, ...