From 6c8dc6a52b97e3eab59cecc90ba37eb5f8027563 Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Sun, 31 May 2026 06:00:53 +0300 Subject: [PATCH] enscapsulate SingleChildElement.child --- lib/simple_ui/core/builder.lua | 23 ++++++++++++++------- lib/simple_ui/core/element.lua | 1 - lib/simple_ui/core/single_child_element.lua | 15 +++++++------- lib/simple_ui/elements/center.lua | 12 +++++------ lib/simple_ui/elements/flex.lua | 4 ++-- lib/simple_ui/elements/padding.lua | 10 ++++----- lib/simple_ui/elements/placeholder.lua | 10 ++++----- lib/simple_ui/elements/screen_area.lua | 8 +++---- lib/simple_ui/elements/sized_box.lua | 8 +++---- lib/simple_ui/level/test.lua | 19 ++++++++++++----- 10 files changed, 64 insertions(+), 46 deletions(-) diff --git a/lib/simple_ui/core/builder.lua b/lib/simple_ui/core/builder.lua index f777fd9..643fd8b 100644 --- a/lib/simple_ui/core/builder.lua +++ b/lib/simple_ui/core/builder.lua @@ -51,22 +51,31 @@ function builder:_makeKey(element) return element.key end +--- @param cur UIElement --- @private function builder:build_step(cur) + cur = cur --[[@as SingleChildElement | MultiChildElement]] if cur.build then - local orphan = cur:build() - local child = cur.child - child = orphan + cur = cur --[[@as SingleChildElement]] + + local child = cur:build() if not child then return end - child._parent_ = cur - cur.child = child + -- local oldChild = cur._child_ + -- if oldChild then + -- for key, value in pairs(oldChild) do + -- if (not Element[key]) then child[key] = value end + -- end + -- end - self:build_step(cur.child) + cur._child_ = child + child._parent_ = cur + + self:build_step(cur._child_) elseif cur.children then + cur = cur --[[@as MultiChildElement]] for _, child in ipairs(cur.children) do child._parent_ = cur - self:build_step(child) end end diff --git a/lib/simple_ui/core/element.lua b/lib/simple_ui/core/element.lua index 4c96a2e..98de443 100644 --- a/lib/simple_ui/core/element.lua +++ b/lib/simple_ui/core/element.lua @@ -8,7 +8,6 @@ local Vec3 = require "lib.utils.vec3" --- @field _constraints_ Constraints --- @field _offset_ Vec3 Положение левого верхнего угла элемента в локальных координатах {x, y}. Устанавливается родительским элементом. --- @field _size_ Vec3 Размеры элемента {x, y} ---- @field build? fun(self, ctx: UIElement): UIElement local element = {} element.__index = element element.type = "Element" diff --git a/lib/simple_ui/core/single_child_element.lua b/lib/simple_ui/core/single_child_element.lua index 962dbb4..f21c94f 100644 --- a/lib/simple_ui/core/single_child_element.lua +++ b/lib/simple_ui/core/single_child_element.lua @@ -3,10 +3,11 @@ local Constraints = require "lib.simple_ui.core.constraints" --- @class SingleChildElement : UIElement --- @field child? UIElement +--- @field _child_? UIElement local element = setmetatable({}, require "lib.simple_ui.core.element") element.__index = element ---- дефолтное поведение -- просто возвращать своего ребенка +--- дефолтное поведение -- просто возвращать переданного ребенка function element:build() return self.child end @@ -15,20 +16,20 @@ function element:layout() --- передать ребенку ограничения --- получить назад размеры --- разместить ребенка - if not self.child then return end - self.child._constraints_ = Constraints(self._constraints_) - self.child:layout() - self.child._offset_ = Vec3 {} + if not self._child_ then return end + self._child_._constraints_ = Constraints(self._constraints_) + self._child_:layout() + self._child_._offset_ = Vec3 {} end function element:update(dt) - if self.child then self.child:update(dt) end + if self._child_ then self._child_:update(dt) end end function element:draw() love.graphics.push("transform") love.graphics.translate(self._offset_.x, self._offset_.y) - if self.child then self.child:draw() end + if self._child_ then self._child_:draw() end love.graphics.pop() end diff --git a/lib/simple_ui/elements/center.lua b/lib/simple_ui/elements/center.lua index 3f564a5..98c42ce 100644 --- a/lib/simple_ui/elements/center.lua +++ b/lib/simple_ui/elements/center.lua @@ -9,13 +9,13 @@ element.type = "Center" function element:layout() self._size_ = Vec3 { self._constraints_.maxWidth, self._constraints_.maxHeight } - if not self.child then return end - self.child._constraints_ = Constraints(self._constraints_) - self.child:layout() + if not self._child_ then return end + self._child_._constraints_ = Constraints(self._constraints_) + self._child_:layout() - self.child._offset_ = Vec3 { - (self._size_.x - self.child._size_.x) / 2, - (self._size_.y - self.child._size_.y) / 2, + self._child_._offset_ = Vec3 { + (self._size_.x - self._child_._size_.x) / 2, + (self._size_.y - self._child_._size_.y) / 2, } end diff --git a/lib/simple_ui/elements/flex.lua b/lib/simple_ui/elements/flex.lua index 0058143..c98cd09 100644 --- a/lib/simple_ui/elements/flex.lua +++ b/lib/simple_ui/elements/flex.lua @@ -31,7 +31,7 @@ function element:layout() end local shift = 0 for _, child in ipairs(self.children) do - child._offset_ = Vec3 { self._offset_.x + start + shift, self._offset_.y } + child._offset_ = Vec3 { start + shift, 0 } shift = shift + child._size_.x end @@ -57,7 +57,7 @@ function element:layout() end local shift = 0 for _, child in ipairs(self.children) do - child._offset_ = Vec3 { self._offset_.x, self._offset_.y + start + shift } + child._offset_ = Vec3 { 0, start + shift } shift = shift + child._size_.y end diff --git a/lib/simple_ui/elements/padding.lua b/lib/simple_ui/elements/padding.lua index 9ced4ef..71ea048 100644 --- a/lib/simple_ui/elements/padding.lua +++ b/lib/simple_ui/elements/padding.lua @@ -19,17 +19,17 @@ element.bottom = 0 --- --- as in https://api.flutter.dev/flutter/widgets/Padding-class.html function element:layout() - if not self.child then return end + if not self._child_ then return end local c = Constraints(self._constraints_) c.maxWidth = c.maxWidth - self.left - self.right c.maxHeight = c.maxHeight - self.top - self.bottom c.maxWidth = c.maxWidth > 0 and c.maxWidth or 0 c.maxHeight = c.maxHeight > 0 and c.maxHeight or 0 - self.child._constraints_ = c + self._child_._constraints_ = c - self.child:layout() - self._size_ = Vec3 { self.child._size_.x + self.left + self.right, self.child._size_.y + self.top + self.bottom } - self.child._offset_ = Vec3 { self.left, self.top } + self._child_:layout() + self._size_ = Vec3 { self._child_._size_.x + self.left + self.right, self._child_._size_.y + self.top + self.bottom } + self._child_._offset_ = Vec3 { self.left, self.top } end --- @return Padding diff --git a/lib/simple_ui/elements/placeholder.lua b/lib/simple_ui/elements/placeholder.lua index 2146165..c4b175d 100644 --- a/lib/simple_ui/elements/placeholder.lua +++ b/lib/simple_ui/elements/placeholder.lua @@ -9,17 +9,17 @@ element.type = "Placeholder" function element:layout() self._size_ = Vec3 { self._constraints_.maxWidth, self._constraints_.maxHeight } - if not self.child then return end - self.child._constraints_ = Constraints(self._constraints_) - self.child:layout() + if not self._child_ then return end + self._child_._constraints_ = Constraints(self._constraints_) + self._child_:layout() end function element:draw() love.graphics.rectangle("line", self._offset_.x, self._offset_.y, self._size_.x, self._size_.y) love.graphics.line(self._offset_.x, self._offset_.y, self._offset_.x + self._size_.x, self._offset_.y + self._size_ - .y) + .y) love.graphics.line(self._offset_.x, self._offset_.y + self._size_.y, self._offset_.x + self._size_.x, self._offset_ - .y) + .y) end --- @return Placeholder diff --git a/lib/simple_ui/elements/screen_area.lua b/lib/simple_ui/elements/screen_area.lua index bab3124..60a1dfb 100644 --- a/lib/simple_ui/elements/screen_area.lua +++ b/lib/simple_ui/elements/screen_area.lua @@ -14,10 +14,10 @@ function element:layout() } self._size_ = Vec3 { screenW, screenH } - if not self.child then return end - self.child._constraints_ = Constraints(self._constraints_) - self.child:layout() - self.child._offset_ = Vec3 {} + if not self._child_ then return end + self._child_._constraints_ = Constraints(self._constraints_) + self._child_:layout() + self._child_._offset_ = Vec3 {} end --- @return ScreenArea diff --git a/lib/simple_ui/elements/sized_box.lua b/lib/simple_ui/elements/sized_box.lua index 37444be..94dbd00 100644 --- a/lib/simple_ui/elements/sized_box.lua +++ b/lib/simple_ui/elements/sized_box.lua @@ -11,13 +11,13 @@ element.height = 0 function element:layout() self._size_ = Vec3 { self.width, self.height } - if not self.child then return end - self.child._constraints_ = Constraints { + if not self._child_ then return end + self._child_._constraints_ = Constraints { maxWidth = self.width, maxHeight = self.height, } - self.child:layout() - self.child._offset_ = Vec3 {} + self._child_:layout() + self._child_._offset_ = Vec3 {} end --- @return SizedBox diff --git a/lib/simple_ui/level/test.lua b/lib/simple_ui/level/test.lua index c567e92..049b639 100644 --- a/lib/simple_ui/level/test.lua +++ b/lib/simple_ui/level/test.lua @@ -18,8 +18,8 @@ Canary.type = "Canary" local reported = false function Canary:build() - -- self.i = self.i and self.i + 1 or 0 - -- print(self.i) + self.i = self.i and self.i + 1 or 0 + print(self.i) -- if not reported then -- self:traverseUp(function(element) -- print(element.type) @@ -60,7 +60,7 @@ function MyWidget:build() width = 100, height = 100, child = Canary:new { - i = 10 + i = 0 } }, }, @@ -68,7 +68,7 @@ function MyWidget:build() }, Flex:new { key = "inner_flex2", - mainAxisAlignment = "center", + mainAxisAlignment = "end", children = { SizedBox:new { width = 100, @@ -84,6 +84,7 @@ function MyWidget:build() }, }, + math.floor(love.timer.getTime()) % 2 == 0 and self.child or nil } } end @@ -119,6 +120,14 @@ end return Builder { elementTree = ScreenArea:new { - child = MyWidget:new {} + child = MyWidget:new { + child = SizedBox:new { + width = 100, + height = 100, + child = Canary:new { + i = 100 + } + } + } } }