Update layout component, add layout fit example

This commit is contained in:
Insality 2022-09-09 20:45:08 +03:00
parent 25a17773e7
commit ba383261b0
10 changed files with 1472 additions and 76 deletions

View File

@ -413,7 +413,7 @@ Also now you can change the input priority of components temporary. For example
- **#133** [Hotkey] Add new extended component: Hotkey - **#133** [Hotkey] Add new extended component: Hotkey
- It's allow you set hotkeys to call callbacks - It's allow you set hotkeys to call callbacks
- You should pass one action key and several modificator keys (left shift, ctrl etc) - You should pass one action key and several modificator keys (left shift, right ctrl etc)
- List of modificator keys setup via component style (you can change it) - List of modificator keys setup via component style (you can change it)
- You can add several hotkeys on one callback via `hotkey:add_hotkey` with additional params - You can add several hotkeys on one callback via `hotkey:add_hotkey` with additional params
- **#98** [Layout] Add new extended component: Layout - **#98** [Layout] Add new extended component: Layout
@ -440,3 +440,4 @@ Also now you can change the input priority of components temporary. For example
- **#185** [System] Add `on_window_resized` component interest. It will called on game window size changes - **#185** [System] Add `on_window_resized` component interest. It will called on game window size changes
- **#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

View File

@ -5,6 +5,15 @@
-- @within BaseComponent -- @within BaseComponent
-- @alias druid.layout -- @alias druid.layout
--- Layout node
-- @tfield node node
--- Current layout mode
-- @tfield string mode
---On window resize callback(self, new_size)
-- @tfield DruidEvent on_size_changed @{DruidEvent}
--- ---
@ -17,111 +26,162 @@ local Event = require("druid.event")
local Layout = component.create("layout") local Layout = component.create("layout")
function Layout:init(node, mode, on_size_changed_callback) --- Component init function
self.node = self:get_node(node) -- @tparam Layout self @{Layout}
-- @tparam node node Gui node
-- @tparam string node The layout mode (from const.LAYOUT_MODE)
-- @tparam[opt] function on_size_changed_callback The callback on window resize
function Layout.init(self, node, mode, on_size_changed_callback)
self.node = self:get_node(node)
self._min_size = nil self._min_size = nil
self._max_size = nil self._max_size = nil
self._inited = false self._inited = false
self.gui_size = vmath.vector3(gui.get_width(), gui.get_height(), 0) self._fit_node = nil
self.mode = mode or const.LAYOUT_MODE.FIT
self.on_size_changed = Event(on_size_changed_callback) self.mode = mode or const.LAYOUT_MODE.FIT
self.on_size_changed = Event(on_size_changed_callback)
end end
function Layout:on_late_init() function Layout.on_late_init(self)
self._inited = true self._inited = true
self.origin_size = self.origin_size or gui.get_size(self.node) self.origin_size = self.origin_size or gui.get_size(self.node)
self.fit_size = self.fit_size or vmath.vector3(self.origin_size) self.fit_size = self.fit_size or vmath.vector3(self.origin_size)
self.pivot = helper.get_pivot_offset(gui.get_pivot(self.node)) self.pivot = helper.get_pivot_offset(gui.get_pivot(self.node))
self.origin_position = gui.get_position(self.node) self.origin_position = gui.get_position(self.node)
self.position = vmath.vector3(self.origin_position) self.position = vmath.vector3(self.origin_position)
gui.set_size_mode(self.node, gui.SIZE_MODE_MANUAL) gui.set_size_mode(self.node, gui.SIZE_MODE_MANUAL)
gui.set_adjust_mode(self.node, gui.ADJUST_FIT) gui.set_adjust_mode(self.node, gui.ADJUST_FIT)
self:on_window_resized() self:on_window_resized()
end end
function Layout:on_window_resized() function Layout.on_window_resized(self)
if not self._inited then if not self._inited then
return return
end end
local x_koef, y_koef = helper.get_screen_aspect_koef() local x_koef, y_koef = helper.get_screen_aspect_koef()
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._fit_node then
new_size.x = new_size.x * x_koef self.fit_size = gui.get_size(self._fit_node)
end self.fit_size.x = self.fit_size.x / x_koef
if self.mode == const.LAYOUT_MODE.STRETCH_Y or self.mode == const.LAYOUT_MODE.STRETCH then self.fit_size.y = self.fit_size.y / y_koef
new_size.y = new_size.y * y_koef end
end
-- Fit to the stretched container (node size or other defined) x_koef = self.fit_size.x / self.origin_size.x * x_koef
if self.mode == const.LAYOUT_MODE.ZOOM_MIN then y_koef = self.fit_size.y / self.origin_size.y * y_koef
new_size = new_size * math.min(x_koef, y_koef)
end
if self.mode == const.LAYOUT_MODE.ZOOM_MAX then
new_size = new_size * math.max(x_koef, y_koef)
end
if self._min_size then local new_size = vmath.vector3(self.origin_size)
new_size.x = math.max(new_size.x, self._min_size.x)
new_size.y = math.max(new_size.y, self._min_size.y) if self.mode == const.LAYOUT_MODE.STRETCH_X or self.mode == const.LAYOUT_MODE.STRETCH then
end new_size.x = new_size.x * x_koef
if self._max_size then end
new_size.x = math.min(new_size.x, self._max_size.x) if self.mode == const.LAYOUT_MODE.STRETCH_Y or self.mode == const.LAYOUT_MODE.STRETCH then
new_size.y = math.min(new_size.y, self._max_size.y) new_size.y = new_size.y * y_koef
end end
gui.set_size(self.node, new_size)
-- Fit to the stretched container (node size or other defined)
if self.mode == const.LAYOUT_MODE.ZOOM_MIN then
new_size = new_size * math.min(x_koef, y_koef)
end
if self.mode == const.LAYOUT_MODE.ZOOM_MAX then
new_size = new_size * math.max(x_koef, y_koef)
end
if self._min_size then
new_size.x = math.max(new_size.x, self._min_size.x)
new_size.y = math.max(new_size.y, self._min_size.y)
end
if self._max_size then
new_size.x = math.min(new_size.x, self._max_size.x)
new_size.y = math.min(new_size.y, self._max_size.y)
end
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)
self.position.y = self.origin_position.y + self.origin_position.y * (y_koef - 1) self.position.y = self.origin_position.y + self.origin_position.y * (y_koef - 1)
gui.set_position(self.node, self.position) gui.set_position(self.node, self.position)
self.on_size_changed:trigger(self:get_context(), new_size) self.on_size_changed:trigger(self:get_context(), new_size)
end end
function Layout:set_min_size(min_size) --- Set minimal size of layout node
self._min_size = min_size -- @tparam Layout self @{Layout}
return self -- @tparam vector3 min_size
-- @treturn Layout @{Layout}
function Layout.set_min_size(self, min_size)
self._min_size = min_size
return self
end end
function Layout:set_max_size(max_size) --- Set maximum size of layout node
self._max_size = max_size -- @tparam Layout self @{Layout}
return self -- @tparam vector3 min_size
-- @treturn Layout @{Layout}
function Layout.set_max_size(self, max_size)
self._max_size = max_size
return self
end end
function Layout:set_origin_position(new_origin_position) --- Set new origin position of layout node. You should apply this on node movement
self.origin_position = new_origin_position or self.origin_position -- @tparam Layout self @{Layout}
return self -- @tparam vector3 new_origin_position
-- @treturn Layout @{Layout}
function Layout.set_origin_position(self, new_origin_position)
self.origin_position = new_origin_position or self.origin_position
self:on_window_resized()
return self
end end
function Layout:set_origin_size(new_origin_size) --- Set new origin size of layout node. You should apply this on node manual size change
self.origin_size = new_origin_size or self.origin_size -- @tparam Layout self @{Layout}
self:on_window_resized() -- @tparam vector3 new_origin_size
return self -- @treturn Layout @{Layout}
function Layout.set_origin_size(self, new_origin_size)
self.origin_size = new_origin_size or self.origin_size
self:on_window_resized()
return self
end end
function Layout:fit_into_size(target_size) --- Set size for layout node to fit inside it
self.fit_size = target_size -- @tparam Layout self @{Layout}
self:on_window_resized() -- @tparam vector3 target_size
return self -- @treturn Layout @{Layout}
function Layout.fit_into_size(self, target_size)
self.fit_size = target_size
self:on_window_resized()
return self
end end
function Layout:fit_into_window() --- Set node for layout node to fit inside it. Pass nil to reset
return self:fit_into_size(vmath.vector3( -- @tparam Layout self @{Layout}
gui.get_width(), -- @tparam[opt] Node node
gui.get_height(), -- @treturn Layout @{Layout}
0)) function Layout.fit_into_node(self, node)
self._fit_node = node
self:on_window_resized()
return self
end
--- Set current size for layout node to fit inside it
-- @tparam Layout self @{Layout}
-- @treturn Layout @{Layout}
function Layout.fit_into_window(self)
return self:fit_into_size(vmath.vector3(
gui.get_width(),
gui.get_height(),
0))
end end

View File

@ -62,6 +62,10 @@ images {
image: "/example/assets/images/buttons/button_blue.png" image: "/example/assets/images/buttons/button_blue.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF sprite_trim_mode: SPRITE_TRIM_MODE_OFF
} }
images {
image: "/example/assets/images/logo.png"
sprite_trim_mode: SPRITE_TRIM_MODE_OFF
}
margin: 0 margin: 0
extrude_borders: 2 extrude_borders: 2
inner_padding: 0 inner_padding: 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -162,6 +162,9 @@ local function init_lobby(self)
self.lobby_grid:add(get_button(self, "Reinit data", "data_list_reinit_data", "/data_list/reinit_data/reinit_data.gui_script")) self.lobby_grid:add(get_button(self, "Reinit data", "data_list_reinit_data", "/data_list/reinit_data/reinit_data.gui_script"))
self.lobby_grid:add(get_button(self, "With component", "data_list_with_component", "/data_list/with_component/with_component.gui_script")) self.lobby_grid:add(get_button(self, "With component", "data_list_with_component", "/data_list/with_component/with_component.gui_script"))
self.lobby_grid:add(get_title(self, "Layouts"))
self.lobby_grid:add(get_button(self, "Layout fit", "layout_fit", "/custom/layout_fit/layout_fit.gui_script"))
self.lobby_grid:add(get_title(self, "Custom components")) self.lobby_grid:add(get_title(self, "Custom components"))
self.lobby_grid:add(get_button(self, "Rich Input", "custom_rich_input", "/custom/rich_input/rich_input.gui_script")) self.lobby_grid:add(get_button(self, "Rich Input", "custom_rich_input", "/custom/rich_input/rich_input.gui_script"))
self.lobby_grid:add(get_button(self, "Pin Knob", "custom_pin_knob", "/custom/pin_knob/pin_knob.gui_script")) self.lobby_grid:add(get_button(self, "Pin Knob", "custom_pin_knob", "/custom/pin_knob/pin_knob.gui_script"))

View File

@ -70,7 +70,7 @@ nodes {
} }
nodes { nodes {
position { position {
x: -100.0 x: 0.0
y: 250.0 y: 250.0
z: 0.0 z: 0.0
w: 1.0 w: 1.0
@ -190,7 +190,7 @@ nodes {
} }
nodes { nodes {
position { position {
x: -100.0 x: 0.0
y: 100.0 y: 100.0
z: 0.0 z: 0.0
w: 1.0 w: 1.0
@ -310,7 +310,7 @@ nodes {
} }
nodes { nodes {
position { position {
x: -100.0 x: 0.0
y: -50.0 y: -50.0
z: 0.0 z: 0.0
w: 1.0 w: 1.0
@ -430,7 +430,7 @@ nodes {
} }
nodes { nodes {
position { position {
x: -100.0 x: 0.0
y: -200.0 y: -200.0
z: 0.0 z: 0.0
w: 1.0 w: 1.0
@ -637,7 +637,7 @@ nodes {
} }
type: TYPE_TEXT type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA blend_mode: BLEND_MODE_ALPHA
text: "Layout Stretch by Y Anchor W" text: "Layout Stretch by X Anchor W"
font: "game" font: "game"
id: "text_layout_stretch3" id: "text_layout_stretch3"
xanchor: XANCHOR_NONE xanchor: XANCHOR_NONE

View File

@ -9,7 +9,7 @@ function init(self)
self.druid:new_layout("node_layout_stretch", const_druid.LAYOUT_MODE.STRETCH) self.druid:new_layout("node_layout_stretch", const_druid.LAYOUT_MODE.STRETCH)
self.druid:new_layout("node_layout_stretch_x", const_druid.LAYOUT_MODE.STRETCH_X) self.druid:new_layout("node_layout_stretch_x", const_druid.LAYOUT_MODE.STRETCH_X)
self.druid:new_layout("node_layout_stretch_y", const_druid.LAYOUT_MODE.STRETCH_Y) self.druid:new_layout("node_layout_stretch_y", const_druid.LAYOUT_MODE.STRETCH_Y)
self.druid:new_layout("node_layout_stretch_y_anchor_w", const_druid.LAYOUT_MODE.STRETCH_Y) self.druid:new_layout("node_layout_stretch_y_anchor_w", const_druid.LAYOUT_MODE.STRETCH_X)
end end

View File

@ -0,0 +1,37 @@
name: "layout_fit"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"layout_fit\"\n"
" component: \"/example/examples/layout/layout_fit/layout_fit.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"
"}\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
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
local druid = require("druid.druid")
local const_druid = require("druid.const")
local layout = require("druid.extended.layout")
function init(self)
druid.register("layout", layout)
self.druid = druid.new(self)
self.druid:new_layout("node_zoom_test", const_druid.LAYOUT_MODE.STRETCH)
:fit_into_window()
self.druid:new_layout("image_1", const_druid.LAYOUT_MODE.STRETCH)
:fit_into_node(gui.get_node("back_1"))
self.druid:new_layout("image_2", const_druid.LAYOUT_MODE.ZOOM_MAX)
:fit_into_node(gui.get_node("back_2"))
self.druid:new_layout("image_3", const_druid.LAYOUT_MODE.ZOOM_MIN)
:fit_into_node(gui.get_node("back_3"))
self.druid:new_layout("image_4", const_druid.LAYOUT_MODE.STRETCH_X)
:fit_into_node(gui.get_node("back_4"))
self.druid:new_layout("image_5", const_druid.LAYOUT_MODE.STRETCH_Y)
:fit_into_node(gui.get_node("back_5"))
self.druid:new_layout("image_6", const_druid.LAYOUT_MODE.FIT)
:fit_into_node(gui.get_node("back_6"))
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