From db2ae32a1974019fd839eecf8c45f158595031c3 Mon Sep 17 00:00:00 2001 From: Insality Date: Sat, 9 May 2020 16:07:38 +0300 Subject: [PATCH] Updated documentation to 0.4.0 --- README.md | 23 ++--- docs/index.html | 2 +- docs/modules/component.html | 93 ++++++++++++------ docs/modules/druid.back_handler.html | 2 +- docs/modules/druid.blocker.html | 2 +- docs/modules/druid.button.html | 27 ++++- docs/modules/druid.checkbox.html | 8 +- docs/modules/druid.checkbox_group.html | 2 +- docs/modules/druid.drag.html | 9 +- docs/modules/druid.grid.html | 7 +- docs/modules/druid.helper.html | 2 +- docs/modules/druid.hover.html | 33 ++++++- docs/modules/druid.html | 2 +- docs/modules/druid.input.html | 16 +-- docs/modules/druid.lang_text.html | 2 +- docs/modules/druid.progress.html | 10 +- docs/modules/druid.radio_group.html | 2 +- docs/modules/druid.scroll.html | 30 ++++-- docs/modules/druid.slider.html | 2 +- docs/modules/druid.swipe.html | 11 ++- docs/modules/druid.text.html | 2 +- docs/modules/druid.timer.html | 2 +- docs/modules/druid_event.html | 2 +- docs/modules/druid_instance.html | 33 ++++++- docs/topics/01-components.md.html | 84 ++++++++++++---- .../02-creating_custom_components.md.html | 10 +- docs/topics/03-styles.md.html | 24 ++++- docs/topics/04-druid_assets.md.html | 2 +- docs/topics/05-examples.md.html | 2 +- docs/topics/README.md.html | 20 ++-- docs/topics/changelog.md.html | 45 +++++++-- docs_md/01-components.md | 68 ++++++++++--- docs_md/02-creating_custom_components.md | 8 +- docs_md/03-styles.md | 16 +++ docs_md/changelog.md | 15 +-- game.project | 2 +- media/input_binding_1.png | Bin 16657 -> 24916 bytes 37 files changed, 458 insertions(+), 162 deletions(-) diff --git a/README.md b/README.md index d3ba89c..cc2f071 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,12 @@ Or point to the ZIP file of a [specific release](https://github.com/Insality/dr For **Druid** to work requires next input bindings: -- Mouse trigger - `Button 1` -> `touch` _For basic input components_ -- Key trigger - `Backspace` -> `key_backspace` _For back_handler component, input component_ -- Key trigger - `Back` -> `key_back` _For back_handler component, Android back button, input component_ +- Mouse trigger - `Button 1` -> `touch` _For basic input components_ +- Key trigger - `Backspace` -> `key_backspace` _For back_handler component, input component_ +- Key trigger - `Back` -> `key_back` _For back_handler component, Android back button, input component_ - Key trigger - `Enter` -> `key_enter` _For input component, optional_ - Key trigger - `Esc` -> `key_esc` _For input component, optional_ +- Touch triggers - `Touch multi` -> `multitouch` _For scroll component_ ![](media/input_binding_2.png) ![](media/input_binding_1.png) @@ -61,7 +62,7 @@ druid.set_default_style(your_style) -- Call this function on language changing in the game, -- to retranslate all lang_text components: -druid.on_languge_change() +druid.on_language_change() -- Call this function on layout changing in the game, -- to reapply layouts @@ -109,6 +110,8 @@ druid.on_window_callback(event) - **[Swipe](https://github.com/Insality/druid/blob/master/docs_md/01-components.md#swipe)** - System Druid component, handle swipe gestures on node +- **[Drag](https://github.com/Insality/druid/blob/master/docs_md/01-components.md#drag)** - System Druid component, handle drag input on node + Full info see on _[components.md](https://github.com/Insality/druid/blob/master/docs_md/01-components.md)_ @@ -183,7 +186,7 @@ end - *on_input* used for almost all basic druid components - *update* used for progress bar, scroll and timer base components -- *on_message* used for specific druid events, like language change or layout change (TODO: in future) +- *on_message* used for specific druid events, like language change or layout change - *final* used for custom components, what have to do several action before destroy Recommended is fully integrate al druid lifecycles functions @@ -223,13 +226,11 @@ _Will fill later_ ## License -Original created by [AGulev](https://github.com/AGulev) +- Original created by [AGulev](https://github.com/AGulev) +- Developed and supporting by [Insality](https://github.com/Insality) +- Assets from [Kenney](http://www.kenney.nl/) -Developed and supporting by [Insality](https://github.com/Insality) - -Assets from [Kenney](http://www.kenney.nl/) - -MIT License +**MIT** License ## Issues and suggestions diff --git a/docs/index.html b/docs/index.html index c7116f4..e4788f4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -200,7 +200,7 @@
generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
diff --git a/docs/modules/component.html b/docs/modules/component.html index aae8da2..99b8ff4 100644 --- a/docs/modules/component.html +++ b/docs/modules/component.html @@ -83,13 +83,9 @@

Functions

- - - - - + @@ -136,11 +132,19 @@ - + + + + + + + + + - +
get_style()Get current component style table
set_style(style)Set current component style tableSet current component style table.
get_template()Return druid with context of calling component.
setup_component(table, table)is_child_of()Return true, if current component is child of another component
get_name()Return component name
setup_component(table, table, table) Setup component context and his style table
Component.create(name, interest)Component.create(name[, interest={}]) Create new component.
@@ -152,32 +156,14 @@

Functions

-
- - get_style() -
-
- Get current component style table - - - -

Returns:

-
    - - table - Component style table -
- - - - -
set_style(style)
- Set current component style table + Set current component style table. + Invoke on_style_change on component, if exist. Component should handle + their style changing and store all style params

Parameters:

@@ -414,10 +400,50 @@ +
+
+ + is_child_of() +
+
+ Return true, if current component is child of another component + + + +

Returns:

+
    + + bool + True, if current component is child of another +
+ + + + +
+
+ + get_name() +
+
+ Return component name + + + +

Returns:

+
    + + string + The component name +
+ + + +
- setup_component(table, table) + setup_component(table, table, table)
Setup component context and his style table @@ -433,6 +459,10 @@ style Druid style module +
  • table + style + Druid style module +
  • Returns:

    @@ -448,7 +478,7 @@
    - Component.create(name, interest) + Component.create(name[, interest={}])
    Create new component. It will inheritance from basic @@ -464,6 +494,7 @@
  • interest table List of component's interest + (default {})
  • @@ -479,7 +510,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.back_handler.html b/docs/modules/druid.back_handler.html index 7e95a33..7f6e1b0 100644 --- a/docs/modules/druid.back_handler.html +++ b/docs/modules/druid.back_handler.html @@ -218,7 +218,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.blocker.html b/docs/modules/druid.blocker.html index 721f904..236317c 100644 --- a/docs/modules/druid.blocker.html +++ b/docs/modules/druid.blocker.html @@ -237,7 +237,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.button.html b/docs/modules/druid.button.html index 883e585..0c807bf 100644 --- a/docs/modules/druid.button.html +++ b/docs/modules/druid.button.html @@ -123,7 +123,7 @@ Style - Component style params + Component style params. @@ -382,11 +382,28 @@ Style
    - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

    Fields:

      +
    • LONGTAP_TIME + number + Minimum time to trigger onholdcallback + (default 0.4) +
    • +
    • AUTOHOLD_TRIGGER + number + Maximum hold time to trigger button release while holding + (default 0.8) +
    • +
    • DOUBLETAP_TIME + number + Time between double taps + (default 0.4) +
    • on_click function (self, node) @@ -399,6 +416,10 @@ function (self, node, hover_state)
    • +
    • on_mouse_hover + function + (self, node, hover_state) +
    • on_set_enabled function (self, node, enabled_state) @@ -417,7 +438,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
      diff --git a/docs/modules/druid.checkbox.html b/docs/modules/druid.checkbox.html index ea9bf32..8d8c732 100644 --- a/docs/modules/druid.checkbox.html +++ b/docs/modules/druid.checkbox.html @@ -111,7 +111,7 @@ Style - Component style params + Component style params. @@ -257,7 +257,9 @@ Style
      - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

      Fields:

      @@ -280,7 +282,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
      diff --git a/docs/modules/druid.checkbox_group.html b/docs/modules/druid.checkbox_group.html index ee56ba9..bd03b40 100644 --- a/docs/modules/druid.checkbox_group.html +++ b/docs/modules/druid.checkbox_group.html @@ -242,7 +242,7 @@
      generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
      diff --git a/docs/modules/druid.drag.html b/docs/modules/druid.drag.html index a25b190..5cc0261 100644 --- a/docs/modules/druid.drag.html +++ b/docs/modules/druid.drag.html @@ -107,7 +107,7 @@ Style - Component style params + Component style params. @@ -256,7 +256,9 @@ Style
      - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

      Fields:

      @@ -264,6 +266,7 @@
    • DRAG_DEADZONE number Distance in pixels to start dragging + (default 10)
    @@ -279,7 +282,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.grid.html b/docs/modules/druid.grid.html index a487fda..730bc39 100644 --- a/docs/modules/druid.grid.html +++ b/docs/modules/druid.grid.html @@ -110,7 +110,7 @@ clear() - Clear all items from the grid + Clear grid nodes array.

    Tables

    @@ -275,7 +275,8 @@ clear()
    - Clear all items from the grid + Clear grid nodes array. GUI nodes will be not deleted! + If you want to delete GUI nodes, use grid.nodes array before grid:clear @@ -373,7 +374,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.helper.html b/docs/modules/druid.helper.html index e05799f..64a239d 100644 --- a/docs/modules/druid.helper.html +++ b/docs/modules/druid.helper.html @@ -298,7 +298,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.hover.html b/docs/modules/druid.hover.html index 7d36b64..25a72f9 100644 --- a/docs/modules/druid.hover.html +++ b/docs/modules/druid.hover.html @@ -95,6 +95,10 @@ Set hover state + set_mouse_hover(state) + Set mouse hover state + + set_click_zone(zone) Strict hover click area. @@ -159,6 +163,27 @@ +
    +
    + + set_mouse_hover(state) +
    +
    + Set mouse hover state + + +

    Parameters:

    +
      +
    • state + bool + The mouse hover state +
    • +
    + + + + +
    @@ -198,7 +223,11 @@
    • on_hover druid_event - On hover callback + On hover callback (Touch pressed) +
    • +
    • on_mouse_hover + druid_event + On mouse hover callback (Touch over without action_id)
    @@ -214,7 +243,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.html b/docs/modules/druid.html index ea8c216..ac40eb7 100644 --- a/docs/modules/druid.html +++ b/docs/modules/druid.html @@ -329,7 +329,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.input.html b/docs/modules/druid.input.html index 737bc3d..d5a0952 100644 --- a/docs/modules/druid.input.html +++ b/docs/modules/druid.input.html @@ -121,7 +121,7 @@ Style - Component style params + Component style params. @@ -341,7 +341,9 @@ Style
    - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

    Fields:

    @@ -349,14 +351,12 @@
  • IS_LONGTAP_ERASE bool Is long tap will erase current input data -
  • -
  • BUTTON_SELECT_INCREASE - number - Button scale multiplier on selecting input field + (default false)
  • MASK_DEFAULT_CHAR string Default character mask for password input + (default *)
  • on_select function @@ -370,7 +370,7 @@ function (self, button_node) Callback on wrong user input
  • -
  • button +
  • button_style table Custom button style for input node
  • @@ -388,7 +388,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.lang_text.html b/docs/modules/druid.lang_text.html index 8345b88..84c9334 100644 --- a/docs/modules/druid.lang_text.html +++ b/docs/modules/druid.lang_text.html @@ -243,7 +243,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.progress.html b/docs/modules/druid.progress.html index 60b3a72..ec3270b 100644 --- a/docs/modules/druid.progress.html +++ b/docs/modules/druid.progress.html @@ -125,7 +125,7 @@ Style - Component style params + Component style params. @@ -355,7 +355,9 @@ Style
    - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

    Fields:

    @@ -363,10 +365,12 @@
  • SPEED number Progress bas fill rate. More -> faster + (default 5)
  • MIN_DELTA number Minimum step to fill progress bar + (default 0.005)
  • @@ -382,7 +386,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.radio_group.html b/docs/modules/druid.radio_group.html index 65b2d6f..f87e4ad 100644 --- a/docs/modules/druid.radio_group.html +++ b/docs/modules/druid.radio_group.html @@ -242,7 +242,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.scroll.html b/docs/modules/druid.scroll.html index e9aae94..da5ff6e 100644 --- a/docs/modules/druid.scroll.html +++ b/docs/modules/druid.scroll.html @@ -122,7 +122,7 @@ Return if scroll have inertion. - set_extra_strech_size(stretch_size) + set_extra_strech_size([stretch_size=0]) Set extra size for scroll stretching. @@ -146,7 +146,7 @@ Style - Component style params + Component style params. @@ -369,7 +369,7 @@
    - set_extra_strech_size(stretch_size) + set_extra_strech_size([stretch_size=0])
    Set extra size for scroll stretching. @@ -381,6 +381,7 @@
  • stretch_size number Size in pixels of additional scroll area + (default 0)
  • @@ -543,46 +544,57 @@ Style
    - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

    Fields:

      -
    • FRICT_HOLD - number - Multiplier for inertion, while touching -
    • FRICT number Multiplier for free inertion + (default 0) +
    • +
    • FRICT_HOLD + number + Multiplier for inertion, while touching + (default 0)
    • INERT_THRESHOLD number Scroll speed to stop inertion + (default 3)
    • INERT_SPEED number Multiplier for inertion speed + (default 30)
    • POINTS_DEADZONE number Speed to check points of interests in no_inertion mode + (default 20)
    • BACK_SPEED number Scroll back returning lerp speed + (default 0.35)
    • ANIM_SPEED number Scroll gui.animation speed for scroll_to function + (default 0.2)
    • EXTRA_STRECH_SIZE number extra size in pixels outside of scroll (stretch effect) + (default 0)
    • SMALL_CONTENT_SCROLL bool If true, content node with size less than view node size can be scrolled + (default false)
    @@ -598,7 +610,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.slider.html b/docs/modules/druid.slider.html index c81ac6e..1303128 100644 --- a/docs/modules/druid.slider.html +++ b/docs/modules/druid.slider.html @@ -281,7 +281,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.swipe.html b/docs/modules/druid.swipe.html index 6589bc4..60464fd 100644 --- a/docs/modules/druid.swipe.html +++ b/docs/modules/druid.swipe.html @@ -106,7 +106,7 @@ Style - Component style params + Component style params. @@ -220,7 +220,9 @@ Style
    - Component style params + Component style params. + You can override this component styles params in druid styles table + or create your own style

    Fields:

    @@ -228,14 +230,17 @@
  • SWIPE_TIME number Maximum time for swipe trigger + (default 0.4)
  • SWIPE_THRESHOLD number Minimum distance for swipe trigger + (default 50)
  • SWIPE_TRIGGER_ON_MOVE bool If true, trigger on swipe moving, not only release action + (default false)
  • @@ -251,7 +256,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.text.html b/docs/modules/druid.text.html index a081325..b75b29b 100644 --- a/docs/modules/druid.text.html +++ b/docs/modules/druid.text.html @@ -407,7 +407,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid.timer.html b/docs/modules/druid.timer.html index c1ad7b9..517ff76 100644 --- a/docs/modules/druid.timer.html +++ b/docs/modules/druid.timer.html @@ -296,7 +296,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid_event.html b/docs/modules/druid_event.html index 877e8bc..261e260 100644 --- a/docs/modules/druid_event.html +++ b/docs/modules/druid_event.html @@ -242,7 +242,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/modules/druid_instance.html b/docs/modules/druid_instance.html index ad27765..c0f164b 100644 --- a/docs/modules/druid_instance.html +++ b/docs/modules/druid_instance.html @@ -211,6 +211,10 @@ druid:new_swipe(...) Create swipe basic component + + druid:new_drag(...) + Create drag basic component +
    @@ -874,6 +878,33 @@ +
    +
    + + druid:new_drag(...) +
    +
    + Create drag basic component + + +

    Parameters:

    +
      +
    • ... + args + drag init args +
    • +
    + +

    Returns:

    +
      + + Componetn + drag component +
    + + + +
    @@ -882,7 +913,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/01-components.md.html b/docs/topics/01-components.md.html index 7f48b5e..21478e4 100644 --- a/docs/topics/01-components.md.html +++ b/docs/topics/01-components.md.html @@ -48,6 +48,7 @@
  • Grid
  • Hover
  • Swipe
  • +
  • Drag
  • @@ -158,7 +159,7 @@ Where node name is name of node from GUI scene. You can use node_name

    Blocker

    -

    Blocker API here

    +

    Blocker API here

    Overview

    Druid component for block input. Use it to block input in special zone.

    @@ -211,32 +212,35 @@ Where node name is name of node from GUI scene. You can use node_nameBasic Druid scroll component. Handle all scrolling stuff in druid GUI

    Setup

    -

    Create scroll component with druid: scroll = druid:new_scroll(scroll_parent, scroll_input).

    +

    Create scroll component with druid: scroll = druid:new_scroll(view_node, content_node).

    -

    Scroll parent - is dynamic part. This node will change position by scroll system

    +

    Viewnode_ - is static part. It capturing user input and recognize scrolling touches

    -

    Scroll input - is static part. It capturing user input and recognize scrolling touches

    +

    Contentnode_ - is dynamic part. This node will change position by scroll system

    -

    Initial scroll size will be equal to scroll parent node size. The initial view box will be equal to scroll input node size

    +

    Initial scroll size will be equal to contentnode_ node size. The initial view box will be equal to viewnode_ node size

    -

    Usually, Place static input zone part, and as children add scroll parent part: +

    Usually, Place viewnode_ and as children add contentnode_:

    -

    *Here scrollcontentzone below input zone, in game content zone be able to scroll left until end*

    +

    *Here contentnode below viewnode, in game content_node be able to scroll left until end*

    Notes

    -

    - Scroll by default style have inertion and "back moving". It can be adjust via scroll style settings +

    - Scroll by default style have inertion and extra size for strecthing effect. It can be adjust via scroll style settings - You can setup "points of interest". Scroll always will be centered on closes point of interest. It is able to create slider without inertion and points of interest on each scroll element. - Scroll have next events:

    -- *on_scroll* On scroll move callback
    -- *on_scroll_to* On scroll_to function callback
    -- *on_point_scroll* On scroll_to_index function callback
    +- *on_scroll* (self, position) On scroll move callback
    +- *on_scroll_to* (self, position, is_instant) On scroll_to function callback
    +- *on_point_scroll* (self, item_index, position) On scroll_to_index function callback
     
    -

    - You can adjust scroll content size by scroll:set_border(node_size). It will setup new size to content node.

    +

    - You can adjust scroll content size by scroll:set_size(node_size). It will setup new size to content node +- You can enabled or disable inertion mode via scroll:set_intert(state) +- You can adjust extra stretch size via scroll:set_extra_stretch_size +- Multitouch is required for scroll. Scroll is correctly handling touch_id swap while dragging scroll

    @@ -361,7 +365,7 @@ Key is value from druid const: const.SIDE.X (or just "x") or const.SIDE.Y (or ju

    Component for manage node positions. Very simple implementation for nodes with equal size

    Setup

    -

    Create grid component with druid: grid = druid:new_grid(parent_node, prefab_node, max_in_row_elements)

    +

    Create component with druid: grid = druid:new_grid(parent_node, prefab_node, max_in_row_elements)

    Notes

    - Grid on adding elements will setup parent to parentnode_ @@ -381,6 +385,8 @@ Key is value from druid const: const.SIDE.X (or just "x") or const.SIDE.Y (or ju

    Create hover component with druid: hover = druid:new_hover(node, callback)

    Notes

    +

    - By default, hover handles hover event with pressed touch action_id. So it's mean, what mouse or touch have to be pressed +- On desktop platforms there is onmousehover event. It's event on mouse hover without any action id

    @@ -391,7 +397,7 @@ Key is value from druid const: const.SIDE.X (or just "x") or const.SIDE.Y (or ju

    System Druid component, handle swipe actions on node

    Setup

    -

    Create hover component with druid: hover = druid:new_swipe(node, swipe_callback)

    +

    Create swipe component with druid: hover = druid:new_swipe(node, swipe_callback)

    Notes

    - Swipe callback have next params: (self, swipe_side, distance, time)

    @@ -404,16 +410,60 @@ Key is value from druid const: const.SIDE.X (or just "x") or const.SIDE.Y (or ju

    - Swipe trigger only, if all input actions was on swipe node. If action will be outside of node, swipe status will be reseted -- In swipe style table you can adjust minimal distance and maximum time to trigger swipe +- In swipe style table you can adjust minimal distance and maximum time to trigg- Hover state trigger only with touch on mobile devices or button mouse holding. Just mouse over swipe - In swipe style table you can toggle type of swipe triggering. if SWIPETRIGGERON_MOVE setup to true - swipe will trigger as swipe can be triggered. If setup to false - swipe will trigger only on released action -- If you have stencil on swipe node and you don't want trigger it outside of stencil node, you can use swipe:set_click_zone to restrict swipe zone

    +- If you have stencil on swipe node and you don't want trigger it outside of stencil node, you can use swipe:set_click_zone to restrict swipe zonethout buttons is now not allowed.

    + + +

    +

    Drag

    +

    Drag API here

    + +

    Overview

    +

    System Druid component, handle drag actions on node

    + +

    Setup

    +

    Create drag component with druid: hover = druid:new_drag(node, drag_callback)

    + +

    Notes

    +

    - Drag callback have next params: (self, swipe_side, distance, time)

    + +
    +- **self**: Druid self context
    +- **dx**: *number* - delta x position
    +- **dy**: *number* - delta y position
    +
    + +

    - In styles, you can point the drag start deadzone. Default value is 10 pixels +- Drag correctly process multitouch. You can switch touch_id, while dragging on node with correct dx and dy values (made for correct scrolling) +- You can restrict horizontal or vertical dragging by setting drag.can_x or drag.can_y to false value +- You can get info about current drag state:

    + +
    +- _is_touch_ - Is currently node touching
    +- _is_drag_ - Is currently node is dragging
    +- _x_ and _y_ - Current touch position
    +- _touch_start_pos_ - Touch stat positions
    +
    + +

    - Drag have next events:

    + +
    +- _on_touch_start_ (self) - Event on touch start
    +- _on_touch_end_ (self) - Event on touch end
    +- _on_drag_start_ (self) - Event on drag start
    +- _on_drag_ (self, dx, dy) - Event on drag process
    +- _on_drag_end_ (self) - Event on drag end
    +
    + +

    - Drag node zone can be restricted via drag:set_click_zone(node)

    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/02-creating_custom_components.md.html b/docs/topics/02-creating_custom_components.md.html index 67a5e37..086bc4f 100644 --- a/docs/topics/02-creating_custom_components.md.html +++ b/docs/topics/02-creating_custom_components.md.html @@ -113,6 +113,10 @@ function M.on_input(self, action_id, action) end +-- Call on component creation and on component:set_style() function +function M.on_style_change(self, style) +end + -- Call only if exist interest: const.ON_MESSAGE function M.on_message(self, message_id, message, sender) end @@ -226,10 +230,6 @@ There is next interests in druid: -- Button self on callback is self of _this_ component local button = druid:new_button(...) - - -- helper can return you the component style for current component - -- It return by component name from - local my_style = self:get_style() end @@ -245,7 +245,7 @@ There is next interests in druid:
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/03-styles.md.html b/docs/topics/03-styles.md.html index 8bdb3b1..b51a6c6 100644 --- a/docs/topics/03-styles.md.html +++ b/docs/topics/03-styles.md.html @@ -34,6 +34,7 @@ @@ -90,7 +91,8 @@

    Usage

    -

    Setup default druid style for all druid instances via druid.set_default_style

    +

    Setup default druid style for all druid instances via druid.set_default_style +You can pass nil or emptytable_ to use default values for all components (no styles)

     local druid = require("druid.druid")
    @@ -131,11 +133,29 @@
     
     
     
    +

    +

    Create your own styles

    + +

    The most components have their styles. You can explore it on Druid API in table style section (button example). Or you can see, what fields component uses in code in function on_style_change

    + +

    To create you style, create lua module, what return <componentname_, componentstyle_> table

    + +

    Example: default druid style

    + +

    Override all fields you want and set your style with one of next ways:

    + +
      +
    • Set your style as global via druid.set_default_style
    • +
    • Set style for concrete druid instance via druid = druid.new(self, style)
    • +
    • Set style for concrete instance via component:set_style(style)
    • +
    + +
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/04-druid_assets.md.html b/docs/topics/04-druid_assets.md.html index 738e4fb..8df0a70 100644 --- a/docs/topics/04-druid_assets.md.html +++ b/docs/topics/04-druid_assets.md.html @@ -92,7 +92,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/05-examples.md.html b/docs/topics/05-examples.md.html index 187c016..c124314 100644 --- a/docs/topics/05-examples.md.html +++ b/docs/topics/05-examples.md.html @@ -90,7 +90,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/README.md.html b/docs/topics/README.md.html index 2205ddb..07dcf24 100644 --- a/docs/topics/README.md.html +++ b/docs/topics/README.md.html @@ -116,6 +116,7 @@
  • Key trigger - Back -> key_back For backhandler component, Android back button, input component_
  • Key trigger - Enter -> key_enter For input component, optional
  • Key trigger - Esc -> key_esc For input component, optional
  • +
  • Touch triggers - Touch multi -> multitouch For scroll component
  • @@ -152,7 +153,7 @@ -- Call this function on language changing in the game, -- to retranslate all lang_text components: -druid.on_languge_change() +druid.on_language_change() -- Call this function on layout changing in the game, -- to reapply layouts @@ -187,6 +188,7 @@

  • Grid - Component for manage node positions

  • Hover - System Druid component, handle hover node state

  • Swipe - System Druid component, handle swipe gestures on node

  • +
  • Drag - System Druid component, handle drag input on node

  • Full info see on components.md

    @@ -271,7 +273,7 @@
    • *on_input* used for almost all basic druid components
    • update used for progress bar, scroll and timer base components
    • -
    • *on_message* used for specific druid events, like language change or layout change (TODO: in future)
    • +
    • *on_message* used for specific druid events, like language change or layout change
    • final used for custom components, what have to do several action before destroy
    @@ -319,13 +321,13 @@ https://insality.github.io/druid/

    License

    -

    Original created by AGulev

    + -

    Developed and supporting by Insality

    - -

    Assets from Kenney

    - -

    MIT License

    +

    MIT License

    @@ -337,7 +339,7 @@ https://insality.github.io/druid/

    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs/topics/changelog.md.html b/docs/topics/changelog.md.html index 2cfc3d9..4fe82e0 100644 --- a/docs/topics/changelog.md.html +++ b/docs/topics/changelog.md.html @@ -140,21 +140,52 @@
  • Druid Scroll component fully reworked. Input logic moved to Drag component

    -- Updated scroll documentation
    -- Changed constructor order params
    +- Update scroll documentation
    +- Change constructor order params
    +- 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 scroll size via _.gui_ scene. Just setup correct node size
    -- Different anchoring is supported (for easier layout)
    +- 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_
    +- **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 can be disappeared
     
  • -
  • Grid anchor by default equals to node pivot (so, more gui settings in .gui settings)

  • +
  • 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 style can be only set
    +- 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 bloker)

  • +
  • 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

  • @@ -162,7 +193,7 @@
    generated by LDoc 1.4.6 -Last updated 2020-05-04 00:51:46 +Last updated 2020-05-09 16:07:15
    diff --git a/docs_md/01-components.md b/docs_md/01-components.md index fd94779..9b3ee6e 100644 --- a/docs_md/01-components.md +++ b/docs_md/01-components.md @@ -51,7 +51,7 @@ Create text node with druid: `text = druid:new_text(node_name, [initial_value], ## Blocker -[Blocker API here](https://insality.github.io/druid/modules/druid.button.html) +[Blocker API here](https://insality.github.io/druid/modules/druid.blocker.html) ### Overview Druid component for block input. Use it to block input in special zone. @@ -101,28 +101,31 @@ Create lang text component with druid `text = druid:new_lang_text(node_name, loc Basic Druid scroll component. Handle all scrolling stuff in druid GUI ### Setup -Create scroll component with druid: `scroll = druid:new_scroll(scroll_parent, scroll_input)`. +Create scroll component with druid: `scroll = druid:new_scroll(view_node, content_node)`. -_Scroll parent_ - is dynamic part. This node will change position by scroll system +_View_node_ - is static part. It capturing user input and recognize scrolling touches -_Scroll input_ - is static part. It capturing user input and recognize scrolling touches +_Content_node_ - is dynamic part. This node will change position by scroll system -Initial scroll size will be equal to _scroll parent_ node size. The initial view box will be equal to _scroll input_ node size +Initial scroll size will be equal to _content_node_ node size. The initial view box will be equal to _view_node_ node size -Usually, Place static input zone part, and as children add scroll parent part: +Usually, Place _view_node_ and as children add _content_node_: ![](../media/scroll_scheme.png) ![](../media/scroll_outline.png) -*Here scroll_content_zone below input zone, in game content zone be able to scroll left until end* +*Here content_node below view_node, in game content_node be able to scroll left until end* ### Notes -- Scroll by default style have inertion and "back moving". It can be adjust via scroll [style settings](https://insality.github.io/druid/modules/druid.scroll.html#Style) +- Scroll by default style have inertion and extra size for strecthing effect. It can be adjust via scroll [style settings](https://insality.github.io/druid/modules/druid.scroll.html#Style) - You can setup "points of interest". Scroll always will be centered on closes point of interest. It is able to create slider without inertion and points of interest on each scroll element. - Scroll have next events: - - *on_scroll* On scroll move callback - - *on_scroll_to* On scroll_to function callback - - *on_point_scroll* On scroll_to_index function callback -- You can adjust scroll content size by `scroll:set_border(node_size)`. It will setup new size to content node. + - *on_scroll* (self, position) On scroll move callback + - *on_scroll_to* (self, position, is_instant) On scroll_to function callback + - *on_point_scroll* (self, item_index, position) On scroll_to_index function callback +- You can adjust scroll content size by `scroll:set_size(node_size)`. It will setup new size to _content node_ +- You can enabled or disable inertion mode via `scroll:set_intert(state)` +- You can adjust extra stretch size via `scroll:set_extra_stretch_size` +- Multitouch is required for scroll. Scroll is correctly handling touch_id swap while dragging scroll ## Progress @@ -239,7 +242,7 @@ Create timer component with druid: `timer = druid:new_timer(text_node, from_seco Component for manage node positions. Very simple implementation for nodes with equal size ### Setup -Create grid component with druid: `grid = druid:new_grid(parent_node, prefab_node, max_in_row_elements)` +Create component with druid: `grid = druid:new_grid(parent_node, prefab_node, max_in_row_elements)` ### Notes - Grid on _adding elements_ will setup parent to _parent_node_ @@ -258,6 +261,8 @@ System Druid component, handle hover node state. Create hover component with druid: `hover = druid:new_hover(node, callback)` ### Notes +- By default, hover handles _hover event_ with pressed touch action_id. So it's mean, what mouse or touch have to be pressed +- On desktop platforms there is _on_mouse_hover_ event. It's event on mouse hover without any action id ## Swipe @@ -267,7 +272,7 @@ Create hover component with druid: `hover = druid:new_hover(node, callback)` System Druid component, handle swipe actions on node ### Setup -Create hover component with druid: `hover = druid:new_swipe(node, swipe_callback)` +Create swipe component with druid: `hover = druid:new_swipe(node, swipe_callback)` ### Notes - Swipe callback have next params: (self, swipe_side, distance, time) @@ -276,6 +281,37 @@ Create hover component with druid: `hover = druid:new_swipe(node, swipe_callback - **distance**: *number* - in pixels, distance of swipe - **time**: *number* - in seconds, time of swiping - Swipe trigger only, if all input actions was on swipe node. If action will be outside of node, swipe status will be reseted -- In swipe style table you can adjust minimal distance and maximum time to trigger swipe +- In swipe style table you can adjust minimal distance and maximum time to trigg- Hover state trigger only with touch on mobile devices or button mouse holding. Just mouse over swipe - In swipe style table you can toggle type of swipe triggering. if SWIPE_TRIGGER_ON_MOVE setup to true - swipe will trigger as swipe can be triggered. If setup to false - swipe will trigger only on released action -- If you have stencil on swipe node and you don't want trigger it outside of stencil node, you can use `swipe:set_click_zone` to restrict swipe zone \ No newline at end of file +- If you have stencil on swipe node and you don't want trigger it outside of stencil node, you can use `swipe:set_click_zone` to restrict swipe zonethout buttons is now not allowed. + + +## Drag +[Drag API here](https://insality.github.io/druid/modules/druid.drag.html) + +### Overview +System Druid component, handle drag actions on node + +### Setup +Create drag component with druid: `hover = druid:new_drag(node, drag_callback)` + +### Notes +- Drag callback have next params: (self, swipe_side, distance, time) + - **self**: Druid self context + - **dx**: *number* - delta x position + - **dy**: *number* - delta y position +- In styles, you can point the drag start deadzone. Default value is 10 pixels +- Drag correctly process multitouch. You can switch touch_id, while dragging on node with correct _dx_ and _dy_ values (made for correct scrolling) +- You can restrict horizontal or vertical dragging by setting `drag.can_x` or `drag.can_y` to _false_ value +- You can get info about current drag state: + - _is_touch_ - Is currently node touching + - _is_drag_ - Is currently node is dragging + - _x_ and _y_ - Current touch position + - _touch_start_pos_ - Touch stat positions +- Drag have next events: + - _on_touch_start_ (self) - Event on touch start + - _on_touch_end_ (self) - Event on touch end + - _on_drag_start_ (self) - Event on drag start + - _on_drag_ (self, dx, dy) - Event on drag process + - _on_drag_end_ (self) - Event on drag end +- Drag node zone can be restricted via `drag:set_click_zone(node)` diff --git a/docs_md/02-creating_custom_components.md b/docs_md/02-creating_custom_components.md index 38534e3..b6ed5ed 100644 --- a/docs_md/02-creating_custom_components.md +++ b/docs_md/02-creating_custom_components.md @@ -28,6 +28,10 @@ end function M.on_input(self, action_id, action) end +-- Call on component creation and on component:set_style() function +function M.on_style_change(self, style) +end + -- Call only if exist interest: const.ON_MESSAGE function M.on_message(self, message_id, message, sender) end @@ -138,10 +142,6 @@ function M.init(self, template_name, node_table) -- Button self on callback is self of _this_ component local button = druid:new_button(...) - - -- helper can return you the component style for current component - -- It return by component name from - local my_style = self:get_style() end ``` diff --git a/docs_md/03-styles.md b/docs_md/03-styles.md index d651333..426c3a7 100644 --- a/docs_md/03-styles.md +++ b/docs_md/03-styles.md @@ -9,6 +9,7 @@ In component API documentation, you can find the style API for this component. O ## Usage Setup default druid style for all druid instances via `druid.set_default_style` +You can pass _nil_ or _empty_table_ to use default values for all components (no styles) ```lua local druid = require("druid.druid") local my_style = require("my.amazing.style") @@ -41,3 +42,18 @@ local function init(self) self.button:set_style(my_style) end ``` + + +## Create your own styles + +The most components have their styles. You can explore it on [Druid API](https://insality.github.io/druid/) in table style section ([button example](https://insality.github.io/druid/modules/druid.button.html#Style)). Or you can see, what fields component uses in code in function `on_style_change` + +To create you style, create lua module, what return <_component_name_, _component_style_> table + +Example: [default druid style](https://github.com/Insality/druid/blob/develop/druid/styles/default/style.lua) + +Override all fields you want and set your style with one of next ways: + +- Set your style as global via `druid.set_default_style` +- Set style for concrete druid instance via `druid = druid.new(self, style)` +- Set style for concrete instance via `component:set_style(style)` \ No newline at end of file diff --git a/docs_md/changelog.md b/docs_md/changelog.md index ceb4a95..e809c88 100644 --- a/docs_md/changelog.md +++ b/docs_md/changelog.md @@ -58,16 +58,17 @@ Druid 0.4.0: - 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 - - Updated scroll documentation - - Changed constructor order params + - Update scroll documentation + - Change constructor order params + - 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 scroll size via _.gui_ scene. Just setup correct node size - - Different anchoring is supported (for easier layout) + - 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_ + - **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 can be disappeared - Druid _Grid_ Update @@ -75,7 +76,7 @@ Druid 0.4.0: - 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 old hover event. Trigger only if touch pressed on node + - _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: @@ -89,4 +90,4 @@ Druid 0.4.0: - **Fix:** Blocker component bug (blocker had very high priority, so it's block even button components, created after bloker) - **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 \ No newline at end of file +- **Fix #53:** Bug with final _Druid instance_ without any components diff --git a/game.project b/game.project index 4fd3084..055a75d 100644 --- a/game.project +++ b/game.project @@ -10,7 +10,7 @@ height = 900 [project] title = druid -version = 0.3.0 +version = 0.4.0 [library] include_dirs = druid diff --git a/media/input_binding_1.png b/media/input_binding_1.png index aac429b0f1d06e389379f8606ebf31378083e3b7..aa0856a63ab8b33b81e529a7dcb2f0122b9d7825 100644 GIT binary patch delta 18466 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 delta 10142 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 KNtC@Y4){M>bhSYM