Druid - Component GUI Framework

I’m experimenting with Druid :wink: I was thinking about very generic use case, but for example, if I want to have a list that would contain e.g. “lines of codes” in render script (I’m thinking about making a tool to simplify making render scripts) I would like to have a drag-and-drop functionality to reorder them, like I would reorder lines of code in Lua:

image

So idea with handling it in long_press callback is a great place to start - then I would attach Drag component, but what about the list below then?

For example, I want to drag Viewport before/above Clear. I drag Viewport - I create a temporary, draggable node, cloned from original Viewport, so the list stays the same, but I would like to add to the list some kind of “placeholder” - indicating, where the dragged element would be dropped, when I release mouse click - How to take on making such “placeholder”? It should follow the dragged element and somehow “fit” into the list below

2 Likes

I think about empty node, inserted into the grid and adjusting grid nodes indexes next.

For example, static grid had the element size, it’s ok to pass into it any sized node but it will posing depends of default element size

It can be catchy to get drag node index, but probably we can check it with grid:get_index(pos)

It can be next flow:

  • Long press to pickup the element
  • Remove picked element from the Grid, set drag it to cursor in some way
  • Remember pickup grid index
  • On element drag - check grid node index and insert into this index empty node (and remove previous before)
  • On drop item - place it on current grid index or to picked place if we drop item out of grid box
  • To make grid element move animations we can set grid: set_position_function

I would like to have a drag-and-drop functionality to reorder them, like I would reorder lines of code in Lua

The drag node seems pretty complex way. It’s a reason why I use button “Set Parent” and “Move Up/Down” in Panthera instead of drag-n-drop :smiley:
It’s also probably can be much better way for you in practical way (but it’s interesting task anyway!)

2 Likes

Where does Panthera utilise such functionality (Move Up/Down)? I only saw “Set Parent” :smiley:

In node settings:

1 Like

The post on HTML5 input on mobile also remind me about other issue with Druid - it looks like text Inputs are not working on mobile Web browser (keyboard is not showing up) - is it only me?

Right, currently Druid is not support html5 mobile keyboard. But it will be in the next release I think (even I have the issue!)

2 Likes

How to add on_element_add callback?

https://insality.github.io/druid/modules/DataList.html#on_element_add

This is simply wrong understanding of the field and documentation:

self.dynamic_list.on_element_add = function(self, index, node, instance)
	print("Element added to dynamic list")
end

Because on_element_add is a very complex table and not a function called then (I guess such function would be somewhere inside this table though, but it’s huge and not clear to me which one could I overwrite like this :confused: )

There is no parameter in new_list_data() to pass such on_element_add callback nor there is any function like set_on_element_add_callback()

Or other thing I want to achieve is to refresh some other list to which I added element, but addition of element happened in a callback of another component.

Use case: I click on element on left list and want it to be added to dynamic list on right:
I add it to the data_list table used for dynamic list, but only when I start interacting with dynamic list it is updated and new element in table is taken into account and created in list:

Can’t answer detailed now, but here are notes about your question:

  • The on_element_add is Druid event: Defold Druid UI Library. You can use method subscribe to add handler to this event (on_element_add:subscribe(callback, first_argument))

  • To add element to data list probably better way will be to use ‘set_data’. It should work. What is your way to add elements? If you push element to list you should to update the list somehow.

  • Also probably there is better to use just scroll + static grid instead of data list. Seems you have no any possible troubles with amount of elements :wink:

2 Likes

This is what I missed, it fixed the behavior!

Thank you! Now I know how to subscribe to any events :blush:

1 Like

Hello
Thank you for the Druid! :slight_smile:

I have a question about the EmmyLua annotations. I don’t understand how the annotations.lua are supposed to be used. I’m using sumneko.lua plugin.

I copied the druid folder into my project, out of the box the annotations do not apply:

Only when I add ---@type druid into druid.lua, but then there are a lot of other classes so I feel that I’m doing something wrong… Am I missing an easy solution?

Hello

Basically, you can just copy the annotation file to your project and annotate the require field:

---@type druid
local druid = require("druid.druid")

Source

All other annotations should work well

1 Like

Oh, of course))) Thank you!

Indeed :grin:

But still, thanks @Insality and @Pawel for your answers.

For some reason, I couldn’t work on my project for 1 month, but when I came back, everything was clearer and I used the" blacklist" method (using a table of buttons that is updated when necessary). Seems to work as intended now.

Not sure I would know how to implement the other approaches, but… one problem at a time :slight_smile:

1 Like

Hey @Insality! (edit : just tagged the wrong insality :see_no_evil: fixed)

I was about to post a wall of text (with lots of screenshots and videos :monkey:), but then I realized that my problem could maybe be summarized as:

How to add/remove elements from a data list? (without deleting/recreating the list)

In the example list, this use case is not available:

However, I did some digging, and there is an example regarding this (even though it’s not enabled by default).

I tried running it, but it doesn’t seem to work correctly.

  • The list positions itself incorrectly when removing an element at the end.
  • The scrolling doesn’t adjust (basically, a “small content” list keeps scrolling as if it had its original size).
  • Some other minor issues here and there.

I suppose that, for now, the example in question is not 100% functional (which is probably why you didn’t enable it).

Just in case: do you have a functional example lying around? :nerd_face:

Not sure about the others, but adding/removing elements to/from a list seems to be an important feature (to me at least). Perhaps someone here has already implemented it?

1 Like

Yea, right now the add/remove the single entry in DataList is not implemented and tested, so it’s disabled.
There are several issues, so currently you have only one option with data_list:set_data until me or someone will implement this.

2 Likes

When the window is resized, dragging becomes offset. I can’t remember if there is a way to address this in Druid?

Minimal project:
Archive.zip (2.6 KB)

Again, thanks for a great extension. :star_struck:

1 Like

Thanks for the report!
I’m already fix this in upcoming release

Should publish soon :upside_down_face:

5 Likes

Druid 0.11.0 : Release Defold Druid v0.11.0 · Insality/druid · GitHub

Hello! What a wonderful day for the new Druid update!

Alright, let’s get straight to the point. Look at what I have for you!

Druid Rich Text has finally been released. The main difference from the existing Bjorn’s Rich Text is that all visual parameters are customizable directly in the GUI. This allows you to integrate Rich Text more accurately and quickly. Additionally, this Rich Text aligns pixel perfect (well, almost) with regular GUI text node.

This version is the most basic one. Honestly, just wanna to publish current version for your and polish it later. Read RichText API here

Another addition is the ability to enable the “HTML mode” for the Button component. In this mode, the button’s action occurs in the context of user action, allowing operations like “copy and paste text” “show the keyboard” and more. However, in this mode, the button only responds to regular clicks due to the technical implementation of it (so no double clicks or long taps for this button).

The huge work was done on documentation. Now it’s more clear and have more examples. All documentation now moved to the API section. The separate componentd.md manual will be deleted soon as all documentation will be moved to the API section.

The API section now filled with overview and usage examples. I’ve started with the basic modules, in future I will add more examples for all modules.

Also, I’ve added the Unit Tests. It’s not cover all Druid code, but it’s a good start! :tada:

Have a good day!

Changelog 0.11.0


  • #126 [Breaking] [Input] Change input bindings to Defold’s defaults
    • This changes was done in prev. tagged release, please sure your input bindings for Druid now are like in the Defold default input bindings. Refer to README for more instructions.
  • #191: [RichText] Finally add Druid Rich Text custom component (live example here). Component is used to make formatted text in your’s GUI. This Rich Text mostly adjusted visually in GUI and have almost pixel-perfect match with similar GUI text node
  • #39: [System] Finally add Unit Tests. Yeah, it cover not all Druid code, but it’s a good start! :tada:
  • #219: [System] UTF-8 performance optimization. Now Druid will try to use utf8 native extension over lua utf8 library if exists. If you wanna use native utf8, just add the extension in your game.project dependency.
  • #156: [Button] Now button can work in HTML5 with html5.set_interaction_listener.
    • The API is button:set_web_user_interaction(true). In HTML5 mode button have several restrictions. Basically, only the single tap event will work.
  • #227: [System] Update current URL in HTML5 example
    • Now if you will open the example from direct URL, it will be updated to the current URL in your browser. So now it’s much easier to share the example link with each other.
  • #183: [Docs] Documentation about GUI in World Space
    • Also not only the GUI in World Space, but overall How to GUI in Defold article.
  • #234: [BREAKING] [Blocker] Now blocker:set_enabled and blocker:is_enabled affects only inner state of component. To consume input, the blocker component should be enabled and the node itself should be enabled.
    • Breaking due the changes can affect your current logic. Please if use this re-check Blocker component usage.
  • #235: [Drag] Fix Drag coordinates on streched screen.
  • #236: [Hover] Fix nil return in hover:on_input.
  • #237: [Layout] Add layout:set_max_gui_upscale function.
    • This functions will scale down element, if current GUI scale is bigger than max_gui_upscale value. It can be useful for adapt mobile device to desktop screen.
  • #238: [System] Add Helper documentation.
  • [System] Now the documentation contains the Druid size. The current size as dependency is around 67KB. It counted without extended components, which is not included by default in the build.

Thanks to the my supporters:

:heart: Support :heart:

Please support me if you like this project! It will help me keep engaged to update Druid and make it even better!

Github-sponsors Ko-Fi BuyMeACoffee

18 Likes

I’m still seeing the same stretched window behaviour in the new build for some reason. Are any changes needed to make it work?

Minimal project:
Archive.zip (2.6 KB)

1 Like

Thanks for the repro!

The issue is the absent druid.on_window_callback function, which catch the window resize to update inner scale koefs.

So if you add the next code, all should be correct

window.set_listener(function(_, event)
	druid.on_window_callback(event)
end)
4 Likes