mirror of
https://github.com/Insality/druid.git
synced 2025-06-27 10:27:47 +02:00
Update drag/slider scene node koefs, add layout max gui upscale
This commit is contained in:
parent
9cd1769c37
commit
4de50591f8
@ -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,11 +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 IS_USE_SCREEN_KOEF If screen aspect ration affects on drag values
|
-- @tfield[opt=false] boolean NO_USE_SCREEN_KOEF If screen aspect ration 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.IS_USE_SCREEN_KOEF = style.IS_USE_SCREEN_KOEF or false
|
self.style.NO_USE_SCREEN_KOEF = style.NO_USE_SCREEN_KOEF or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -183,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()
|
||||||
@ -208,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
|
||||||
|
|
||||||
|
|
||||||
@ -231,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
|
||||||
@ -281,15 +284,15 @@ function Drag.on_input(self, action_id, action)
|
|||||||
|
|
||||||
if self.is_drag then
|
if self.is_drag then
|
||||||
local x_koef, y_koef = self._x_koef, self._y_koef
|
local x_koef, y_koef = self._x_koef, self._y_koef
|
||||||
if not self.style.IS_USE_SCREEN_KOEF then
|
if self.style.NO_USE_SCREEN_KOEF then
|
||||||
x_koef, y_koef = 1, 1
|
x_koef, y_koef = 1, 1
|
||||||
end
|
end
|
||||||
|
|
||||||
self.on_drag:trigger(self:get_context(),
|
self.on_drag:trigger(self:get_context(),
|
||||||
self.dx * x_koef,
|
self.dx * x_koef / self._scene_scale.x,
|
||||||
self.dy * y_koef,
|
self.dy * y_koef / self._scene_scale.y,
|
||||||
(self.x - self.touch_start_pos.x) * x_koef,
|
(self.x - self.touch_start_pos.x) * x_koef / self._scene_scale.x,
|
||||||
(self.y - self.touch_start_pos.y) * 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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
@ -181,7 +188,6 @@ function M.get_text_metrics_from_node(text_node)
|
|||||||
end
|
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
|
||||||
@ -199,6 +205,23 @@ function M.is_enabled(node)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if node is enabled in gui hierarchy.
|
||||||
|
-- Return false, if node or any his parent is disabled
|
||||||
|
-- @function helper.is_enabled
|
||||||
|
-- @tparam node node Gui node
|
||||||
|
-- @treturn bool Is enabled in hierarchy
|
||||||
|
function M.get_scene_scale(node)
|
||||||
|
local scale = gui.get_scale(node)
|
||||||
|
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
|
||||||
|
@ -56,7 +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
|
||||||
IS_USE_SCREEN_KOEF = true,
|
NO_USE_SCREEN_KOEF = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,5 +239,28 @@ return function()
|
|||||||
druid:on_input(mock_input.click_released(25, 25))
|
druid:on_input(mock_input.click_released(25, 25))
|
||||||
assert(on_click_mock.calls == 1)
|
assert(on_click_mock.calls == 1)
|
||||||
end)
|
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)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user