excessive / domy Goto Github PK
View Code? Open in Web Editor NEWA DOM-like GUI framework for the *awesome* LÖVE framework
License: Other
A DOM-like GUI framework for the *awesome* LÖVE framework
License: Other
Batching elements is going to be key to efficiently drawing. If we have hundreds or thousands of individual elements, we sure don't want to draw them one at a time.
Since each element may have a relatively unique texture, it is going to be crucial to create texture atlases so we can batch as many elements together as possible.
With a large texture atlas, we can then sort all of the elements based on their Z-index position. All root elements will have a default Z-index based on their sequential order, starting from 1. All child elements will have a Z-index of parent.properties.z-index + 1 unless manually set.
Once every element is sorted by their Z-index, the elements will be buffered into a sprite batch and drawn.
On the next frame, if there are any updates, the batch will be resorted before being drawn again, et infinitum.
Does this sound right? Am I missing anything?
If you wanna show tooltips this is important.
Only using enter and leave does not work in love2d, because they are only called when window is active.
Well text input in love is kinda hard, but I made an almost full text editor so it is not THAT hard haha.
Check it out, it is messy (I wrote it in a day) but it haves the functions you may need.
Missing features are copying, cutting, pasting, undo, redo, and that is it I think.
You may need to refactor everything, but I can always help
The general idea here is to be able to define a sort of GUI "class" that can be used extensively. A great example would be building a generic name plate widget complete with avatar, name, health bar, etc. The widget can be used for the player, party members, targeted enemy, etc.
This feature is an absolute must.
While this may not exactly be important for LOVE proper, I am working on a LOVE3D project and would like for this to support both 2D and 3D GUIs. More thought needs to be put into 3D GUIs, so if you have any ideas, toss them here. :)
I think this line needs to be a bit more explicit what exactly to "require". Many libraries have a single file which needs to required so I think the DOMy documentation should say something like "require the folder in which the init.lua file is located".
EDIT: And maybe a link to the documentation should be added to README.md.
EDIT2: Small typo in this line " The model is used to structure the interface and nothing more." and this one "working horse of ..."
need to figure this one out.
The Script API should vaguely resemble jQuery (but be less convoluted). Each object should have:
And probably other stuff, too.
The lists of siblings and children should be indexed arrays (you can loop through them via ipairs).
The parent, siblings, and children should be pointers to other objects.
There should be helper functions in place despite Lua's ability to access data directly.
local child = object.children[3] -- object
local other_child = object:get_child(3) -- object
Customized properties (properties not set by the object default, id, or class associated to an object) should be held in a custom properties table so when an object needs to be rerendered (say, if it is resized), the programatically defined properties will persist.
If anyone else has ideas, feel free to throw them in here and we can discuss them.
I am currently implementing the base Element object and I need to know what people would expect from a cloned element.
When cloning an Element, do you simply expect a default element of the same type with the same value, an element with the same value and properties (such as visual styles) and scripts, or something else?
My issue with cloning properties verbatim is that some properties such as positioning are going to be relative (unless otherwise specified) so if you clone an element that is 10 dp to the left and it was inside some other element, this new element will be 10 dp left from the screen which is not in the same position at all. Is that expected behaviour?
What does everyone think about the markup syntax? I want the markup to be Lua so I don't need to run a script to convert, say, XML to Lua when it's not necessary. Is the current markup.lua example sensible or are there some serious changes needed?
The basis here is that named named keys within a table are used to define the object and its properties while the sequential keys are used to define child objects (if tables) or direct value (if string/float). Maybe value="some value" would be less ambiguous, if not more wordy?
{ type="block", id="windows",
{ type="text", "Windows XP+" } ,
{ type="list",
{ type="text", class="link", onclick=web_link(strings.some_link), "32-bit installer" },
{ type="text", class="link", onclick=web_link(strings.some_link), "32-bit zipped" },
{ type="text", class="link", onclick=web_link(strings.some_link), "64-bit installer" },
{ type="text", class="link", onclick=web_link(strings.some_link), "64-bit zipped" },
},
}
After discussing the idea of ordering, buffering, and drawing elements, I think the following system may be wise:
Some example uses:
local frame = gui:new_element("frame")
function frame:on_focus()
self:bring_forward() -- no arg defaults to draw on top
-- do frame stuff
end
local frame = gui:new_element("frame")
local button = gui:new_element("button", frame)
function button:on_focus()
self:bring_forward(1) -- never draw over top of the action bar!
-- also pushes the command up to frame
-- do button stuff
end
I think this could work pretty well and give designers enough control without forcing them to manage their own z-index table. Thoughts?
Should there be a value key, or should value (and sometimes children) simply be the sequential second key? Or perhaps both, with value overriding a sequential value?
-- value key
{ "text", value="Some text", id="important_textbox", class={"class1", "class2"},
{ "text", value="Some child" },
}
-- sequential key
{ "text", "Some text", id="important_textbox", class={"class1", "class2"},
{ "text", "Some child" },
}
-- priority key
{ "text", "Some text", value="This takes priority!", id="important_textbox", class={"class1", "class2"},
{ "text", "Some child" },
}
What is the community's opinion of the current styles syntax? The way I have designed it is to organize various scopes since Lua does not have symbols like CSS. The way that this would work would be that for every instance of an object type, the parser will check the styles or see if any styles are defined and apply them. The parser will then check if there is an ID, and if there is a style for that ID. Any ID styles will override Object styles. Finally the parser will check classes (in the order given) and apply them.
Default->Object_Style->ID_Style->Class1_Style->Class2_Style->Class3_Style->...
The properties are mostly stolen from CSS though I plan to review them and make them more game oriented and less document oriented.
I am unsure if I should enforce ID styles tot he first instance of an ID (as an ID should be unique) or just enforce IDs in scripting.
Image replacements for unicode glyphs! My emoji is the emoji that will emote all the ji's.
In a regular grid, you have very obvious up, down, left, and right directions. When taking input from a user, it is very clear which cell within the grid they want to highlight.
In an irregular grid, this is not always obvious. An irregular grid can be defined as a group of sibling objects that are in an unstructured positioning scheme such that the items have no defined path between them. This makes determining if "left" input from object A is expected to go to object B or object C.
What I propose is a sort of constellation system where a set of objects are are handed to the parser and the parser spits out what up, down, left, and right means for each object.
As you can see from the above image, each Star object has a path to nearby objects. In this example, the maximum paths seem to be three, but for a GUI system I believe we can have a maximum of four.
So my question is this: What sort of data should the parser require? I suggest that a table of objects, a maximum radius for paths, and maybe more?
-- in this example, each obj has at minimum an X any Y coordinate
-- units of measurement are listed in dp, not px
local objects = { obj1, obj2, onj3, obj4, obj5 }
local radius = 5
local grid = dom.get_constellation(objects, radius)
How are we going to pull off hypertext? The ability to use multiple colours, fonts, throw in some emoji, etc in a single line or paragraph of text is probably going to be important, especially for online games with chat boxes.
It was suggested in the forum thread that anchor points for elements would be wise. An archor point is defined as the point of an element where positioning takes place. For instance, by default anchor points would be Top-Left, or 0,0. If I want to position an element at 0.5,0.0 on screen, then the top-left corner of the element will be in the middle of the screen on the x axis. If the anchor point is Top-Right or 1,0, then the top-right corner will be at the 50% mark.
The most notable use case for this is allowing elements to resize in any desired direction. If you set the anchor to the centre of the object, then when you resize the object it will stay where it is located but grow or shrink outward. If you set the anchor point of an object to the bottom centre, then you can grow or shrink an object to the edge of the screen.
So I guess the question here is, should there be a set of defined anchor points (TL, TC, TR, L, C, R, BL, BC, BR) or should the anchor be definable based on a % value? vec2(0.25,0.78) would set the anchor point to 25% from the left and 78% from the top.
The GUI instance needs to be aware which element currently has focus.
Each element needs the following functions:
function Element:focus(f)
local focus = self:has_focus()
if focus and not f then
gui:set_focus(false)
elseif not focus and f then
gui:set_focus(self)
end
end
function Element:has_focus()
return gui._focus == self
end
I suppose for this to work, each element is going to need a handle of the GUI instance it belongs to!
Okay so here is the basic idea:
Anything that could affect the visual status of a cell would make it invalid, such as an animation, an element moving, an element scrolling, etc etc etc.
As discussed in Issue #4, should events such as on_click, on_hover, etc be able to be defined within the markup of the file, or should events be strictly defined in scripts?
{ "button" on_click=function() do_a_thing() end, "Button Text" }
or
-- markup.lua
{ "button", id="Button1", "Button Text" }
-- scripts.lua
local button = dom.get_button_by_id("Button1")
button.on_click = do_a_thing
My feeling is that we should toss the idea of pixels right out the window. All objects should have their own local coordinate system, both X and Y valued from 0 to 1. This will allow consistent spacing and positioning across all screens.
This may also bring an issue where persons with box screens (4:3, 5:4) may have skinny GUIs or persons with wide screens (16:9, 16:10) may have fat GUIs depending on how the GUI designer is putting things together. A fix for this may be to use a Point (pt) system where an object can be set to a fixed size based on more relevant metrics than pixels. I believe Android and CSS both allow for various point systems such as pt, em, ex, and px on top of the % system.
EDIT:
We will be going with %, dp, and sp units.
local w, h = love.graphics.getDimensions()
local pc_w = value * w -- value is between 0 and 1
local pc_h = value * h
local dp = px * love.window.getPixelScale()
local sp = dp * font_scale
http://stackoverflow.com/questions/2025282/difference-between-px-dp-dip-and-sp-in-android
http://blog.edwinevans.me/?p=131
http://developer.android.com/guide/practices/screens_support.html
So I have decided to use a SpriteBatch for each individual family tree. A family tree is defined as having a root element with no parent.
I will be using a Canvas as the texture for the batches (maybe a canvas for each batch, but I can probably get away with a single texture).
I will draw each object to the canvas on init, and use scissors to select objects to clear when a style needs to be changed (such as for animations, deletions, interactions, etc).
This method should allow me to render all objects to look exactly as expected while maintaining the efficiency of batching draw calls since every single object will not need to be updated every single frame.
In the markup you declare the type o each segment or child like this:
{type="header",id="myHeader",
{type="image",id="HeaderIcon",src="pathToMyImage"}
...
}
I think that it may be better to have the type mandatory being the first element:
{"header",id="myHeader",
{"image",id="HeaderIcon",src="pathToMyImage"}
...
}
It looks more like HTML, also you avoid writing type at every node hahaha
You could use Image:setWrap() and a Quad bigger than the image to make it repeat.
An Image element should probably be able to use quads so that a user can create their own image atlases for icons and whatever else.
Just wanted to say it... I hate variables that look like this_because_they_are_not_cool
hahaha. My point of view. I just hate writing things that dont add to the content or readability of the code
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 include markup.lua
, styles.lua
, and scripts.lua
.-- main.lua
local dom = require "libs.DOMinatrix"
local gui = dom.new()
gui:add_widget_directory("assets/widgets/")
gui:include_markup("assets/gui/game_screen.lua")
-- game_screen.lua
return {
{ "window_frame", id="character_window" },
}
-- window_frame/markup.lua
return {
{ "inline", class="window_frame",
{ "text", class="window_frame_title" },
{ "button", class="window_frame_collapse" },
{ "button", class="window_frame_close" },
{ "block", class="window_frame_content" },
}
}
Got this mostly working thats to @positive07 but this needs to be scaled down so the outside of the polygon is on the border edge, not the inside!
-- https://gist.github.com/gvx/9072860
local function get_stencil_clip(x, y, w, h, precision, corners)
local polygon = {}
-- true if on x/y, false if on w/h; TL, TR, BR, BL
local xs = { true, false, false, true }
local ys = { true, true, false, false }
for i, radius in ipairs(corners) do
if radius == 0 then
table.insert(polygon, xs[i] and x or x+w)
table.insert(polygon, ys[i] and y or y+h)
else
for j = 0, precision do
local angle = (j / precision + (i - 3)) * math.pi / 2
table.insert(polygon, (xs[i] and x or x+w) + radius * math.cos(angle))
table.insert(polygon, (ys[i] and y or y+h) + radius * math.sin(angle))
end
end
end
return polygon
end
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.