mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 10:27:47 +02:00
Merge branch 'develop' into rich_text
This commit is contained in:
commit
6ea5ed0b97
@ -45,8 +45,12 @@ globals = {
|
|||||||
"debug",
|
"debug",
|
||||||
"timer",
|
"timer",
|
||||||
"window",
|
"window",
|
||||||
"buffer",
|
"buffer",
|
||||||
"resource",
|
"resource",
|
||||||
"defos",
|
"defos",
|
||||||
"html5",
|
"html5",
|
||||||
|
"describe",
|
||||||
|
"before",
|
||||||
|
"after",
|
||||||
|
"it",
|
||||||
}
|
}
|
||||||
|
14
README.md
14
README.md
@ -25,13 +25,13 @@ Or point to the ZIP file of a [specific release](https://github.com/Insality/dru
|
|||||||
**Druid** requires the following input bindings:
|
**Druid** requires the following input bindings:
|
||||||
|
|
||||||
- Mouse trigger - `Button 1` -> `touch` _For basic input components_
|
- Mouse trigger - `Button 1` -> `touch` _For basic input components_
|
||||||
- Mouse trigger - `Wheel up` -> `scroll_up` _For scroll component_
|
- Mouse trigger - `Wheel up` -> `mouse_wheel_up` _For scroll component_
|
||||||
- Mouse trigger - `Wheel down` -> `scroll_down` _For scroll component_
|
- Mouse trigger - `Wheel down` -> `mouse_wheel_down` _For scroll component_
|
||||||
- Key trigger - `Backspace` -> `key_backspace` _For back_handler component, input component_
|
- 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 - `Back` -> `key_back` _For back_handler component, Android back button, input component_
|
||||||
- Key trigger - `Enter` -> `key_enter` _For input component, optional_
|
- Key trigger - `Enter` -> `key_enter` _For input component, optional_
|
||||||
- Key trigger - `Esc` -> `key_esc` _For input component, optional_
|
- Key trigger - `Esc` -> `key_esc` _For input component, optional_
|
||||||
- Touch triggers - `Touch multi` -> `multitouch` _For scroll component_
|
- Touch triggers - `Touch multi` -> `touch_multi` _For scroll component_
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@ -50,9 +50,9 @@ input_key_esc = key_esc
|
|||||||
input_key_back = key_back
|
input_key_back = key_back
|
||||||
input_key_enter = key_enter
|
input_key_enter = key_enter
|
||||||
input_key_backspace = key_backspace
|
input_key_backspace = key_backspace
|
||||||
input_multitouch = multitouch
|
input_multitouch = touch_multi
|
||||||
input_scroll_up = scroll_up
|
input_scroll_up = mouse_wheel_up
|
||||||
input_scroll_down = scroll_down
|
input_scroll_down = mouse_wheel_down
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ Here is full **Druid** components list:
|
|||||||
| Name | Description | API page | Example Link | Is Basic component[^1] | Preview |
|
| Name | Description | API page | Example Link | Is Basic component[^1] | Preview |
|
||||||
|------|-------------|----------|------------|-------------|---------|
|
|------|-------------|----------|------------|-------------|---------|
|
||||||
| **[Button](docs_md/01-components.md#button)** | Basic input component. Handles all types of interactions: click, long click, hold click, double click, etc | [Button API](https://insality.github.io/druid/modules/Button.html) | [Button Example](https://insality.github.io/druid/druid/?example=general_buttons) | ✅ | <img src="media/preview/button.gif" width="200" height="100"> |
|
| **[Button](docs_md/01-components.md#button)** | Basic input component. Handles all types of interactions: click, long click, hold click, double click, etc | [Button API](https://insality.github.io/druid/modules/Button.html) | [Button Example](https://insality.github.io/druid/druid/?example=general_buttons) | ✅ | <img src="media/preview/button.gif" width="200" height="100"> |
|
||||||
| **[Text](docs_md/01-components.md#text)** | Wrap on GUI text node, handle different text size adjusting, providing additional text API | [Text API](https://insality.github.io/druid/modules/Button.html) | [Text Example](https://insality.github.io/druid/druid/?example=texts_general) | ✅ | <img src="media/preview/text.gif" width="200" height="100"> |
|
| **[Text](docs_md/01-components.md#text)** | Wrap on GUI text node, handle different text size adjusting, providing additional text API | [Text API](https://insality.github.io/druid/modules/Text.html) | [Text Example](https://insality.github.io/druid/druid/?example=texts_general) | ✅ | <img src="media/preview/text.gif" width="200" height="100"> |
|
||||||
| **[Scroll](docs_md/01-components.md#scroll)** | Scroll component | [Scroll API](https://insality.github.io/druid/modules/Scroll.html) | [Scroll Example](https://insality.github.io/druid/druid/?example=general_scroll) | ✅ | <img src="media/preview/scroll.gif" width="200" height="100"> |
|
| **[Scroll](docs_md/01-components.md#scroll)** | Scroll component | [Scroll API](https://insality.github.io/druid/modules/Scroll.html) | [Scroll Example](https://insality.github.io/druid/druid/?example=general_scroll) | ✅ | <img src="media/preview/scroll.gif" width="200" height="100"> |
|
||||||
| **[Blocker](docs_md/01-components.md#blocker)** | Block user input in node zone area | [Blocker API](https://insality.github.io/druid/modules/Blocker.html) | ❌ | ✅ | |
|
| **[Blocker](docs_md/01-components.md#blocker)** | Block user input in node zone area | [Blocker API](https://insality.github.io/druid/modules/Blocker.html) | ❌ | ✅ | |
|
||||||
| **[Back Handler](docs_md/01-components.md#back-handler)** | Handle back button (Android back button, backspace key) | [Back Handler API](https://insality.github.io/druid/modules/BackHandler.html) | ❌ | ✅ | |
|
| **[Back Handler](docs_md/01-components.md#back-handler)** | Handle back button (Android back button, backspace key) | [Back Handler API](https://insality.github.io/druid/modules/BackHandler.html) | ❌ | ✅ | |
|
||||||
|
@ -445,4 +445,4 @@ And yeah, the new **Druid** logo is here!
|
|||||||
- **#189** [System] Add optional flag to `component:set_input_priority` to mark it as temporary. It will reset to default input priority after the `component:reset_input_priority`
|
- **#189** [System] Add optional flag to `component:set_input_priority` to mark it as temporary. It will reset to default input priority after the `component:reset_input_priority`
|
||||||
- **#204** [System] Fix: wrong code example link, if open example from direct URL
|
- **#204** [System] Fix: wrong code example link, if open example from direct URL
|
||||||
- **#202** [System] Enabled stencil check to true by default. To disable this, use `druid.no_stencil_check` in game.project settings
|
- **#202** [System] Enabled stencil check to true by default. To disable this, use `druid.no_stencil_check` in game.project settings
|
||||||
- [Examples] Add layout, layout fit, progres bar, data list + component examples
|
- [Examples] Add layout, layout fit, progress bar, data list + component examples
|
||||||
|
@ -61,7 +61,7 @@ local Button = component.create("button")
|
|||||||
|
|
||||||
|
|
||||||
local function is_input_match(self, action_id)
|
local function is_input_match(self, action_id)
|
||||||
if action_id == const.ACTION_TOUCH then
|
if action_id == const.ACTION_TOUCH or action_id == const.ACTION_MULTITOUCH then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ local function on_button_release(self)
|
|||||||
self.can_action = false
|
self.can_action = false
|
||||||
|
|
||||||
local time = socket.gettime()
|
local time = socket.gettime()
|
||||||
local is_long_click = (time - self.last_pressed_time) > self.style.LONGTAP_TIME
|
local is_long_click = (time - self.last_pressed_time) >= self.style.LONGTAP_TIME
|
||||||
is_long_click = is_long_click and self.on_long_click:is_exist()
|
is_long_click = is_long_click and self.on_long_click:is_exist()
|
||||||
|
|
||||||
local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME
|
local is_double_click = (time - self.last_released_time) < self.style.DOUBLETAP_TIME
|
||||||
@ -248,6 +248,10 @@ function Button.on_input(self, action_id, action)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not self:is_enabled() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
local is_pick = true
|
local is_pick = true
|
||||||
local is_key_trigger = (action_id == self.key_trigger)
|
local is_key_trigger = (action_id == self.key_trigger)
|
||||||
if not is_key_trigger then
|
if not is_key_trigger then
|
||||||
@ -280,7 +284,7 @@ function Button.on_input(self, action_id, action)
|
|||||||
|
|
||||||
-- While hold button, repeat rate pick from input.repeat_interval
|
-- While hold button, repeat rate pick from input.repeat_interval
|
||||||
if action.repeated then
|
if action.repeated then
|
||||||
if not self.disabled and self.on_repeated_click:is_exist() and self.can_action then
|
if self.on_repeated_click:is_exist() and self.can_action then
|
||||||
on_button_repeated_click(self)
|
on_button_repeated_click(self)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -290,7 +294,7 @@ function Button.on_input(self, action_id, action)
|
|||||||
return on_button_release(self)
|
return on_button_release(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.disabled and self.can_action and self.on_long_click:is_exist() then
|
if self.can_action and self.on_long_click:is_exist() then
|
||||||
local press_time = socket.gettime() - self.last_pressed_time
|
local press_time = socket.gettime() - self.last_pressed_time
|
||||||
|
|
||||||
if self.style.AUTOHOLD_TRIGGER <= press_time then
|
if self.style.AUTOHOLD_TRIGGER <= press_time then
|
||||||
|
@ -63,6 +63,7 @@ local function start_touch(self, touch)
|
|||||||
|
|
||||||
self.x = touch.x
|
self.x = touch.x
|
||||||
self.y = touch.y
|
self.y = touch.y
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
|
|
||||||
self.on_touch_start:trigger(self:get_context())
|
self.on_touch_start:trigger(self:get_context())
|
||||||
end
|
end
|
||||||
@ -155,9 +156,11 @@ end
|
|||||||
-- or create your own style
|
-- or create your own style
|
||||||
-- @table style
|
-- @table style
|
||||||
-- @tfield[opt=10] number DRAG_DEADZONE Distance in pixels to start dragging
|
-- @tfield[opt=10] number DRAG_DEADZONE Distance in pixels to start dragging
|
||||||
|
-- @tfield[opt=false] boolean NO_USE_SCREEN_KOEF If screen aspect ratio affects on drag values
|
||||||
function Drag.on_style_change(self, style)
|
function Drag.on_style_change(self, style)
|
||||||
self.style = {}
|
self.style = {}
|
||||||
self.style.DRAG_DEADZONE = style.DRAG_DEADZONE or 10
|
self.style.DRAG_DEADZONE = style.DRAG_DEADZONE or 10
|
||||||
|
self.style.NO_USE_SCREEN_KOEF = style.NO_USE_SCREEN_KOEF or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -181,6 +184,8 @@ function Drag.init(self, node, on_drag_callback)
|
|||||||
self.can_x = true
|
self.can_x = true
|
||||||
self.can_y = true
|
self.can_y = true
|
||||||
|
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
|
|
||||||
self.click_zone = nil
|
self.click_zone = nil
|
||||||
self.on_touch_start = Event()
|
self.on_touch_start = Event()
|
||||||
self.on_touch_end = Event()
|
self.on_touch_end = Event()
|
||||||
@ -206,6 +211,7 @@ function Drag.on_window_resized(self)
|
|||||||
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
||||||
self._x_koef = x_koef
|
self._x_koef = x_koef
|
||||||
self._y_koef = y_koef
|
self._y_koef = y_koef
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -229,7 +235,6 @@ function Drag.on_input(self, action_id, action)
|
|||||||
if self.click_zone then
|
if self.click_zone then
|
||||||
is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y)
|
is_pick = is_pick and gui.pick_node(self.click_zone, action.x, action.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not is_pick and not self.is_drag then
|
if not is_pick and not self.is_drag then
|
||||||
end_touch(self)
|
end_touch(self)
|
||||||
return false
|
return false
|
||||||
@ -278,11 +283,16 @@ function Drag.on_input(self, action_id, action)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.is_drag then
|
if self.is_drag then
|
||||||
|
local x_koef, y_koef = self._x_koef, self._y_koef
|
||||||
|
if self.style.NO_USE_SCREEN_KOEF then
|
||||||
|
x_koef, y_koef = 1, 1
|
||||||
|
end
|
||||||
|
|
||||||
self.on_drag:trigger(self:get_context(),
|
self.on_drag:trigger(self:get_context(),
|
||||||
self.dx * self._x_koef,
|
self.dx * x_koef / self._scene_scale.x,
|
||||||
self.dy * self._y_koef,
|
self.dy * y_koef / self._scene_scale.y,
|
||||||
(self.x - self.touch_start_pos.x) * self._x_koef,
|
(self.x - self.touch_start_pos.x) * x_koef / self._scene_scale.x,
|
||||||
(self.y - self.touch_start_pos.y) * self._y_koef)
|
(self.y - self.touch_start_pos.y) * y_koef / self._scene_scale.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.is_drag
|
return self.is_drag
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
-- @within BaseComponent
|
-- @within BaseComponent
|
||||||
-- @alias druid.hover
|
-- @alias druid.hover
|
||||||
|
|
||||||
--- On hover callback(self, state)
|
--- On hover callback(self, state, hover_instance)
|
||||||
-- @tfield DruidEvent on_hover @{DruidEvent}
|
-- @tfield DruidEvent on_hover @{DruidEvent}
|
||||||
|
|
||||||
--- On mouse hover callback(self, state)
|
--- On mouse hover callback(self, state, hover_instance)
|
||||||
-- @tfield DruidEvent on_mouse_hover @{DruidEvent}
|
-- @tfield DruidEvent on_mouse_hover @{DruidEvent}
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -81,6 +81,8 @@ function Hover.on_input(self, action_id, action)
|
|||||||
else
|
else
|
||||||
hover_function(self, true)
|
hover_function(self, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -95,21 +97,38 @@ end
|
|||||||
function Hover.set_hover(self, state)
|
function Hover.set_hover(self, state)
|
||||||
if self._is_hovered ~= state then
|
if self._is_hovered ~= state then
|
||||||
self._is_hovered = state
|
self._is_hovered = state
|
||||||
self.on_hover:trigger(self:get_context(), state)
|
self.on_hover:trigger(self:get_context(), state, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return current hover state. True if touch action was on the node at current time
|
||||||
|
-- @tparam Hover self @{Hover}
|
||||||
|
-- @treturn bool The current hovered state
|
||||||
|
function Hover.is_hovered(self)
|
||||||
|
return self._is_hovered
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set mouse hover state
|
--- Set mouse hover state
|
||||||
-- @tparam Hover self @{Hover}
|
-- @tparam Hover self @{Hover}
|
||||||
-- @tparam bool state The mouse hover state
|
-- @tparam bool state The mouse hover state
|
||||||
function Hover.set_mouse_hover(self, state)
|
function Hover.set_mouse_hover(self, state)
|
||||||
if self._is_mouse_hovered ~= state then
|
if self._is_mouse_hovered ~= state then
|
||||||
self._is_mouse_hovered = state
|
self._is_mouse_hovered = state
|
||||||
self.on_mouse_hover:trigger(self:get_context(), state)
|
self.on_mouse_hover:trigger(self:get_context(), state, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Return current hover state. True if nil action_id (usually desktop mouse) was on the node at current time
|
||||||
|
-- @tparam Hover self @{Hover}
|
||||||
|
-- @treturn bool The current hovered state
|
||||||
|
function Hover.is_mouse_hovered(self)
|
||||||
|
return self._is_mouse_hovered
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Strict hover click area. Useful for
|
--- Strict hover click area. Useful for
|
||||||
-- no click events outside stencil node
|
-- no click events outside stencil node
|
||||||
-- @tparam Hover self @{Hover}
|
-- @tparam Hover self @{Hover}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
--- On set text callback(self, text)
|
--- On set text callback(self, text)
|
||||||
-- @tfield DruidEvent on_set_text @{DruidEvent}
|
-- @tfield DruidEvent on_set_text @{DruidEvent}
|
||||||
|
|
||||||
--- On adjust text size callback(self, new_scale)
|
--- On adjust text size callback(self, new_scale, text_metrics)
|
||||||
-- @tfield DruidEvent on_update_text_scale @{DruidEvent}
|
-- @tfield DruidEvent on_update_text_scale @{DruidEvent}
|
||||||
|
|
||||||
--- On change pivot callback(self, pivot)
|
--- On change pivot callback(self, pivot)
|
||||||
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
local Event = require("druid.event")
|
local Event = require("druid.event")
|
||||||
local const = require("druid.const")
|
local const = require("druid.const")
|
||||||
|
local helper = require("druid.helper")
|
||||||
local utf8 = require("druid.system.utf8")
|
local utf8 = require("druid.system.utf8")
|
||||||
local component = require("druid.component")
|
local component = require("druid.component")
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ local function update_text_area_size(self)
|
|||||||
local max_width = self.text_area.x
|
local max_width = self.text_area.x
|
||||||
local max_height = self.text_area.y
|
local max_height = self.text_area.y
|
||||||
|
|
||||||
local metrics = gui.get_text_metrics_from_node(self.node)
|
local metrics = helper.get_text_metrics_from_node(self.node)
|
||||||
|
|
||||||
local scale_modifier = max_width / metrics.width
|
local scale_modifier = max_width / metrics.width
|
||||||
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
scale_modifier = math.min(scale_modifier, self.start_scale.x)
|
||||||
@ -101,7 +102,7 @@ local function update_text_area_size(self)
|
|||||||
|
|
||||||
update_text_size(self)
|
update_text_size(self)
|
||||||
|
|
||||||
self.on_update_text_scale:trigger(self:get_context(), new_scale)
|
self.on_update_text_scale:trigger(self:get_context(), new_scale, metrics)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -135,8 +136,8 @@ end
|
|||||||
-- calculate space width with font
|
-- calculate space width with font
|
||||||
local function get_space_width(self, font)
|
local function get_space_width(self, font)
|
||||||
if not self._space_width[font] then
|
if not self._space_width[font] then
|
||||||
local no_space = gui.get_text_metrics(font, "1", 0, false, 0, 0).width
|
local no_space = resource.get_text_metrics(font, "1").width
|
||||||
local with_space = gui.get_text_metrics(font, " 1", 0, false, 0, 0).width
|
local with_space = resource.get_text_metrics(font, " 1").width
|
||||||
self._space_width[font] = with_space - no_space
|
self._space_width[font] = with_space - no_space
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ M.ACTION_MARKED_TEXT = hash(sys.get_config("druid.input_marked_text", "marked_te
|
|||||||
M.ACTION_ESC = hash(sys.get_config("druid.input_key_esc", "key_esc"))
|
M.ACTION_ESC = hash(sys.get_config("druid.input_key_esc", "key_esc"))
|
||||||
M.ACTION_BACK = hash(sys.get_config("druid.input_key_back", "key_back"))
|
M.ACTION_BACK = hash(sys.get_config("druid.input_key_back", "key_back"))
|
||||||
M.ACTION_ENTER = hash(sys.get_config("druid.input_key_enter", "key_enter"))
|
M.ACTION_ENTER = hash(sys.get_config("druid.input_key_enter", "key_enter"))
|
||||||
M.ACTION_MULTITOUCH = hash(sys.get_config("druid.input_multitouch", "multitouch"))
|
M.ACTION_MULTITOUCH = hash(sys.get_config("druid.input_multitouch", "touch_multi"))
|
||||||
M.ACTION_BACKSPACE = hash(sys.get_config("druid.input_key_backspace", "key_backspace"))
|
M.ACTION_BACKSPACE = hash(sys.get_config("druid.input_key_backspace", "key_backspace"))
|
||||||
|
|
||||||
M.ACTION_SCROLL_UP = hash(sys.get_config("druid.input_scroll_up", "scroll_up"))
|
M.ACTION_SCROLL_UP = hash(sys.get_config("druid.input_scroll_up", "mouse_wheel_up"))
|
||||||
M.ACTION_SCROLL_DOWN = hash(sys.get_config("druid.input_scroll_down", "scroll_down"))
|
M.ACTION_SCROLL_DOWN = hash(sys.get_config("druid.input_scroll_down", "mouse_wheel_down"))
|
||||||
|
|
||||||
|
|
||||||
M.IS_STENCIL_CHECK = not (sys.get_config("druid.no_stencil_check") == "1")
|
M.IS_STENCIL_CHECK = not (sys.get_config("druid.no_stencil_check") == "1")
|
||||||
|
@ -87,6 +87,7 @@ end
|
|||||||
-- @tfield[opt=false] bool IS_LONGTAP_ERASE Is long tap will erase current input data
|
-- @tfield[opt=false] bool IS_LONGTAP_ERASE Is long tap will erase current input data
|
||||||
-- @tfield[opt=*] string MASK_DEFAULT_CHAR Default character mask for password input
|
-- @tfield[opt=*] string MASK_DEFAULT_CHAR Default character mask for password input
|
||||||
-- @tfield[opt=false] bool IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input
|
-- @tfield[opt=false] bool IS_UNSELECT_ON_RESELECT If true, call unselect on select selected input
|
||||||
|
-- @tfield[opt=false] bool NO_CONSUME_INPUT_WHILE_SELECTED If true, will not consume input while input is selected. It's allow to interact with other components while input is selected (text input still captured)
|
||||||
-- @tfield function on_select (self, button_node) Callback on input field selecting
|
-- @tfield function on_select (self, button_node) Callback on input field selecting
|
||||||
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting
|
-- @tfield function on_unselect (self, button_node) Callback on input field unselecting
|
||||||
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
|
-- @tfield function on_input_wrong (self, button_node) Callback on wrong user input
|
||||||
@ -97,6 +98,7 @@ function Input.on_style_change(self, style)
|
|||||||
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
|
self.style.IS_LONGTAP_ERASE = style.IS_LONGTAP_ERASE or false
|
||||||
self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*"
|
self.style.MASK_DEFAULT_CHAR = style.MASK_DEFAULT_CHAR or "*"
|
||||||
self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false
|
self.style.IS_UNSELECT_ON_RESELECT = style.IS_UNSELECT_ON_RESELECT or false
|
||||||
|
self.style.NO_CONSUME_INPUT_WHILE_SELECTED = style.NO_CONSUME_INPUT_WHILE_SELECTED or false
|
||||||
|
|
||||||
self.style.on_select = style.on_select or function(_, button_node) end
|
self.style.on_select = style.on_select or function(_, button_node) end
|
||||||
self.style.on_unselect = style.on_unselect or function(_, button_node) end
|
self.style.on_unselect = style.on_unselect or function(_, button_node) end
|
||||||
@ -214,7 +216,8 @@ function Input.on_input(self, action_id, action)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.is_selected
|
local is_consume_input = not self.style.NO_CONSUME_INPUT_WHILE_SELECTED and self.is_selected
|
||||||
|
return is_consume_input
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,10 +36,13 @@ function Layout.init(self, node, mode, on_size_changed_callback)
|
|||||||
|
|
||||||
self._min_size = nil
|
self._min_size = nil
|
||||||
self._max_size = nil
|
self._max_size = nil
|
||||||
|
self._current_size = vmath.vector3(0)
|
||||||
self._inited = false
|
self._inited = false
|
||||||
|
self._max_gui_upscale = nil
|
||||||
self._fit_node = nil
|
self._fit_node = nil
|
||||||
|
|
||||||
|
self._anchors = {}
|
||||||
|
|
||||||
self.mode = mode or const.LAYOUT_MODE.FIT
|
self.mode = mode or const.LAYOUT_MODE.FIT
|
||||||
|
|
||||||
self.on_size_changed = Event(on_size_changed_callback)
|
self.on_size_changed = Event(on_size_changed_callback)
|
||||||
@ -66,6 +69,13 @@ function Layout.on_window_resized(self)
|
|||||||
|
|
||||||
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
||||||
|
|
||||||
|
local revert_scale = 1
|
||||||
|
if self._max_gui_upscale then
|
||||||
|
revert_scale = self._max_gui_upscale / helper.get_gui_scale()
|
||||||
|
revert_scale = math.min(revert_scale, 1)
|
||||||
|
end
|
||||||
|
gui.set_scale(self.node, vmath.vector3(revert_scale))
|
||||||
|
|
||||||
if self._fit_node then
|
if self._fit_node then
|
||||||
self.fit_size = gui.get_size(self._fit_node)
|
self.fit_size = gui.get_size(self._fit_node)
|
||||||
self.fit_size.x = self.fit_size.x / x_koef
|
self.fit_size.x = self.fit_size.x / x_koef
|
||||||
@ -77,11 +87,17 @@ function Layout.on_window_resized(self)
|
|||||||
|
|
||||||
local new_size = vmath.vector3(self.origin_size)
|
local new_size = vmath.vector3(self.origin_size)
|
||||||
|
|
||||||
if self.mode == const.LAYOUT_MODE.STRETCH_X or self.mode == const.LAYOUT_MODE.STRETCH then
|
if self.mode == const.LAYOUT_MODE.STRETCH then
|
||||||
new_size.x = new_size.x * x_koef
|
new_size.x = new_size.x * x_koef / revert_scale
|
||||||
|
new_size.y = new_size.y * y_koef / revert_scale
|
||||||
end
|
end
|
||||||
if self.mode == const.LAYOUT_MODE.STRETCH_Y or self.mode == const.LAYOUT_MODE.STRETCH then
|
|
||||||
new_size.y = new_size.y * y_koef
|
if self.mode == const.LAYOUT_MODE.STRETCH_X then
|
||||||
|
new_size.x = new_size.x * x_koef / revert_scale
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.mode == const.LAYOUT_MODE.STRETCH_Y then
|
||||||
|
new_size.y = new_size.y * y_koef / revert_scale
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fit to the stretched container (node size or other defined)
|
-- Fit to the stretched container (node size or other defined)
|
||||||
@ -100,6 +116,7 @@ function Layout.on_window_resized(self)
|
|||||||
new_size.x = math.min(new_size.x, self._max_size.x)
|
new_size.x = math.min(new_size.x, self._max_size.x)
|
||||||
new_size.y = math.min(new_size.y, self._max_size.y)
|
new_size.y = math.min(new_size.y, self._max_size.y)
|
||||||
end
|
end
|
||||||
|
self._current_size = new_size
|
||||||
gui.set_size(self.node, new_size)
|
gui.set_size(self.node, new_size)
|
||||||
|
|
||||||
self.position.x = self.origin_position.x + self.origin_position.x * (x_koef - 1)
|
self.position.x = self.origin_position.x + self.origin_position.x * (x_koef - 1)
|
||||||
@ -152,6 +169,16 @@ function Layout.set_origin_size(self, new_origin_size)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set max gui upscale for FIT adjust mode (or side). It happens on bigger render gui screen
|
||||||
|
-- @tparam Layout self @{Layout}
|
||||||
|
-- @tparam number max_gui_upscale
|
||||||
|
-- @treturn Layout @{Layout}
|
||||||
|
function Layout.set_max_gui_upscale(self, max_gui_upscale)
|
||||||
|
self._max_gui_upscale = max_gui_upscale
|
||||||
|
self:on_window_resized()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set size for layout node to fit inside it
|
--- Set size for layout node to fit inside it
|
||||||
-- @tparam Layout self @{Layout}
|
-- @tparam Layout self @{Layout}
|
||||||
-- @tparam vector3 target_size
|
-- @tparam vector3 target_size
|
||||||
|
@ -121,12 +121,8 @@ function Progress.init(self, node, key, init_value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.on_change = Event()
|
self.on_change = Event()
|
||||||
end
|
|
||||||
|
|
||||||
|
self:set_to(self.last_value)
|
||||||
-- @tparam Progress self @{Progress}
|
|
||||||
function Progress.on_late_init(self)
|
|
||||||
self:set_to(self._init_value)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ function Slider.init(self, node, end_pos, callback)
|
|||||||
|
|
||||||
self.start_pos = gui.get_position(self.node)
|
self.start_pos = gui.get_position(self.node)
|
||||||
self.pos = gui.get_position(self.node)
|
self.pos = gui.get_position(self.node)
|
||||||
self.target_pos = self.pos
|
self.target_pos = vmath.vector3(self.pos)
|
||||||
self.end_pos = end_pos
|
self.end_pos = end_pos
|
||||||
|
|
||||||
self.dist = self.end_pos - self.start_pos
|
self.dist = self.end_pos - self.start_pos
|
||||||
@ -72,6 +72,7 @@ function Slider.init(self, node, end_pos, callback)
|
|||||||
self.value = 0
|
self.value = 0
|
||||||
|
|
||||||
self.on_change_value = Event(callback)
|
self.on_change_value = Event(callback)
|
||||||
|
self:on_window_resized()
|
||||||
|
|
||||||
assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal")
|
assert(self.dist.x == 0 or self.dist.y == 0, "Slider for now can be only vertical or horizontal")
|
||||||
end
|
end
|
||||||
@ -82,6 +83,14 @@ function Slider.on_layout_change(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function Slider.on_window_resized(self)
|
||||||
|
local x_koef, y_koef = helper.get_screen_aspect_koef()
|
||||||
|
self._x_koef = x_koef
|
||||||
|
self._y_koef = y_koef
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function Slider.on_input(self, action_id, action)
|
function Slider.on_input(self, action_id, action)
|
||||||
if action_id ~= const.ACTION_TOUCH then
|
if action_id ~= const.ACTION_TOUCH then
|
||||||
return false
|
return false
|
||||||
@ -90,15 +99,17 @@ function Slider.on_input(self, action_id, action)
|
|||||||
if gui.pick_node(self.node, action.x, action.y) then
|
if gui.pick_node(self.node, action.x, action.y) then
|
||||||
if action.pressed then
|
if action.pressed then
|
||||||
self.pos = gui.get_position(self.node)
|
self.pos = gui.get_position(self.node)
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
self.is_drag = true
|
self.is_drag = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.is_drag and self._input_node and gui.pick_node(self._input_node, action.x, action.y) then
|
if not self.is_drag and self._input_node and gui.pick_node(self._input_node, action.x, action.y) then
|
||||||
if action.pressed and gui.screen_to_local then
|
if action.pressed and gui.screen_to_local then
|
||||||
|
self._scene_scale = helper.get_scene_scale(self.node)
|
||||||
self.pos = gui.screen_to_local(self.node, vmath.vector3(action.screen_x, action.screen_y, 0))
|
self.pos = gui.screen_to_local(self.node, vmath.vector3(action.screen_x, action.screen_y, 0))
|
||||||
self.pos.x = helper.clamp(self.pos.x, self.start_pos.x, self.end_pos.x)
|
self.pos.x = helper.clamp(self.pos.x / self._scene_scale.x, self.start_pos.x, self.end_pos.x)
|
||||||
self.pos.y = helper.clamp(self.pos.y, self.start_pos.y, self.end_pos.y)
|
self.pos.y = helper.clamp(self.pos.y / self._scene_scale.y, self.start_pos.y, self.end_pos.y)
|
||||||
|
|
||||||
gui.set_position(self.node, self.pos)
|
gui.set_position(self.node, self.pos)
|
||||||
self.is_drag = true
|
self.is_drag = true
|
||||||
@ -107,8 +118,8 @@ function Slider.on_input(self, action_id, action)
|
|||||||
|
|
||||||
if self.is_drag and not action.pressed then
|
if self.is_drag and not action.pressed then
|
||||||
-- move
|
-- move
|
||||||
self.pos.x = self.pos.x + action.dx
|
self.pos.x = self.pos.x + action.dx * self._x_koef / self._scene_scale.x
|
||||||
self.pos.y = self.pos.y + action.dy
|
self.pos.y = self.pos.y + action.dy * self._y_koef / self._scene_scale.y
|
||||||
|
|
||||||
local prev_x = self.target_pos.x
|
local prev_x = self.target_pos.x
|
||||||
local prev_y = self.target_pos.y
|
local prev_y = self.target_pos.y
|
||||||
|
@ -12,7 +12,7 @@ local M = {}
|
|||||||
--- Text node or icon node can be nil
|
--- Text node or icon node can be nil
|
||||||
local function get_text_width(text_node)
|
local function get_text_width(text_node)
|
||||||
if text_node then
|
if text_node then
|
||||||
local text_metrics = gui.get_text_metrics_from_node(text_node)
|
local text_metrics = M.get_text_metrics_from_node(text_node)
|
||||||
local text_scale = gui.get_scale(text_node).x
|
local text_scale = gui.get_scale(text_node).x
|
||||||
return text_metrics.width * text_scale
|
return text_metrics.width * text_scale
|
||||||
end
|
end
|
||||||
@ -107,6 +107,13 @@ function M.get_screen_aspect_koef()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.get_gui_scale()
|
||||||
|
local window_x, window_y = window.get_size()
|
||||||
|
return math.min(window_x / gui.get_width(),
|
||||||
|
window_y / gui.get_height())
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function M.step(current, target, step)
|
function M.step(current, target, step)
|
||||||
if current < target then
|
if current < target then
|
||||||
return math.min(current + step, target)
|
return math.min(current + step, target)
|
||||||
@ -166,6 +173,21 @@ function M.contains(t, value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get text metric from gui node. Replacement of previous gui.get_text_metrics_from_node function
|
||||||
|
-- @tparam Node text_node
|
||||||
|
-- @treturn table {width, height, max_ascent, max_descent}
|
||||||
|
function M.get_text_metrics_from_node(text_node)
|
||||||
|
local font_name = gui.get_font(text_node)
|
||||||
|
local font = gui.get_font_resource(font_name)
|
||||||
|
return resource.get_text_metrics(font, gui.get_text(text_node), {
|
||||||
|
width = gui.get_size(text_node).x,
|
||||||
|
leading = gui.get_leading(text_node),
|
||||||
|
tracking = gui.get_tracking(text_node),
|
||||||
|
line_break = gui.get_line_break(text_node),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Check if node is enabled in gui hierarchy.
|
--- Check if node is enabled in gui hierarchy.
|
||||||
-- Return false, if node or any his parent is disabled
|
-- Return false, if node or any his parent is disabled
|
||||||
-- @function helper.is_enabled
|
-- @function helper.is_enabled
|
||||||
@ -183,6 +205,23 @@ function M.is_enabled(node)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get cumulative parent's node scale
|
||||||
|
-- @function helper.get_scene_scale
|
||||||
|
-- @tparam node node Gui node
|
||||||
|
-- @tparam bool include_passed_node_scale True if add current node scale to result
|
||||||
|
-- @treturn vector3 The scene node scale
|
||||||
|
function M.get_scene_scale(node, include_passed_node_scale)
|
||||||
|
local scale = include_passed_node_scale and gui.get_scale(node) or vmath.vector3(1)
|
||||||
|
local parent = gui.get_parent(node)
|
||||||
|
while parent do
|
||||||
|
scale = vmath.mul_per_elem(scale, gui.get_scale(parent))
|
||||||
|
parent = gui.get_parent(parent)
|
||||||
|
end
|
||||||
|
|
||||||
|
return scale
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Return closest non inverted clipping parent node for node
|
--- Return closest non inverted clipping parent node for node
|
||||||
-- @function helper.get_closest_stencil_node
|
-- @function helper.get_closest_stencil_node
|
||||||
-- @tparam node node Gui node
|
-- @tparam node node Gui node
|
||||||
@ -280,6 +319,26 @@ function M.get_border(node, offset)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get text metric from gui node. Replacement of previous gui.get_text_metrics_from_node function
|
||||||
|
-- @tparam Node text_node
|
||||||
|
-- @treturn table {width, height, max_ascent, max_descent}
|
||||||
|
function M.get_text_metrics_from_node(text_node)
|
||||||
|
local font_resource = gui.get_font_resource(gui.get_font(text_node))
|
||||||
|
local options = {
|
||||||
|
tracking = gui.get_tracking(text_node),
|
||||||
|
line_break = gui.get_line_break(text_node),
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Gather other options only if it used in node
|
||||||
|
if options.line_break then
|
||||||
|
options.width = gui.get_size(text_node).x
|
||||||
|
options.leading = gui.get_leading(text_node)
|
||||||
|
end
|
||||||
|
|
||||||
|
return resource.get_text_metrics(font_resource, gui.get_text(text_node), options)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Show deprecated message. Once time per message
|
--- Show deprecated message. Once time per message
|
||||||
-- @function helper.deprecated
|
-- @function helper.deprecated
|
||||||
-- @tparam string message The deprecated message
|
-- @tparam string message The deprecated message
|
||||||
|
@ -56,6 +56,7 @@ M["button"] = {
|
|||||||
|
|
||||||
M["drag"] = {
|
M["drag"] = {
|
||||||
DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone
|
DRAG_DEADZONE = 10, -- Size in pixels of drag deadzone
|
||||||
|
NO_USE_SCREEN_KOEF = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ M["input"] = {
|
|||||||
BUTTON_SELECT_INCREASE = 1.06,
|
BUTTON_SELECT_INCREASE = 1.06,
|
||||||
MASK_DEFAULT_CHAR = "*",
|
MASK_DEFAULT_CHAR = "*",
|
||||||
IS_UNSELECT_ON_RESELECT = false,
|
IS_UNSELECT_ON_RESELECT = false,
|
||||||
|
NO_CONSUME_INPUT_WHILE_SELECTED = false,
|
||||||
|
|
||||||
on_select = function(self, button_node)
|
on_select = function(self, button_node)
|
||||||
local target_scale = self.button.start_scale
|
local target_scale = self.button.start_scale
|
||||||
|
@ -49,16 +49,17 @@ local static_grid = require("druid.base.static_grid")
|
|||||||
local swipe = require("druid.base.swipe")
|
local swipe = require("druid.base.swipe")
|
||||||
local text = require("druid.base.text")
|
local text = require("druid.base.text")
|
||||||
|
|
||||||
local checkbox = require("druid.extended.checkbox")
|
-- To use this components, you should register them first
|
||||||
local checkbox_group = require("druid.extended.checkbox_group")
|
-- local checkbox = require("druid.extended.checkbox")
|
||||||
local dynamic_grid = require("druid.extended.dynamic_grid")
|
-- local checkbox_group = require("druid.extended.checkbox_group")
|
||||||
local input = require("druid.extended.input")
|
-- local dynamic_grid = require("druid.extended.dynamic_grid")
|
||||||
local lang_text = require("druid.extended.lang_text")
|
-- local input = require("druid.extended.input")
|
||||||
local progress = require("druid.extended.progress")
|
-- local lang_text = require("druid.extended.lang_text")
|
||||||
local radio_group = require("druid.extended.radio_group")
|
-- local progress = require("druid.extended.progress")
|
||||||
local slider = require("druid.extended.slider")
|
-- local radio_group = require("druid.extended.radio_group")
|
||||||
local timer_component = require("druid.extended.timer")
|
-- local slider = require("druid.extended.slider")
|
||||||
local data_list = require("druid.extended.data_list")
|
-- local timer_component = require("druid.extended.timer")
|
||||||
|
-- local data_list = require("druid.extended.data_list")
|
||||||
|
|
||||||
|
|
||||||
local DruidInstance = class("druid.druid_instance")
|
local DruidInstance = class("druid.druid_instance")
|
||||||
@ -193,6 +194,18 @@ local function process_input(self, action_id, action, components)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function schedule_late_init(self)
|
||||||
|
if self._late_init_timer_id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self._late_init_timer_id = timer.delay(0, false, function()
|
||||||
|
self._late_init_timer_id = nil
|
||||||
|
self:late_init()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Druid class constructor
|
--- Druid class constructor
|
||||||
-- @tparam DruidInstance self
|
-- @tparam DruidInstance self
|
||||||
-- @tparam table context Druid context. Usually it is self of script
|
-- @tparam table context Druid context. Usually it is self of script
|
||||||
@ -215,10 +228,6 @@ function DruidInstance.initialize(self, context, style)
|
|||||||
for i = 1, #base_component.ALL_INTERESTS do
|
for i = 1, #base_component.ALL_INTERESTS do
|
||||||
self.components_interest[base_component.ALL_INTERESTS[i]] = {}
|
self.components_interest[base_component.ALL_INTERESTS[i]] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
timer.delay(0, false, function()
|
|
||||||
self:late_init()
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -244,6 +253,9 @@ function DruidInstance.new(self, component, ...)
|
|||||||
if instance.init then
|
if instance.init then
|
||||||
instance:init(...)
|
instance:init(...)
|
||||||
end
|
end
|
||||||
|
if instance.on_late_init or (not self.input_inited and instance.on_input) then
|
||||||
|
schedule_late_init(self)
|
||||||
|
end
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
end
|
end
|
||||||
@ -315,7 +327,7 @@ function DruidInstance.remove(self, component)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Druid late update function call after init and before udpate step
|
--- Druid late update function call after init and before update step
|
||||||
-- @tparam DruidInstance self
|
-- @tparam DruidInstance self
|
||||||
function DruidInstance.late_init(self)
|
function DruidInstance.late_init(self)
|
||||||
local late_init_components = self.components_interest[base_component.ON_LATE_INIT]
|
local late_init_components = self.components_interest[base_component.ON_LATE_INIT]
|
||||||
@ -569,7 +581,7 @@ end
|
|||||||
-- @tparam node node Gui text node
|
-- @tparam node node Gui text node
|
||||||
-- @tparam[opt] string value Initial text. Default value is node text from GUI scene.
|
-- @tparam[opt] string value Initial text. Default value is node text from GUI scene.
|
||||||
-- @tparam[opt] bool no_adjust If true, text will be not auto-adjust size
|
-- @tparam[opt] bool no_adjust If true, text will be not auto-adjust size
|
||||||
-- @treturn Tet text component
|
-- @treturn Text text component
|
||||||
function DruidInstance.new_text(self, node, value, no_adjust)
|
function DruidInstance.new_text(self, node, value, no_adjust)
|
||||||
return DruidInstance.new(self, text, node, value, no_adjust)
|
return DruidInstance.new(self, text, node, value, no_adjust)
|
||||||
end
|
end
|
||||||
@ -634,8 +646,7 @@ end
|
|||||||
-- @tparam node parent The gui node parent, where items will be placed
|
-- @tparam node parent The gui node parent, where items will be placed
|
||||||
-- @treturn DynamicGrid grid component
|
-- @treturn DynamicGrid grid component
|
||||||
function DruidInstance.new_dynamic_grid(self, parent)
|
function DruidInstance.new_dynamic_grid(self, parent)
|
||||||
-- return helper.extended_component("dynamic_grid")
|
return helper.extended_component("dynamic_grid")
|
||||||
return DruidInstance.new(self, dynamic_grid, parent)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -646,8 +657,7 @@ end
|
|||||||
-- @tparam bool no_adjust If true, will not correct text size
|
-- @tparam bool no_adjust If true, will not correct text size
|
||||||
-- @treturn LangText lang_text component
|
-- @treturn LangText lang_text component
|
||||||
function DruidInstance.new_lang_text(self, node, locale_id, no_adjust)
|
function DruidInstance.new_lang_text(self, node, locale_id, no_adjust)
|
||||||
-- return helper.extended_component("lang_text")
|
return helper.extended_component("lang_text")
|
||||||
return DruidInstance.new(self, lang_text, node, locale_id, no_adjust)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -658,8 +668,7 @@ end
|
|||||||
-- @tparam[opt] function callback On slider change callback
|
-- @tparam[opt] function callback On slider change callback
|
||||||
-- @treturn Slider slider component
|
-- @treturn Slider slider component
|
||||||
function DruidInstance.new_slider(self, node, end_pos, callback)
|
function DruidInstance.new_slider(self, node, end_pos, callback)
|
||||||
-- return helper.extended_component("slider")
|
return helper.extended_component("slider")
|
||||||
return DruidInstance.new(self, slider, node, end_pos, callback)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -671,8 +680,7 @@ end
|
|||||||
-- @tparam[opt=false] boolean initial_state The initial state of checkbox, default - false
|
-- @tparam[opt=false] boolean initial_state The initial state of checkbox, default - false
|
||||||
-- @treturn Checkbox checkbox component
|
-- @treturn Checkbox checkbox component
|
||||||
function DruidInstance.new_checkbox(self, node, callback, click_node, initial_state)
|
function DruidInstance.new_checkbox(self, node, callback, click_node, initial_state)
|
||||||
-- return helper.extended_component("checkbox")
|
return helper.extended_component("checkbox")
|
||||||
return DruidInstance.new(self, checkbox, node, callback, click_node, initial_state)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -683,8 +691,7 @@ end
|
|||||||
-- @tparam[opt] number keyboard_type Gui keyboard type for input field
|
-- @tparam[opt] number keyboard_type Gui keyboard type for input field
|
||||||
-- @treturn Input input component
|
-- @treturn Input input component
|
||||||
function DruidInstance.new_input(self, click_node, text_node, keyboard_type)
|
function DruidInstance.new_input(self, click_node, text_node, keyboard_type)
|
||||||
-- return helper.extended_component("input")
|
return helper.extended_component("input")
|
||||||
return DruidInstance.new(self, input, click_node, text_node, keyboard_type)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -695,8 +702,7 @@ end
|
|||||||
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes
|
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes
|
||||||
-- @treturn CheckboxGroup checkbox_group component
|
-- @treturn CheckboxGroup checkbox_group component
|
||||||
function DruidInstance.new_checkbox_group(self, nodes, callback, click_nodes)
|
function DruidInstance.new_checkbox_group(self, nodes, callback, click_nodes)
|
||||||
-- return helper.extended_component("checkbox_group")
|
return helper.extended_component("checkbox_group")
|
||||||
return DruidInstance.new(self, checkbox_group, nodes, callback, click_nodes)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -707,8 +713,7 @@ end
|
|||||||
-- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
|
-- @tparam function create_function The create function callback(self, data, index, data_list). Function should return (node, [component])
|
||||||
-- @treturn DataList data_list component
|
-- @treturn DataList data_list component
|
||||||
function DruidInstance.new_data_list(self, druid_scroll, druid_grid, create_function)
|
function DruidInstance.new_data_list(self, druid_scroll, druid_grid, create_function)
|
||||||
-- return helper.extended_component("data_list")
|
return helper.extended_component("data_list")
|
||||||
return DruidInstance.new(self, data_list, druid_scroll, druid_grid, create_function)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -719,8 +724,7 @@ end
|
|||||||
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes
|
-- @tparam[opt=node] node[] click_nodes Array of trigger nodes, by default equals to nodes
|
||||||
-- @treturn RadioGroup radio_group component
|
-- @treturn RadioGroup radio_group component
|
||||||
function DruidInstance.new_radio_group(self, nodes, callback, click_nodes)
|
function DruidInstance.new_radio_group(self, nodes, callback, click_nodes)
|
||||||
-- return helper.extended_component("radio_group")
|
return helper.extended_component("radio_group")
|
||||||
return DruidInstance.new(self, radio_group, nodes, callback, click_nodes)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -732,8 +736,7 @@ end
|
|||||||
-- @tparam[opt] function callback Function on timer end
|
-- @tparam[opt] function callback Function on timer end
|
||||||
-- @treturn Timer timer component
|
-- @treturn Timer timer component
|
||||||
function DruidInstance.new_timer(self, node, seconds_from, seconds_to, callback)
|
function DruidInstance.new_timer(self, node, seconds_from, seconds_to, callback)
|
||||||
-- return helper.extended_component("timer")
|
return helper.extended_component("timer")
|
||||||
return DruidInstance.new(self, timer_component, node, seconds_from, seconds_to, callback)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -744,8 +747,7 @@ end
|
|||||||
-- @tparam[opt=1] number init_value Initial value of progress bar
|
-- @tparam[opt=1] number init_value Initial value of progress bar
|
||||||
-- @treturn Progress progress component
|
-- @treturn Progress progress component
|
||||||
function DruidInstance.new_progress(self, node, key, init_value)
|
function DruidInstance.new_progress(self, node, key, init_value)
|
||||||
-- return helper.extended_component("progress")
|
return helper.extended_component("progress")
|
||||||
return DruidInstance.new(self, progress, node, key, init_value)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -2067,6 +2067,201 @@ embedded_instances {
|
|||||||
z: 1.0
|
z: 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
embedded_instances {
|
||||||
|
id: "system_late_init_check"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen_factory\"\n"
|
||||||
|
" component: \"/monarch/screen_factory.script\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"screen_id\"\n"
|
||||||
|
" value: \"system_late_init_check\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"popup\"\n"
|
||||||
|
" value: \"true\"\n"
|
||||||
|
" type: PROPERTY_TYPE_BOOLEAN\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionfactory\"\n"
|
||||||
|
" type: \"collectionfactory\"\n"
|
||||||
|
" data: \"prototype: \\\"/example/examples/system/late_init_check/late_init_check.collection\\\"\\n"
|
||||||
|
"load_dynamically: false\\n"
|
||||||
|
"\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
embedded_instances {
|
||||||
|
id: "general_hover"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen_factory\"\n"
|
||||||
|
" component: \"/monarch/screen_factory.script\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"screen_id\"\n"
|
||||||
|
" value: \"general_hover\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"popup\"\n"
|
||||||
|
" value: \"true\"\n"
|
||||||
|
" type: PROPERTY_TYPE_BOOLEAN\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionfactory\"\n"
|
||||||
|
" type: \"collectionfactory\"\n"
|
||||||
|
" data: \"prototype: \\\"/example/examples/general/hover/hover.collection\\\"\\n"
|
||||||
|
"load_dynamically: false\\n"
|
||||||
|
"\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
embedded_instances {
|
||||||
|
id: "texts_lang_text"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"screen_factory\"\n"
|
||||||
|
" component: \"/monarch/screen_factory.script\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"screen_id\"\n"
|
||||||
|
" value: \"texts_lang_text\"\n"
|
||||||
|
" type: PROPERTY_TYPE_HASH\n"
|
||||||
|
" }\n"
|
||||||
|
" properties {\n"
|
||||||
|
" id: \"popup\"\n"
|
||||||
|
" value: \"true\"\n"
|
||||||
|
" type: PROPERTY_TYPE_BOOLEAN\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"embedded_components {\n"
|
||||||
|
" id: \"collectionfactory\"\n"
|
||||||
|
" type: \"collectionfactory\"\n"
|
||||||
|
" data: \"prototype: \\\"/example/examples/texts/lang_text/lang_text.collection\\\"\\n"
|
||||||
|
"load_dynamically: false\\n"
|
||||||
|
"\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
embedded_instances {
|
embedded_instances {
|
||||||
id: "custom_rich_text"
|
id: "custom_rich_text"
|
||||||
data: "components {\n"
|
data: "components {\n"
|
||||||
|
@ -3,6 +3,17 @@ local druid = require("druid.druid")
|
|||||||
local monarch = require("monarch.monarch")
|
local monarch = require("monarch.monarch")
|
||||||
local default_style = require("druid.styles.default.style")
|
local default_style = require("druid.styles.default.style")
|
||||||
|
|
||||||
|
local checkbox = require("druid.extended.checkbox")
|
||||||
|
local checkbox_group = require("druid.extended.checkbox_group")
|
||||||
|
local dynamic_grid = require("druid.extended.dynamic_grid")
|
||||||
|
local input = require("druid.extended.input")
|
||||||
|
local lang_text = require("druid.extended.lang_text")
|
||||||
|
local progress = require("druid.extended.progress")
|
||||||
|
local radio_group = require("druid.extended.radio_group")
|
||||||
|
local slider = require("druid.extended.slider")
|
||||||
|
local timer_component = require("druid.extended.timer")
|
||||||
|
local data_list = require("druid.extended.data_list")
|
||||||
|
|
||||||
local cache_path = sys.get_save_file("druid", "cache")
|
local cache_path = sys.get_save_file("druid", "cache")
|
||||||
|
|
||||||
|
|
||||||
@ -121,6 +132,7 @@ local function init_lobby(self)
|
|||||||
self.lobby_scroll = self.druid:new_scroll("lobby_view", "lobby_content")
|
self.lobby_scroll = self.druid:new_scroll("lobby_view", "lobby_content")
|
||||||
self.lobby_grid = self.druid:new_dynamic_grid("lobby_content")
|
self.lobby_grid = self.druid:new_dynamic_grid("lobby_content")
|
||||||
self.lobby_scroll:bind_grid(self.lobby_grid)
|
self.lobby_scroll:bind_grid(self.lobby_grid)
|
||||||
|
self.lobby_scroll.style.WHEEL_SCROLL_SPEED = 20
|
||||||
|
|
||||||
self.lobby_grid:add(get_title(self, "General examples"))
|
self.lobby_grid:add(get_title(self, "General examples"))
|
||||||
self.lobby_grid:add(get_button(self, "Overview", "general_overview", "/general/overview/overview.gui_script"))
|
self.lobby_grid:add(get_button(self, "Overview", "general_overview", "/general/overview/overview.gui_script"))
|
||||||
@ -133,6 +145,7 @@ local function init_lobby(self)
|
|||||||
self.lobby_grid:add(get_button(self, "Checkboxes", "general_checkboxes", "/general/checkboxes/checkboxes.gui_script"))
|
self.lobby_grid:add(get_button(self, "Checkboxes", "general_checkboxes", "/general/checkboxes/checkboxes.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Input text", "general_input", "/general/input/input.gui_script"))
|
self.lobby_grid:add(get_button(self, "Input text", "general_input", "/general/input/input.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Layout", "general_layout", "/general/layout/layout.gui_script"))
|
self.lobby_grid:add(get_button(self, "Layout", "general_layout", "/general/layout/layout.gui_script"))
|
||||||
|
self.lobby_grid:add(get_button(self, "Hover", "general_hover", "/general/hover/hover.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Swipe", "general_swipe", "/general/swipe/swipe.gui_script"))
|
self.lobby_grid:add(get_button(self, "Swipe", "general_swipe", "/general/swipe/swipe.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Drag", "general_drag", "/general/drag/drag.gui_script"))
|
self.lobby_grid:add(get_button(self, "Drag", "general_drag", "/general/drag/drag.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Hotkey", "general_hotkey", "/general/hotkey/hotkey.gui_script"))
|
self.lobby_grid:add(get_button(self, "Hotkey", "general_hotkey", "/general/hotkey/hotkey.gui_script"))
|
||||||
@ -140,7 +153,7 @@ local function init_lobby(self)
|
|||||||
self.lobby_grid:add(get_title(self, "Texts"))
|
self.lobby_grid:add(get_title(self, "Texts"))
|
||||||
self.lobby_grid:add(get_button(self, "Texts", "texts_general", "/texts/texts_general/texts_general.gui_script"))
|
self.lobby_grid:add(get_button(self, "Texts", "texts_general", "/texts/texts_general/texts_general.gui_script"))
|
||||||
self.lobby_grid:add(get_button(self, "Adjust types", "texts_adjust", "/texts/texts_adjust/texts_adjust.gui_script"))
|
self.lobby_grid:add(get_button(self, "Adjust types", "texts_adjust", "/texts/texts_adjust/texts_adjust.gui_script"))
|
||||||
self.lobby_grid:add(get_button_disabled(self, "Lang Text", "texts_lang_text"))
|
self.lobby_grid:add(get_button(self, "Lang Text", "texts_lang_text", "/texts/texts_adjust/texts_lang_text.gui_script"))
|
||||||
|
|
||||||
self.lobby_grid:add(get_title(self, "Scrolls"))
|
self.lobby_grid:add(get_title(self, "Scrolls"))
|
||||||
self.lobby_grid:add(get_button_disabled(self, "Nested scrolls", "scroll_scene"))
|
self.lobby_grid:add(get_button_disabled(self, "Nested scrolls", "scroll_scene"))
|
||||||
@ -178,6 +191,7 @@ local function init_lobby(self)
|
|||||||
self.lobby_grid:add(get_button(self, "Message input", "system_message_input", "/system/message_input/message_input.gui_script"))
|
self.lobby_grid:add(get_button(self, "Message input", "system_message_input", "/system/message_input/message_input.gui_script"))
|
||||||
self.lobby_grid:add(get_button_disabled(self, "Input priority"))
|
self.lobby_grid:add(get_button_disabled(self, "Input priority"))
|
||||||
self.lobby_grid:add(get_button(self, "Inner templates", "system_inner_templates", "/system/inner_templates/inner_templates.gui_script"))
|
self.lobby_grid:add(get_button(self, "Inner templates", "system_inner_templates", "/system/inner_templates/inner_templates.gui_script"))
|
||||||
|
self.lobby_grid:add(get_button(self, "Late init check", "system_late_init_check", "/system/late_init_check/late_init_check.gui_script"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -220,12 +234,28 @@ local function check_loading(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function register_druid_extended_components(self)
|
||||||
|
druid.register("checkbox", checkbox)
|
||||||
|
druid.register("checkbox_group", checkbox_group)
|
||||||
|
druid.register("dynamic_grid", dynamic_grid)
|
||||||
|
druid.register("input", input)
|
||||||
|
druid.register("lang_text", lang_text)
|
||||||
|
druid.register("progress", progress)
|
||||||
|
druid.register("radio_group", radio_group)
|
||||||
|
druid.register("slider", slider)
|
||||||
|
druid.register("timer", timer_component)
|
||||||
|
druid.register("data_list", data_list)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function init(self)
|
function init(self)
|
||||||
-- Main lobby have more render priority (top panel)
|
-- Main lobby have more render priority (top panel)
|
||||||
gui.set_render_order(10)
|
gui.set_render_order(10)
|
||||||
|
|
||||||
window.set_listener(on_window_callback)
|
window.set_listener(on_window_callback)
|
||||||
druid.set_default_style(default_style)
|
druid.set_default_style(default_style)
|
||||||
|
register_druid_extended_components(self)
|
||||||
self.druid = druid.new(self)
|
self.druid = druid.new(self)
|
||||||
self.cache = sys.load(cache_path) or {}
|
self.cache = sys.load(cache_path) or {}
|
||||||
|
|
||||||
|
39
example/examples/general/hover/hover.collection
Normal file
39
example/examples/general/hover/hover.collection
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: "hover"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"hover\"\n"
|
||||||
|
" component: \"/example/examples/general/hover/hover.gui\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
249
example/examples/general/hover/hover.gui
Normal file
249
example/examples/general/hover/hover.gui
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
script: "/example/examples/general/hover/hover.gui_script"
|
||||||
|
fonts {
|
||||||
|
name: "game"
|
||||||
|
font: "/example/assets/fonts/game.font"
|
||||||
|
}
|
||||||
|
textures {
|
||||||
|
name: "kenney"
|
||||||
|
texture: "/example/assets/images/kenney.atlas"
|
||||||
|
}
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 300.0
|
||||||
|
y: 415.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 600.0
|
||||||
|
y: 830.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/empty"
|
||||||
|
id: "root"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEMPLATE
|
||||||
|
id: "hover_node"
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
template: "/example/templates/button.gui"
|
||||||
|
template_node_child: false
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 80.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/button_blue"
|
||||||
|
id: "hover_node/button"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
parent: "hover_node"
|
||||||
|
layer: "image"
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 15.0
|
||||||
|
y: 15.0
|
||||||
|
z: 15.0
|
||||||
|
w: 15.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
overridden_fields: 4
|
||||||
|
template_node_child: true
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 7.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 0.7
|
||||||
|
y: 0.7
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Hover me!"
|
||||||
|
font: "game"
|
||||||
|
id: "hover_node/text"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 0.101960786
|
||||||
|
y: 0.2
|
||||||
|
z: 0.6
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "hover_node/button"
|
||||||
|
layer: "text"
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 0.0
|
||||||
|
shadow_alpha: 0.78
|
||||||
|
overridden_fields: 8
|
||||||
|
template_node_child: true
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "image"
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "text"
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
41
example/examples/general/hover/hover.gui_script
Normal file
41
example/examples/general/hover/hover.gui_script
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
local druid = require("druid.druid")
|
||||||
|
|
||||||
|
|
||||||
|
function init(self)
|
||||||
|
self.druid = druid.new(self)
|
||||||
|
|
||||||
|
local hover = self.druid:new_hover("hover_node/button")
|
||||||
|
|
||||||
|
-- Usual hover respect to touch action on mobiles. On desktop we will use mouse hover
|
||||||
|
hover.on_mouse_hover:subscribe(function(_, is_hover, hover_instance)
|
||||||
|
print("is hover", is_hover)
|
||||||
|
local node = hover_instance.node
|
||||||
|
gui.animate(node, gui.PROP_SCALE, is_hover and vmath.vector3(1.2) or vmath.vector3(1), gui.EASING_OUTSINE, 0.2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local button = self.druid:new_button("hover_node/button", function()
|
||||||
|
print("Button clicked")
|
||||||
|
end)
|
||||||
|
-- Remove all animations from button, including button hover animations
|
||||||
|
button:set_style()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function final(self)
|
||||||
|
self.druid:final()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function update(self, dt)
|
||||||
|
self.druid:update(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
self.druid:on_message(message_id, message, sender)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function on_input(self, action_id, action)
|
||||||
|
return self.druid:on_input(action_id, action)
|
||||||
|
end
|
@ -0,0 +1,39 @@
|
|||||||
|
name: "late_init_check"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"late_init_check\"\n"
|
||||||
|
" component: \"/example/examples/system/late_init_check/late_init_check.gui\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
374
example/examples/system/late_init_check/late_init_check.gui
Normal file
374
example/examples/system/late_init_check/late_init_check.gui
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
script: "/example/examples/system/late_init_check/late_init_check.gui_script"
|
||||||
|
fonts {
|
||||||
|
name: "game"
|
||||||
|
font: "/example/assets/fonts/game.font"
|
||||||
|
}
|
||||||
|
textures {
|
||||||
|
name: "kenney"
|
||||||
|
texture: "/example/assets/images/kenney.atlas"
|
||||||
|
}
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 300.0
|
||||||
|
y: 415.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 600.0
|
||||||
|
y: 830.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/empty"
|
||||||
|
id: "root"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 200.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 500.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Late init system check\n"
|
||||||
|
"\n"
|
||||||
|
"Should capture input only after create first input component"
|
||||||
|
font: "game"
|
||||||
|
id: "text_hint"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: true
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 0.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: -46.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEMPLATE
|
||||||
|
id: "prefab_button"
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
template: "/example/templates/button.gui"
|
||||||
|
template_node_child: false
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 60.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/button_blue"
|
||||||
|
id: "prefab_button/button"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
parent: "prefab_button"
|
||||||
|
layer: "image"
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 15.0
|
||||||
|
y: 15.0
|
||||||
|
z: 15.0
|
||||||
|
w: 15.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
overridden_fields: 4
|
||||||
|
template_node_child: true
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 7.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 0.7
|
||||||
|
y: 0.7
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Tap me!"
|
||||||
|
font: "game"
|
||||||
|
id: "prefab_button/text"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 0.101960786
|
||||||
|
y: 0.2
|
||||||
|
z: 0.6
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "prefab_button/button"
|
||||||
|
layer: "text"
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 0.0
|
||||||
|
shadow_alpha: 0.78
|
||||||
|
template_node_child: true
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 400.0
|
||||||
|
y: 300.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/empty"
|
||||||
|
id: "grid"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_N
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "image"
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "text"
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
@ -0,0 +1,46 @@
|
|||||||
|
local druid = require("druid.druid")
|
||||||
|
|
||||||
|
|
||||||
|
local function create_button(self, index)
|
||||||
|
local cloned = gui.clone_tree(self.prefab)
|
||||||
|
local root = cloned["prefab_button/button"]
|
||||||
|
self.grid:add(root)
|
||||||
|
gui.set_enabled(root, true)
|
||||||
|
|
||||||
|
local button = self.druid:new_button(root, function()
|
||||||
|
print("Created button with timer delay:", index)
|
||||||
|
end)
|
||||||
|
-- Override to check calls, don't do it in production ;)
|
||||||
|
button.on_late_init = function()
|
||||||
|
print("Late init button check", index)
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Button created, is input inited now?", self.druid.input_inited)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function init(self)
|
||||||
|
self.druid = druid.new(self)
|
||||||
|
|
||||||
|
self.prefab = gui.get_node("prefab_button/button")
|
||||||
|
gui.set_enabled(self.prefab, false)
|
||||||
|
|
||||||
|
self.grid = self.druid:new_static_grid("grid", self.prefab, 1)
|
||||||
|
|
||||||
|
create_button(self, 0)
|
||||||
|
for index = 1, 4 do
|
||||||
|
timer.delay(index, false, function()
|
||||||
|
create_button(self, index)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function final(self)
|
||||||
|
self.druid:final()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function on_input(self, action_id, action)
|
||||||
|
return self.druid:on_input(action_id, action)
|
||||||
|
end
|
39
example/examples/texts/lang_text/lang_text.collection
Normal file
39
example/examples/texts/lang_text/lang_text.collection
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: "lang_text"
|
||||||
|
scale_along_z: 0
|
||||||
|
embedded_instances {
|
||||||
|
id: "go"
|
||||||
|
data: "components {\n"
|
||||||
|
" id: \"lang_text\"\n"
|
||||||
|
" component: \"/example/examples/texts/lang_text/lang_text.gui\"\n"
|
||||||
|
" position {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" }\n"
|
||||||
|
" rotation {\n"
|
||||||
|
" x: 0.0\n"
|
||||||
|
" y: 0.0\n"
|
||||||
|
" z: 0.0\n"
|
||||||
|
" w: 1.0\n"
|
||||||
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
""
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale3 {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
}
|
||||||
|
}
|
514
example/examples/texts/lang_text/lang_text.gui
Normal file
514
example/examples/texts/lang_text/lang_text.gui
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
script: "/example/examples/texts/lang_text/lang_text.gui_script"
|
||||||
|
fonts {
|
||||||
|
name: "game"
|
||||||
|
font: "/example/assets/fonts/game.font"
|
||||||
|
}
|
||||||
|
textures {
|
||||||
|
name: "kenney"
|
||||||
|
texture: "/example/assets/images/kenney.atlas"
|
||||||
|
}
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 300.0
|
||||||
|
y: 415.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 600.0
|
||||||
|
y: 830.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/empty"
|
||||||
|
id: "root"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
template_node_child: false
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 6.0
|
||||||
|
y: 241.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEMPLATE
|
||||||
|
id: "button_change_lang"
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
template: "/example/templates/button.gui"
|
||||||
|
template_node_child: false
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 60.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_BOX
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
texture: "kenney/button_blue"
|
||||||
|
id: "button_change_lang/button"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
parent: "button_change_lang"
|
||||||
|
layer: "image"
|
||||||
|
inherit_alpha: true
|
||||||
|
slice9 {
|
||||||
|
x: 15.0
|
||||||
|
y: 15.0
|
||||||
|
z: 15.0
|
||||||
|
w: 15.0
|
||||||
|
}
|
||||||
|
clipping_mode: CLIPPING_MODE_NONE
|
||||||
|
clipping_visible: true
|
||||||
|
clipping_inverted: false
|
||||||
|
alpha: 1.0
|
||||||
|
overridden_fields: 4
|
||||||
|
template_node_child: true
|
||||||
|
size_mode: SIZE_MODE_MANUAL
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 7.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 0.7
|
||||||
|
y: 0.7
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Change lang"
|
||||||
|
font: "game"
|
||||||
|
id: "button_change_lang/text"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 0.101960786
|
||||||
|
y: 0.2
|
||||||
|
z: 0.6
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "button_change_lang/button"
|
||||||
|
layer: "text"
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 0.0
|
||||||
|
shadow_alpha: 0.78
|
||||||
|
overridden_fields: 2
|
||||||
|
overridden_fields: 8
|
||||||
|
template_node_child: true
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: 147.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 0.6
|
||||||
|
y: 0.6
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 500.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Current lang: en"
|
||||||
|
font: "game"
|
||||||
|
id: "text_current_lang"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 0.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: -20.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Example 1"
|
||||||
|
font: "game"
|
||||||
|
id: "text_example_1"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: false
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 0.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: -150.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 200.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Example 2"
|
||||||
|
font: "game"
|
||||||
|
id: "text_example_2"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: true
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 0.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
position {
|
||||||
|
x: 0.0
|
||||||
|
y: -270.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
rotation {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
scale {
|
||||||
|
x: 0.6
|
||||||
|
y: 0.6
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
size {
|
||||||
|
x: 400.0
|
||||||
|
y: 100.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
color {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
type: TYPE_TEXT
|
||||||
|
blend_mode: BLEND_MODE_ALPHA
|
||||||
|
text: "Example 3"
|
||||||
|
font: "game"
|
||||||
|
id: "text_example_3"
|
||||||
|
xanchor: XANCHOR_NONE
|
||||||
|
yanchor: YANCHOR_NONE
|
||||||
|
pivot: PIVOT_CENTER
|
||||||
|
outline {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
shadow {
|
||||||
|
x: 1.0
|
||||||
|
y: 1.0
|
||||||
|
z: 1.0
|
||||||
|
w: 1.0
|
||||||
|
}
|
||||||
|
adjust_mode: ADJUST_MODE_FIT
|
||||||
|
line_break: true
|
||||||
|
parent: "root"
|
||||||
|
layer: ""
|
||||||
|
inherit_alpha: true
|
||||||
|
alpha: 1.0
|
||||||
|
outline_alpha: 1.0
|
||||||
|
shadow_alpha: 0.0
|
||||||
|
template_node_child: false
|
||||||
|
text_leading: 1.0
|
||||||
|
text_tracking: 0.0
|
||||||
|
custom_type: 0
|
||||||
|
enabled: true
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "image"
|
||||||
|
}
|
||||||
|
layers {
|
||||||
|
name: "text"
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
50
example/examples/texts/lang_text/lang_text.gui_script
Normal file
50
example/examples/texts/lang_text/lang_text.gui_script
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
local druid = require("druid.druid")
|
||||||
|
local druid_const = require("druid.const")
|
||||||
|
local lang = require("example.lang")
|
||||||
|
|
||||||
|
|
||||||
|
local function refresh_lang_text(self)
|
||||||
|
self.text_current:format(lang.get_locale("ui_lang"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function init(self)
|
||||||
|
self.druid = druid.new(self)
|
||||||
|
|
||||||
|
self.text_current = self.druid:new_lang_text("text_current_lang", "ui_current_lang")
|
||||||
|
self.text_example_1 = self.druid:new_lang_text("text_example_1", "ui_example_1")
|
||||||
|
self.text_example_2 = self.druid:new_lang_text("text_example_2", "ui_example_2")
|
||||||
|
self.text_example_3 = self.druid:new_lang_text("text_example_3", "ui_example_3")
|
||||||
|
self.text_example_3:format(10, 20, 30)
|
||||||
|
|
||||||
|
refresh_lang_text(self)
|
||||||
|
|
||||||
|
self.current_lang = lang.get_locale()
|
||||||
|
self.druid:new_button("button_change_lang/button", lang.toggle_locale)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function final(self)
|
||||||
|
self.druid:final()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function update(self, dt)
|
||||||
|
self.druid:update(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function on_message(self, message_id, message, sender)
|
||||||
|
-- If we have localized text in text formatting, we should update it manually
|
||||||
|
-- If we have non localized text, the lang_text:format or :translate will update text manually again
|
||||||
|
if message_id == hash(druid_const.ON_LANGUAGE_CHANGE) then
|
||||||
|
refresh_lang_text(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.druid:on_message(message_id, message, sender)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function on_input(self, action_id, action)
|
||||||
|
return self.druid:on_input(action_id, action)
|
||||||
|
end
|
@ -3,6 +3,8 @@ local druid = require("druid.druid")
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local en = {
|
local en = {
|
||||||
|
ui_lang = "En",
|
||||||
|
ui_current_lang = "Current lang: %s",
|
||||||
main_page = "Main page",
|
main_page = "Main page",
|
||||||
texts_page = "Text page",
|
texts_page = "Text page",
|
||||||
button_page = "Button page",
|
button_page = "Button page",
|
||||||
@ -21,9 +23,14 @@ local en = {
|
|||||||
ui_section_input = "Input",
|
ui_section_input = "Input",
|
||||||
ui_text_example = "Translated",
|
ui_text_example = "Translated",
|
||||||
ui_text_change_lang = "Change lang",
|
ui_text_change_lang = "Change lang",
|
||||||
|
ui_example_1 = "Some text example",
|
||||||
|
ui_example_2 = "Lang text with different length to be adjusted",
|
||||||
|
ui_example_3 = "Text with 3 params: %s, %s and %s",
|
||||||
}
|
}
|
||||||
|
|
||||||
local ru = {
|
local ru = {
|
||||||
|
ui_lang = "Ру",
|
||||||
|
ui_current_lang = "Текущий язык: %s",
|
||||||
main_page = "Основное",
|
main_page = "Основное",
|
||||||
texts_page = "Текст",
|
texts_page = "Текст",
|
||||||
button_page = "Кнопки",
|
button_page = "Кнопки",
|
||||||
@ -42,6 +49,9 @@ local ru = {
|
|||||||
ui_section_input = "Ввод текста",
|
ui_section_input = "Ввод текста",
|
||||||
ui_text_example = "Переведен",
|
ui_text_example = "Переведен",
|
||||||
ui_text_change_lang = "Сменить язык",
|
ui_text_change_lang = "Сменить язык",
|
||||||
|
ui_example_1 = "Пример текста",
|
||||||
|
ui_example_2 = "Короткий текст",
|
||||||
|
ui_example_3 = "Текст с 3 параметрами: %s, %s и %s",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,4 +74,5 @@ function M.toggle_locale()
|
|||||||
druid.on_language_change()
|
druid.on_language_change()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
@ -36,9 +36,9 @@ input_key_esc = key_esc
|
|||||||
input_key_back = key_back
|
input_key_back = key_back
|
||||||
input_key_enter = key_enter
|
input_key_enter = key_enter
|
||||||
input_key_backspace = key_backspace
|
input_key_backspace = key_backspace
|
||||||
input_multitouch = multitouch
|
input_multitouch = touch_multi
|
||||||
input_scroll_up = scroll_up
|
input_scroll_up = mouse_wheel_up
|
||||||
input_scroll_down = scroll_down
|
input_scroll_down = mouse_wheel_down
|
||||||
|
|
||||||
[html5]
|
[html5]
|
||||||
engine_arguments = --verify-graphics-calls=false
|
engine_arguments = --verify-graphics-calls=false
|
||||||
|
@ -32,11 +32,11 @@ key_trigger {
|
|||||||
}
|
}
|
||||||
mouse_trigger {
|
mouse_trigger {
|
||||||
input: MOUSE_WHEEL_UP
|
input: MOUSE_WHEEL_UP
|
||||||
action: "scroll_up"
|
action: "mouse_wheel_up"
|
||||||
}
|
}
|
||||||
mouse_trigger {
|
mouse_trigger {
|
||||||
input: MOUSE_WHEEL_DOWN
|
input: MOUSE_WHEEL_DOWN
|
||||||
action: "scroll_down"
|
action: "mouse_wheel_down"
|
||||||
}
|
}
|
||||||
mouse_trigger {
|
mouse_trigger {
|
||||||
input: MOUSE_BUTTON_1
|
input: MOUSE_BUTTON_1
|
||||||
@ -44,7 +44,7 @@ mouse_trigger {
|
|||||||
}
|
}
|
||||||
touch_trigger {
|
touch_trigger {
|
||||||
input: TOUCH_MULTI
|
input: TOUCH_MULTI
|
||||||
action: "multitouch"
|
action: "touch_multi"
|
||||||
}
|
}
|
||||||
text_trigger {
|
text_trigger {
|
||||||
input: TEXT
|
input: TEXT
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 40 KiB |
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
use_latest_bob=false
|
use_latest_bob=false
|
||||||
enable_incremental_version=true
|
enable_incremental_version=true
|
||||||
bob_sha="3.0:0e77ba11ac957ee01878bbde2e6ac0c9fae6dc01"
|
bob_sha="4.0:f4a699eb412a2445e894568f2d7466aba61b4c41"
|
||||||
|
62
test/helper/mock_input.lua
Normal file
62
test/helper/mock_input.lua
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
|
||||||
|
function M.click_pressed(x, y)
|
||||||
|
return hash("touch"), {
|
||||||
|
pressed = true,
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.click_released(x, y)
|
||||||
|
return hash("touch"), {
|
||||||
|
released = true,
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.key_pressed(key_id)
|
||||||
|
return hash(key_id), {
|
||||||
|
pressed = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.key_released(key_id)
|
||||||
|
return hash(key_id), {
|
||||||
|
released = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.click_repeated(x, y)
|
||||||
|
return hash("touch"), {
|
||||||
|
repeated = true,
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.input_empty(x, y)
|
||||||
|
return hash("touch"), {
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.input_empty_action_nil(x, y)
|
||||||
|
return nil, {
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
19
test/helper/test_helper.lua
Normal file
19
test/helper/test_helper.lua
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
local mock = require("deftest.mock.mock")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- Userdata type instead of script self
|
||||||
|
function M.get_context()
|
||||||
|
return vmath.vector()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Callback for return value from function
|
||||||
|
function M.get_function(callback)
|
||||||
|
local listener = {}
|
||||||
|
listener.callback = function(...) if callback then return callback(...) end end
|
||||||
|
mock.mock(listener)
|
||||||
|
return function(...) return listener.callback(...) end, listener.callback
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
@ -4,7 +4,7 @@ embedded_instances {
|
|||||||
id: "test"
|
id: "test"
|
||||||
data: "components {\n"
|
data: "components {\n"
|
||||||
" id: \"test\"\n"
|
" id: \"test\"\n"
|
||||||
" component: \"/test/test.script\"\n"
|
" component: \"/test/test.gui\"\n"
|
||||||
" position {\n"
|
" position {\n"
|
||||||
" x: 0.0\n"
|
" x: 0.0\n"
|
||||||
" y: 0.0\n"
|
" y: 0.0\n"
|
||||||
@ -16,6 +16,8 @@ embedded_instances {
|
|||||||
" z: 0.0\n"
|
" z: 0.0\n"
|
||||||
" w: 1.0\n"
|
" w: 1.0\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
" property_decls {\n"
|
||||||
|
" }\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
""
|
""
|
||||||
position {
|
position {
|
||||||
|
10
test/test.gui
Normal file
10
test/test.gui
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
script: "/test/test.gui_script"
|
||||||
|
background_color {
|
||||||
|
x: 0.0
|
||||||
|
y: 0.0
|
||||||
|
z: 0.0
|
||||||
|
w: 0.0
|
||||||
|
}
|
||||||
|
material: "/builtins/materials/gui.material"
|
||||||
|
adjust_reference: ADJUST_REFERENCE_PARENT
|
||||||
|
max_nodes: 512
|
@ -1,7 +1,10 @@
|
|||||||
local deftest = require "deftest.deftest"
|
local deftest = require("deftest.deftest")
|
||||||
|
|
||||||
local tests = {
|
local tests = {
|
||||||
-- Test list
|
-- Test list
|
||||||
|
require("test.tests.test_button"),
|
||||||
|
require("test.tests.test_hover"),
|
||||||
|
require("test.tests.test_drag"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
266
test/tests/test_button.lua
Normal file
266
test/tests/test_button.lua
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
local mock_gui = require("deftest.mock.gui")
|
||||||
|
local mock_time = require("deftest.mock.time")
|
||||||
|
local mock_input = require("test.helper.mock_input")
|
||||||
|
local test_helper = require("test.helper.test_helper")
|
||||||
|
local druid_system = require("druid.druid")
|
||||||
|
|
||||||
|
|
||||||
|
return function()
|
||||||
|
local druid = nil
|
||||||
|
local context = test_helper.get_context()
|
||||||
|
describe("Button Component", function()
|
||||||
|
before(function()
|
||||||
|
mock_gui.mock()
|
||||||
|
mock_time.mock()
|
||||||
|
mock_time.set(60)
|
||||||
|
druid = druid_system.new(context)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after(function()
|
||||||
|
mock_gui.unmock()
|
||||||
|
mock_time.unmock()
|
||||||
|
druid:final(context)
|
||||||
|
druid = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do usual click", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
local is_clicked_pressed = druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
local is_clicked_released = druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(is_clicked_pressed)
|
||||||
|
assert(is_clicked_released)
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(on_click_mock.params[1] == context)
|
||||||
|
assert(on_click_mock.params[2] == button_params)
|
||||||
|
assert(on_click_mock.params[3] == instance)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do long click if exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local on_long_click, on_long_click_mock = test_helper.get_function()
|
||||||
|
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance.on_long_click:subscribe(on_long_click)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
mock_time.elapse(0.3)
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(on_long_click_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
mock_time.elapse(0.5)
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(on_long_click_mock.calls == 1)
|
||||||
|
assert(on_long_click_mock.params[1] == context)
|
||||||
|
assert(on_long_click_mock.params[2] == button_params)
|
||||||
|
assert(on_long_click_mock.params[3] == instance)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do not long click if not exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
druid:new_button(button, on_click, button_params)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
mock_time.elapse(0.5)
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do double click if exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local on_double_click, on_double_click_mock = test_helper.get_function()
|
||||||
|
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance.on_double_click:subscribe(on_double_click)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
mock_time.elapse(0.1)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(on_double_click_mock.calls == 1)
|
||||||
|
assert(on_double_click_mock.params[1] == context)
|
||||||
|
assert(on_double_click_mock.params[2] == button_params)
|
||||||
|
assert(on_double_click_mock.params[3] == instance)
|
||||||
|
|
||||||
|
mock_time.elapse(1)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
mock_time.elapse(0.5) -- The double click should not register, big time between clicks
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 3)
|
||||||
|
assert(on_double_click_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do not double click if not exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
druid:new_button(button, on_click, button_params)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
mock_time.elapse(0.1)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do hold click if exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local on_long_click, on_long_click_mock = test_helper.get_function()
|
||||||
|
local on_hold_callback, on_hold_callback_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance.on_long_click:subscribe(on_long_click) -- long click required for hold callback
|
||||||
|
instance.on_hold_callback:subscribe(on_hold_callback)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
mock_time.elapse(0.5) -- time between hold treshold and autorelease hold time
|
||||||
|
druid:on_input(mock_input.click_repeated(10, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
assert(on_hold_callback_mock.calls == 1)
|
||||||
|
assert(on_hold_callback_mock.params[1] == context)
|
||||||
|
assert(on_hold_callback_mock.params[2] == button_params)
|
||||||
|
assert(on_hold_callback_mock.params[3] == instance)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_released(10, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
assert(on_long_click_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do click outside if exists", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click = test_helper.get_function()
|
||||||
|
local on_click_outside, on_click_outside_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance.on_click_outside:subscribe(on_click_outside)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(-10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(-10, 10))
|
||||||
|
|
||||||
|
assert(on_click_outside_mock.calls == 1)
|
||||||
|
|
||||||
|
mock_time.elapse(1)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(-10, 10))
|
||||||
|
|
||||||
|
assert(on_click_outside_mock.calls == 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should not click if mouse was outside while clicking", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
druid:new_button(button, on_click, button_params)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.input_empty(-10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with check function", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
local check_function, check_function_mock = test_helper.get_function(function() return false end)
|
||||||
|
local failure_function, failure_function_mock = test_helper.get_function()
|
||||||
|
instance:set_check_function(check_function, failure_function)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
assert(check_function_mock.calls == 1)
|
||||||
|
assert(failure_function_mock.calls == 1)
|
||||||
|
|
||||||
|
local check_true_function, check_function_true_mock = test_helper.get_function(function() return true end)
|
||||||
|
instance:set_check_function(check_true_function, failure_function)
|
||||||
|
|
||||||
|
mock_time.elapse(1)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(20, 10))
|
||||||
|
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(check_function_true_mock.calls == 1)
|
||||||
|
assert(failure_function_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should have key trigger", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance:set_key_trigger("key_a")
|
||||||
|
druid:on_input(mock_input.key_pressed("key_a"))
|
||||||
|
druid:on_input(mock_input.key_released("key_a"))
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(instance:get_key_trigger() == hash("key_a"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with click zone", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local zone = mock_gui.add_box("zone", 25, 25, 25, 25)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
instance:set_click_zone(zone)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
druid:on_input(mock_input.click_released(10, 10))
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(25, 25))
|
||||||
|
druid:on_input(mock_input.click_released(25, 25))
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with set_enabled", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local button_params = {}
|
||||||
|
local on_click, on_click_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_button(button, on_click, button_params)
|
||||||
|
|
||||||
|
instance:set_enabled(false)
|
||||||
|
local is_clicked_pressed = druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
local is_clicked_released = druid:on_input(mock_input.click_released(10, 10))
|
||||||
|
assert(is_clicked_pressed == false)
|
||||||
|
assert(is_clicked_released == false)
|
||||||
|
assert(on_click_mock.calls == 0)
|
||||||
|
assert(instance:is_enabled() == false)
|
||||||
|
|
||||||
|
instance:set_enabled(true)
|
||||||
|
local is_clicked_pressed2 = druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(is_clicked_pressed2 == true)
|
||||||
|
local is_clicked_released2 = druid:on_input(mock_input.click_released(10, 10))
|
||||||
|
assert(is_clicked_released2 == true)
|
||||||
|
assert(on_click_mock.calls == 1)
|
||||||
|
assert(instance:is_enabled() == true)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
134
test/tests/test_drag.lua
Normal file
134
test/tests/test_drag.lua
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
local mock_gui = require "deftest.mock.gui"
|
||||||
|
local mock_time = require("deftest.mock.time")
|
||||||
|
local mock_input = require("test.helper.mock_input")
|
||||||
|
local test_helper = require("test.helper.test_helper")
|
||||||
|
local druid_system = require("druid.druid")
|
||||||
|
|
||||||
|
return function()
|
||||||
|
local druid = nil
|
||||||
|
local context = test_helper.get_context()
|
||||||
|
|
||||||
|
local function create_drag_instance(on_drag)
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 20, 20)
|
||||||
|
local instance = druid:new_drag(button, on_drag)
|
||||||
|
instance.style.NO_USE_SCREEN_KOEF = true
|
||||||
|
instance.style.DRAG_DEADZONE = 4
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
describe("Drag component", function()
|
||||||
|
before(function()
|
||||||
|
mock_gui.mock()
|
||||||
|
mock_time.mock()
|
||||||
|
mock_time.set(60)
|
||||||
|
druid = druid_system.new(context)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after(function()
|
||||||
|
mock_gui.unmock()
|
||||||
|
mock_time.unmock()
|
||||||
|
druid:final(context)
|
||||||
|
druid = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should call drag callback on node", function()
|
||||||
|
local on_drag, on_drag_mock = test_helper.get_function()
|
||||||
|
local instance = create_drag_instance(on_drag)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(instance.is_touch == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(12, 10))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(14, 10))
|
||||||
|
assert(on_drag_mock.calls == 1)
|
||||||
|
assert(on_drag_mock.params[2] == 2) -- From the last input dx
|
||||||
|
assert(on_drag_mock.params[3] == 0)
|
||||||
|
assert(on_drag_mock.params[4] == 4) -- Total X from drag start point
|
||||||
|
assert(on_drag_mock.params[5] == 0)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
it("Should call all included events", function()
|
||||||
|
local on_drag, on_drag_mock = test_helper.get_function()
|
||||||
|
local instance = create_drag_instance(on_drag)
|
||||||
|
|
||||||
|
local on_touch_start, on_touch_start_mock = test_helper.get_function()
|
||||||
|
instance.on_touch_start:subscribe(on_touch_start)
|
||||||
|
local on_touch_end, on_touch_end_mock = test_helper.get_function()
|
||||||
|
instance.on_touch_end:subscribe(on_touch_end)
|
||||||
|
local on_drag_start, on_drag_start_mock = test_helper.get_function()
|
||||||
|
instance.on_drag_start:subscribe(on_drag_start)
|
||||||
|
local on_drag_end, on_drag_end_mock = test_helper.get_function()
|
||||||
|
instance.on_drag_end:subscribe(on_drag_end)
|
||||||
|
|
||||||
|
assert(on_touch_start_mock.calls == 0)
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(on_touch_start_mock.calls == 1)
|
||||||
|
assert(on_touch_end_mock.calls == 0)
|
||||||
|
druid:on_input(mock_input.click_released(12, 10))
|
||||||
|
assert(on_touch_end_mock.calls == 1)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(on_drag_start_mock.calls == 0)
|
||||||
|
druid:on_input(mock_input.input_empty(15, 10))
|
||||||
|
assert(on_drag_start_mock.calls == 1)
|
||||||
|
assert(on_drag_mock.calls == 1)
|
||||||
|
assert(on_drag_end_mock.calls == 0)
|
||||||
|
druid:on_input(mock_input.click_released(15, 10))
|
||||||
|
assert(on_drag_end_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with set_enabled", function()
|
||||||
|
local on_drag, on_drag_mock = test_helper.get_function()
|
||||||
|
local instance = create_drag_instance(on_drag)
|
||||||
|
|
||||||
|
instance:set_enabled(false)
|
||||||
|
assert(instance:is_enabled() == false)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(instance.is_touch == false)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(12, 10))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(15, 10))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
instance:set_enabled(true)
|
||||||
|
assert(instance:is_enabled() == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(10, 10))
|
||||||
|
assert(instance.is_touch == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(12, 10))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(15, 10))
|
||||||
|
assert(on_drag_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with click zone", function()
|
||||||
|
local on_drag, on_drag_mock = test_helper.get_function()
|
||||||
|
local instance = create_drag_instance(on_drag)
|
||||||
|
local zone = mock_gui.add_box("zone", 10, 10, 10, 10)
|
||||||
|
instance:set_click_zone(zone)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(5, 5))
|
||||||
|
assert(instance.is_touch == false)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(10, 5))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(15, 10))
|
||||||
|
assert(on_drag_mock.calls == 0)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.click_pressed(15, 15))
|
||||||
|
assert(instance.is_touch == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(20, 15))
|
||||||
|
assert(on_drag_mock.calls == 1)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
102
test/tests/test_hover.lua
Normal file
102
test/tests/test_hover.lua
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
local mock_gui = require "deftest.mock.gui"
|
||||||
|
local mock_time = require("deftest.mock.time")
|
||||||
|
local mock_input = require("test.helper.mock_input")
|
||||||
|
local test_helper = require("test.helper.test_helper")
|
||||||
|
local druid_system = require("druid.druid")
|
||||||
|
|
||||||
|
return function()
|
||||||
|
local druid = nil
|
||||||
|
local context = test_helper.get_context()
|
||||||
|
describe("Hover component", function()
|
||||||
|
before(function()
|
||||||
|
mock_gui.mock()
|
||||||
|
mock_time.mock()
|
||||||
|
mock_time.set(60)
|
||||||
|
druid = druid_system.new(context)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after(function()
|
||||||
|
mock_gui.unmock()
|
||||||
|
mock_time.unmock()
|
||||||
|
druid:final(context)
|
||||||
|
druid = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should fire callback on touch hover and unhover", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local is_hovered = false
|
||||||
|
local on_hover, on_hover_mock = test_helper.get_function(function(_, state)
|
||||||
|
is_hovered = state
|
||||||
|
end)
|
||||||
|
local instance = druid:new_hover(button, on_hover)
|
||||||
|
druid:on_input(mock_input.input_empty(10, 10))
|
||||||
|
assert(is_hovered == true)
|
||||||
|
assert(instance:is_hovered() == true)
|
||||||
|
assert(instance:is_mouse_hovered() == false)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(-10, 10))
|
||||||
|
assert(is_hovered == false)
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
assert(instance:is_mouse_hovered() == false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should fire callback on mouse hover and unhover", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local is_hovered = false
|
||||||
|
local on_hover, on_hover_mock = test_helper.get_function(function(_, state)
|
||||||
|
is_hovered = state
|
||||||
|
end)
|
||||||
|
|
||||||
|
local instance = druid:new_hover(button)
|
||||||
|
instance.on_mouse_hover:subscribe(on_hover)
|
||||||
|
druid:on_input(mock_input.input_empty_action_nil(10, 10))
|
||||||
|
assert(is_hovered == true)
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
assert(instance:is_mouse_hovered() == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty_action_nil(-10, 10))
|
||||||
|
assert(is_hovered == false)
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
assert(instance:is_mouse_hovered() == false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should work with click zone", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local zone = mock_gui.add_box("zone", 25, 25, 25, 25)
|
||||||
|
local on_hover, on_hover_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_hover(button, on_hover)
|
||||||
|
instance:set_click_zone(zone)
|
||||||
|
druid:on_input(mock_input.input_empty(10, 10))
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(25, 25))
|
||||||
|
assert(instance:is_hovered() == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(24, 24))
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should have set_enabled function", function()
|
||||||
|
local button = mock_gui.add_box("button", 0, 0, 100, 50)
|
||||||
|
local on_hover, on_hover_mock = test_helper.get_function()
|
||||||
|
local instance = druid:new_hover(button, on_hover)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(10, 10))
|
||||||
|
assert(instance:is_hovered() == true)
|
||||||
|
|
||||||
|
instance:set_enabled(false)
|
||||||
|
assert(instance:is_enabled() == false)
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
druid:on_input(mock_input.input_empty(12, 12))
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
|
||||||
|
instance:set_enabled(true)
|
||||||
|
druid:on_input(mock_input.input_empty(12, 12))
|
||||||
|
assert(instance:is_enabled() == true)
|
||||||
|
assert(instance:is_hovered() == true)
|
||||||
|
|
||||||
|
druid:on_input(mock_input.input_empty(-10, 10))
|
||||||
|
assert(instance:is_hovered() == false)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
29
test/tests/test_template.lua
Normal file
29
test/tests/test_template.lua
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
local mock_gui = require "deftest.mock.gui"
|
||||||
|
local mock_time = require("deftest.mock.time")
|
||||||
|
local mock_input = require("test.helper.mock_input")
|
||||||
|
local test_helper = require("test.helper.test_helper")
|
||||||
|
local druid_system = require("druid.druid")
|
||||||
|
|
||||||
|
return function()
|
||||||
|
local druid = nil
|
||||||
|
local context = test_helper.get_context()
|
||||||
|
describe("Template component", function()
|
||||||
|
before(function()
|
||||||
|
mock_gui.mock()
|
||||||
|
mock_time.mock()
|
||||||
|
mock_time.set(60)
|
||||||
|
druid = druid_system.new(context)
|
||||||
|
end)
|
||||||
|
|
||||||
|
after(function()
|
||||||
|
mock_gui.unmock()
|
||||||
|
mock_time.unmock()
|
||||||
|
druid:final(context)
|
||||||
|
druid = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("Should do something right", function()
|
||||||
|
assert(2 == 1 + 1)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user