Start implement druid layout component

This commit is contained in:
Insality
2022-04-05 18:17:39 +03:00
parent c263c60de8
commit 2779f9cf7a
13 changed files with 906 additions and 3 deletions

View File

@@ -240,10 +240,16 @@ end
-- @treturn number Height
function Text.get_text_size(self, text)
text = text or self.last_value
local font = gui.get_font(self.node)
local font_name = gui.get_font(self.node)
local font = gui.get_font_resource(font_name)
local scale = gui.get_scale(self.node)
local linebreak = gui.get_line_break(self.node)
local metrics = gui.get_text_metrics(font, text, 0, linebreak, 0, 0)
local metrics = resource.get_text_metrics(font, text, {
line_break = linebreak,
leading = 1,
tracking = 0,
width = self.start_size.x
})
local width = metrics.width
for i = #text, 1, -1 do
local c = string.sub(text, i, i)

View File

@@ -25,6 +25,7 @@ BaseComponent.ON_FOCUS_LOST = const.ON_FOCUS_LOST
BaseComponent.ON_FOCUS_GAINED = const.ON_FOCUS_GAINED
BaseComponent.ON_LAYOUT_CHANGE = const.ON_LAYOUT_CHANGE
BaseComponent.ON_MESSAGE_INPUT = const.ON_MESSAGE_INPUT
BaseComponent.ON_WINDOW_RESIZED = const.ON_WINDOW_RESIZED
BaseComponent.ON_LANGUAGE_CHANGE = const.ON_LANGUAGE_CHANGE
@@ -37,6 +38,7 @@ BaseComponent.ALL_INTERESTS = {
BaseComponent.ON_FOCUS_GAINED,
BaseComponent.ON_LAYOUT_CHANGE,
BaseComponent.ON_MESSAGE_INPUT,
BaseComponent.ON_WINDOW_RESIZED,
BaseComponent.ON_LANGUAGE_CHANGE,
}
@@ -46,6 +48,7 @@ BaseComponent.SPECIFIC_UI_MESSAGES = {
[hash("layout_changed")] = BaseComponent.ON_LAYOUT_CHANGE, -- The message_id from Defold
[hash(BaseComponent.ON_FOCUS_LOST)] = BaseComponent.ON_FOCUS_LOST,
[hash(BaseComponent.ON_FOCUS_GAINED)] = BaseComponent.ON_FOCUS_GAINED,
[hash(BaseComponent.ON_WINDOW_RESIZED)] = BaseComponent.ON_WINDOW_RESIZED,
[hash(BaseComponent.ON_MESSAGE_INPUT)] = BaseComponent.ON_MESSAGE_INPUT,
[hash(BaseComponent.ON_LANGUAGE_CHANGE)] = BaseComponent.ON_LANGUAGE_CHANGE,
}

View File

@@ -40,6 +40,7 @@ M.ON_FOCUS_LOST = "on_focus_lost"
M.ON_FOCUS_GAINED = "on_focus_gained"
M.ON_LAYOUT_CHANGE = "on_layout_change"
M.ON_MESSAGE_INPUT = "on_message_input"
M.ON_WINDOW_RESIZED = "on_window_resized"
M.ON_LANGUAGE_CHANGE = "on_language_change"
@@ -83,6 +84,14 @@ M.REVERSE_PIVOTS = {
}
M.LAYOUT_MODE = {
STRETCH_X = "stretch_x",
STRETCH_Y = "stretch_y",
FIT = gui.ADJUST_FIT,
STRETCH = gui.ADJUST_STRETCH,
}
M.VECTOR_ZERO = vmath.vector3(0)
M.VECTOR_ONE = vmath.vector3(1)
M.SYS_INFO = sys.get_sys_info()

View File

@@ -117,6 +117,12 @@ function M.on_window_callback(event)
msg.post(instances[i].url, base_component.ON_FOCUS_GAINED)
end
end
if event == window.WINDOW_EVENT_RESIZED then
for i = 1, #instances do
msg.post(instances[i].url, base_component.ON_WINDOW_RESIZED)
end
end
end

View File

@@ -14,6 +14,7 @@
---
local const = require("druid.const")
local Event = require("druid.event")
local settings = require("druid.system.settings")
local component = require("druid.component")

100
druid/extended/layout.lua Normal file
View File

@@ -0,0 +1,100 @@
-- Copyright (c) 2021 Maksim Tuprikov <insality@gmail.com>. This code is licensed under MIT license
--- Layout management on node
-- @module Layout
-- @within BaseComponent
-- @alias druid.layout
---
local const = require("druid.const")
local helper = require("druid.helper")
local component = require("druid.component")
local Event = require("druid.event")
---@class layout : druid.base_component
local Layout = component.create("layout")
function Layout:init(node, mode, on_size_changed_callback)
self.node = self:get_node(node)
self.origin_size = gui.get_size(self.node)
self.pivot = helper.get_pivot_offset(gui.get_pivot(self.node))
self.origin_position = gui.get_position(self.node)
self.position = vmath.vector3(self.origin_position)
gui.set_size_mode(self.node, gui.SIZE_MODE_MANUAL)
gui.set_adjust_mode(self.node, gui.ADJUST_FIT)
self._min_size = nil
self._max_size = nil
self.window_size = vmath.vector3(gui.get_width(), gui.get_height(), 0)
self.mode = mode or const.LAYOUT_MODE.FIT
self.on_size_changed = Event(on_size_changed_callback)
self:on_window_resized()
end
function Layout:on_window_resized()
local window_x, window_y = window.get_size()
local stretch_x = window_x / self.window_size.x
local stretch_y = window_y / self.window_size.y
local x_koef = stretch_x / math.min(stretch_x, stretch_y)
local y_koef = stretch_y / math.min(stretch_x, stretch_y)
local new_size = vmath.vector3(self.origin_size)
if self.mode == const.LAYOUT_MODE.STRETCH_X or self.mode == const.LAYOUT_MODE.STRETCH then
new_size.x = new_size.x * x_koef
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
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 * x_koef + self.origin_position.x * (1 - x_koef) * self.pivot.x * 2
self.position.y = self.origin_position.y * y_koef + self.origin_position.y * (1 - y_koef) * self.pivot.y * 2
gui.set_position(self.node, self.position)
self.on_size_changed:trigger(self:get_context(), new_size)
end
function Layout:set_min_size(min_size)
self._min_size = min_size
return self
end
function Layout:set_max_size(max_size)
self._max_size = max_size
return self
end
function Layout:set_origin_position(new_origin_position)
self.origin_position = new_origin_position or self.origin_position
return self
end
function Layout:set_origin_size(new_origin_size)
self.origin_size = new_origin_size or self.origin_size
return self
end
return Layout

View File

@@ -103,11 +103,14 @@ function Progress.init(self, node, key, init_value)
self.prop = hash("scale."..key)
self.key = key
self._init_value = init_value or 1
self.node = self:get_node(node)
self.scale = gui.get_scale(self.node)
self.size = gui.get_size(self.node)
self.max_size = self.size[self.key]
self.slice = gui.get_slice9(self.node)
self.last_value = self._init_value
if key == const.SIDE.X then
self.slice_size = self.slice.x + self.slice.z
else
@@ -115,8 +118,12 @@ function Progress.init(self, node, key, init_value)
end
self.on_change = Event()
end
self:set_to(init_value or 1)
-- @tparam Progress self @{Progress}
function Progress.on_late_init(self)
self:set_to(self._init_value)
end
@@ -204,4 +211,15 @@ function Progress.to(self, to, callback)
end
--- Set progress bar max node size
-- @tparam Progress self @{Progress}
-- @tparam vector3 max_size The new node maximum (full) size
-- @treturn Progress @{Progress}
function Progress:set_max_size(max_size)
self.max_size = max_size[self.key]
self:set_to(self.last_value)
return self
end
return Progress

View File

@@ -30,6 +30,7 @@
-- @see Drag
-- @see DataList
-- @see Hover
-- @see Layout
local helper = require("druid.helper")
local class = require("druid.system.middleclass")
@@ -57,6 +58,7 @@ local radio_group = require("druid.extended.radio_group")
local slider = require("druid.extended.slider")
local timer = require("druid.extended.timer")
local data_list = require("druid.extended.data_list")
local layout = require("druid.extended.layout")
local DruidInstance = class("druid.druid_instance")
@@ -738,4 +740,14 @@ function DruidInstance.new_progress(self, node, key, init_value)
end
--- Create layout component
-- @tparam DruidInstance self
-- @tparam string|node node Layout node
-- @tparam string mode The layout mode
-- @treturn Layout layout component
function DruidInstance.new_layout(self, node, mode)
return helper.extended_component("layout")
end
return DruidInstance