Closed karai17 closed 9 years ago
I think it would be nice to have the ability to override a widget's individual pieces. This would allow the user to define the contents of a widget within markup instead of needing to do so programmatically after the fact. I am not quite sure how I would go about this, though.
Something like jekyll does with Liquid? Templating?
I don't understand what you mean.
Jekyll the static page generator used by Github pages uses Liquid, a templating language, in order to generate the pages.
Basically you write layouts, which are .html
files (but could be anything else) saved in the _layouts
folder, for example lets call this layout mylayout.html
:
<div style="width:50px; margin:auto; color:#F00">
{{ content }}
</div>
Here {{ content }}
is a Liquid variable that will be replaced by the actual content (There are plenty of variables but {{ content }}
is the most important)
Then you define your pages, and at the top you specify the layout to use, for example this file, called mypage.html
:
---
layout:mylayout
---
This will be my content and will be red and centered (possibly), and have a width of 50px because why not?
This will be turned into a final file called mypage.html
with the following content
<div style="width:50px; margin:auto; color:#F00">
This will be my content and will be red and centered (possibly), and have a width of 50px because why not?
</div>
Layouts can also use other layouts.
Multiple pages can use the same layout.
They can be any type of file (another common example is generating RSS feeds file which are .xml
)
Also it is common to use a _config.yml
file which holds data you can then use as variables, so it is pretty extensive.
Liquid also provides syntax for conditionals and loops, for example you can write an if statement like this: {% if something %}Write this{% endif %}
If you are interested in templating markup language check Liquid and Soquid (@LPGHatguy attempt at templating language in Lua)
I have implemented it a little differently. What I do (I just finished implementing this about 3 minutes ago) is allow you to override default settings of the widget by specifying an attribute in the widget declaration. This attribute checks against the widget's elements to see if they have an appropriate class value. If so, it will insert the attribute's data into that element. This also allows you to insert a group of elements into an element by breaking apart the root table of the group. Finally, if you assign an id to the widget, it will assign that id to the container of the widget.
-- group of elements
local content = {
{ "image" },
{ "image" },
{ "image" },
{ "image" },
}
--widget
{ "window_frame", title="Some Window", content=content, id="some_window" }
-- widget markup
{ "inline", class="window_frame",
{ "text", class="window_frame_title" },
{ "block", class="window_frame_content" },
}
-- processed widget markup
{ "inline", class="window_frame", id="some_window",
{ "text", "Some Window", class="window_frame_title" },
{ "block", class="window_frame_content",
{ "image" },
{ "image" },
{ "image" },
{ "image" },
},
}
I see, it looks fine for me! How would this look in different file though? What will be in each one? How should I call this?
Each widget is in a self-contained folder within a group directory. The default is %DOMY%/widgets
, so in the above example's case you would have %DOMY%/widgets/window_frame
. Inside that folder is a markup.lua
file (and styles.lua
and scripts.lua
files). that markup file contains the aforementioned widget markup. The single tag listed widget
is the markup you would write in your normal markup file to define your UI. DOMy knows if it is an element or a widget so it will process it automatically and replace the widget tag with the processed elements.
Widget styles now work. I will see if I can get scripts working today.
What will scripts do?
Scripting the ui is always useful, but I need to figure out how to apply scripts to widgets consistantly. On Apr 2, 2015 8:11 PM, "Bobbyjoness" notifications@github.com wrote:
What will scripts do?
— Reply to this email directly or view it on GitHub https://github.com/excessive/DOMinatrix/issues/23#issuecomment-89073647.
I've added a function to the GUI instance that allows you to register functions. This allows you to define functions in a scripts file and save anything that may need to be run more than once (such as creating a new element and applying all the callbacks it needs).
This finalizes the widget system and API!
local function create_button()
local button = gui:new_element("button")
button.on_clicked = function()
print("Clicked!")
end
end
gui:register_function("create_button", create_button)
gui:create_button()
I think the registration should be under the widget name or something, otherwise if I have two widgets that define a function called create_button
the later one would override the first one.
So if for example my widget mywidg
registers create_button
I can find the function under gui.mywidg:create_button
If you do this you would need something like gui:this_widget
to get the current widget registered functions (since the widget name may be changed by the user) and something like gui:widgets
would be nice to have too, so you can find other widgets.
The registration isn't specifically for widgets, it is a general purpose functionality that widgets can take advantage of. The idea here is that creating a new widget (or any new element, really) programmatically might require you to assign data such as callbacks or classes or other such things that you have pre-written in your scripts file that worked for the initial loading of elements.
Creating a new element won't run your scripts file again, and running the whole thing again might cause unwanted occurrences anyway, so this is a bridge where you can write your UI-specific scripts in a separate file and then register reusable code to invoke in your game code as needed.
I would vouch against storing widgets in a folder, and rather expose an API that creates a widget from a markup/style/script triple. You can then still have widgets in the same structure you have outlined above, just add an init.lua
and let the Lua require work it's magic:
init.lua:
local modname = (...):gsub('%.init$', '')
local markdown = require(modname .. '.markdown')
local styles = require(modname .. '.styles')
local scripts = require(modname .. '.scripts')
-- optionally process or modify the widget here
-- for example generate two different versions, process localization etc.
return gui:registerWidget('this_widget_name', markdown, styles, scripts)
That way you could also dynamically generate widgets.
While I'm not completely against your idea, I don't really see much benefit from it, either.
It would for example allow widget-editors, loading widgets from other sources (internet) and I am sure there are other cases I can't think of at the top of my head.
I just generally find it weird that FS is mixed in with GUI, especially when in lua there is no general way of handling FS.
But you can already do that! You can download widgets and place the folder into some directory and register that directory to DOMy. On Apr 4, 2015 5:53 PM, "Sol Bekic" notifications@github.com wrote:
It would for example allow widget-editors, loading widgets from other sources (internet) and I am sure there are other cases I can't think of at the top of my head.
— Reply to this email directly or view it on GitHub https://github.com/excessive/DOMy/issues/23#issuecomment-89663902.
A Widget is a predefined GUI object that can be loaded into any GUI instance. A simple example would be a Window Frame that includes a close button, a collapse button, a title area, and a content area. The Window Frame would have predefined styles and scripts. Once a widget is loaded, you can load it like any other element.
My basic idea for the Widget API is as follows:
%DOMINATRIX%/widgets
)widgets/window_frame
,widgets/minimap
)markup.lua
file. Loadable files includemarkup.lua
,styles.lua
, andscripts.lua
.