Druid - Component GUI Framework

druid_logo

Druid - powerful Defold component UI library. Use Druid components or make your own game-specific components to make amazing GUI in your games.

Overview

Druid is a UI component library, started by AGulev around ~2 years ago. I’ve use it and develop sometimes. For all this years it’s slowly improving and now I want to share it with community.

Druid GitHub: https://github.com/Insality/druid
Druid API: https://insality.github.io/druid/
Live example (HTML5): druid 0.11.694
25

Basic components

Components description

Druid provides next basic components: Button, Text, Lang text, Scroll, Input, Progress, Slider, Checkbox, Checkbox group, Radio group, Blocker, Back Handler, Timer, StaticGrid, DynamicGrid, Hover and Swipe

All of this components - simple GUI nodes or text nodes. Druid just add logic on your nodes.

Basic usage

local druid = require("druid.druid")

local function button_callback(self)
	print("Button was clicked!")
end

function init(self)
	self.druid = druid.new(self)
	self.druid:new_button("button_node_name", button_callback)
end

function final(self)
 	self.druid:final()
end

function on_input(self, action_id, action)
	return self.druid:on_input(action_id, action)
end

Custom components

Druid allows you to create custom components.

Custom components usually - the GUI template and component logics, what applies upon this GUI template.

Styles

Druid have styles - set of functions and parameters for components to customize their behaviour. Styles used to custom visuals of basic Druid components.

Styles documentation

Notes

Druid is still developing and now version is 0.6.0. It is possible, what will be breaking changes until 1.0.0. I need your feedback to improve Druid.
All documentation is placed on github. Learn it!

Also there is Druid API, generated by LDoc.

You can help with:

  • Share your experience with Druid - it’s important!
  • Add your suggestions, improvements and pull requests in github
  • Create your own custom components and share it with community!
  • Help with documentation, it in progress now. It is pretty hard :slight_smile:
47 Likes

Very nice! Thank you for sharing!

3 Likes

This is a very nice and well considered idea! I will try to add my own bars, indicators, texts etc, it should be easy :smiley:

3 Likes

This is great!

Thanks for sharing these

4 Likes

This is awesome!

Really like the inertia scrolling.

Thank you!

4 Likes

input_component
input_rich_example pin_example
Druid 0.3.0:

  • Druid:final() now is important function for correct working

  • Add swipe basic component

    • Swipe component handle simple swipe gestures on node. It has single callback with direction on swipe. You can adjust a several parameters of swipe in druid style.
    • Swipe can be triggered on action.released or while user is make swiping (in process)
    • Add swipe example at main Druid example. Try swipe left/right to switch example pages.
  • Add input basic component

    • Input component handle user text input. Input contains from button and text components. Button needed for selecting/unselecting input field
    • Long click on input field for clear and select input field (clearing can be disable via styles)
    • Click outside of button to unselect input field
    • On focus lost (game minimized) input field will be unselected
    • You can setup max length of the text
    • You can setup allowed characters. On add not allowed characters on_input_wrong will be called. By default it cause simple shake animation
    • The keyboard for input will not show on mobile HTML5. So input field in mobile HTML5 is not working now
    • To make work different keyboard type, make sure value in game.project Android:InputMethod set to HiddenInputField (https://defold.com/manuals/project-settings/#input-method)
  • Add two functions to basic component: increase_input_priority and reset_input_priority. It used to process component input first in current input stack (there is two input stacks now: INPUT and INPUT_HIGH). Example: on selecting input field, it increase input self priority until it be unselected

  • Add two new component interests: on_focus_gain and on_focus_lost

  • Add global Druid events:

    • on_window_callback: call druid.on_window_callback(event) for on_focus_gain/lost correct work
    • on_language_change: call druid.on_language_change() (#38) for update all druid instances lang components
    • on_layout_change: call druid.on_layout_change() (#37) for update all gui layouts (unimplemented now)
  • Add button on_click_outside event. You can subscribe on this event in button. Was needed for Input component (click outside to deselect input field)

  • Changed input binding settings. Add esc, enter, text and marked_text. Backspace now is different from android back button event. Check the README setup section

  • Add several examples to druid-assets respository (see live example): https://insality.github.io/druid-assets/)

  • Known issues:

    • Adjusting text size by height works wrong. Adjusting single line texting works fine
    • Space is not working in HTML5

Note: code for input field was inspired and partly copied from britzl gooey GUI system. Thanks :slight_smile:

17 Likes

Hi! I’ve been using Godot for half a decade, just want to pass by and say this is looking incredible.
I’m currently in Limbo with my project (been in development for quite some time) and looking to find it a new home. However, I can’t let go of Godot’s RichTextLabel, it’s essential for my Lobby system and in-game chat. I’ll definitely be following this thread!

3 Likes

need help with set_enabled() on a button.
why does a node turn black when i disable it?
how to disable a node with all it’s childrens?

2 Likes

Hi John! What kind of games are you doing with Godot?

There’s a RichText system for Defold as well:

Repo: https://github.com/britzl/defold-richtext
Demo: https://britzl.github.io/RichText

3 Likes

Yea, there is confusing name. Function set_enabled in button is inner logic to disable it’s logic part. And it have default style to turn it black on disabled. I will rework this stuff later (https://github.com/Insality/druid/issues/47).
Default style logic here: https://github.com/Insality/druid/blob/develop/druid/styles/default/style.lua#L36

Styles will be polished closed to Druid 1.0.0

Enable and disable gui elements you should do in Defold way, via gui.set_enabled(node, state). Button have field to node access: button.node

Thanks for feedback!

3 Likes

ok gotcha

but why not add something like :hide :unhide so i don’t need to use gui.set_enabled. It would be more clean and convenient to let druid handle all these things.

1 Like

Probably it will be, but sometimes it looks like over-API (just coping of existence Defold GUI API).

If I will add stuff like this, it will be named exactly, as gui API function to make less confusing names.

I did it with Gooey and Richtext . Therefore, I am sure that you can implement in your game. I am ready to send a code and an example if you need

Gif


https://s4.gifyu.com/images/chat2.gif

@Insality this library is really impressive. Thanks for sharing

4 Likes

whats more confusing then :set_to() in text module for set_text()? :slight_smile:
will this also be renamed?

1 Like

another question, how to get action info on button click? i already searched for it in button parameter from callback method. I need action.x & action.y.

edit: nvm, i think i will try making a custom component for my needs.

With set_text a little different situation in comparing with set_enabled. Component set_text should do more logic, not only text node changing (it’s trigger events, recalc sizes and other stuff).

Yea, API can be reworked. If it will happen, I’ll post about it, and old API will be deprecated for some time.

For action table in button is good point, but for now there is no way to get it. For which stuff you need action table?

Yea, for complex GUI stuff in your game the most reasonable to make your own custom components, which contains already basic one and your modifications. Druid is more about how to create and handle your own GUI components

2 Likes

I have a kind of panel in my game where i can touch different spots in it and the action happens based on the touched position, so in fact i don’t need a button at all for this but it was the closest component to a panel in druid.
But then i thought why not make a simple panel component.

Or i will keep my defold code

Druid 0.4.0: https://github.com/Insality/druid/releases/tag/0.4.0

  • Add Drag basic component

    • Drag component allow you detect dragging on GUI node
    • Drag will be processed even the cursor is outside of node, if drag is already started
    • Drag provides correct handle of several touches. Drag can switch between them (no more scroll gliches with position)
    • Drag have next events:
      • on_touch_start (self)
      • on_touch_end (self)
      • on_drag_start (self)
      • on_drag (self, dx, dy)
      • on_drag_end (self)
    • You can restriction side of dragging by changing drag.can_x and drag.can_y fields
    • You can setup drag deadzone to detect, when dragging is started (by default 10 pixels)
  • Druid Scroll component fully reworked. Input logic moved to Drag component

    • Update scroll documentation
    • [Breaking changes] Change constructor order params
    • [Breaking changes] Change scroll:set_border to scroll:set_size
    • Scroll now contains from view and content node
      • View node - static node, which size determine the “camera” zone
      • Content node - dynamic node, moving by Scroll component
    • Scroll will be disabled only if content size equals to view size (by width or height separatly)
    • You can adjust start scroll size via .gui scene. Just setup correct node size
    • Different anchoring is supported (for easier layouting)
    • Function scroll_to now accept position relative to content node. It’s more easier for handling. Example: if you have children node of content_node, you can pass this node position to scroll to this.
    • Resolve #52: Content node size now can be less than view node size. In this case, content will be scrolled only inside view size (can be disabled via style field: SMALL_CONTENT_SCROLL)
    • Fix #50: If style.SOFT_ZONE_SIZE equals to [0…1], scroll had glitches
  • Druid Grid Update

    • Anchor by default equals to node pivot (so, more component settings in .gui settings) (#51)
    • Function grid:clear now don’t delete any GUI nodes. Druid will not care about gui.delete_node logic anymore (#56)
  • Druid Hover component now have two hover events (#49):

    • on_hover is usual hover event. Trigger only if touch or mouse action_id pressed on node
    • on_mouse_hover action on node without action_id (desktop mouse over). Works only on desktop platform
  • Styles update:

    • Styles table now can be empty, every component have their default style values
    • Remove component:get_style function. Now you can only set styles
    • To get style values in component, add component:on_style_change function. It’s invoked on component:set_style function
    • You can look up default values inside component:on_style_change function or style component API on Druid API
  • Druid update:

    • Now function druid:remove remove instance and all instance children components. No more manual deleting child components (#41)
  • Fix: Blocker component bug (blocker had very high priority, so it’s block even button components, created after blocker)

  • Fix #58: Bug, when druid instance should be always named druid (ex: self.druid = druid.new(self))

  • Fix #53: Bug with final Druid instance without any components

P.S.: Thanks for any feedback you give to me. It’s very helpful :slight_smile:

20 Likes

This is great API, for quick and easy GUI functionality.

Thanks,
I have query and not sure if this right platform to ask.
I am trying to implement scroller with dynamic content, but facing issue with Not enough resources, as we have resource limit,
for example message app having scroller for message, as each message is resource, and have no limit for message.

where as I tried to release resources and re-adding resources. for example while scroll up, release bottom out of grid resources and add then again on top of grid and vise versa.
but not working exactly as expected, is there any provision for this type of requirement ? or what else I can try ?
Thank you in advance,

1 Like

Thanks for the feedback! Glad to hear you like Druid

The way you described to create infinity scroll is correct. I’ll add infinity scroll soon (week or two I guess), it will be available as additional GUI component.

But for now my advice is implement it by you own, as you can.

1 Like