- implemement Scale and virtual screen size for ScreenArea
- fix state management - WIP
This commit is contained in:
parent
1febc65922
commit
93a4d189da
@ -62,6 +62,7 @@ function builder:build_step(cur)
|
|||||||
local storedState = self:getStateOf(cur)
|
local storedState = self:getStateOf(cur)
|
||||||
if not storedState then
|
if not storedState then
|
||||||
self.states[key] = self:initStateOf(cur)
|
self.states[key] = self:initStateOf(cur)
|
||||||
|
cur.state = self.states[key]
|
||||||
else
|
else
|
||||||
cur.state = storedState
|
cur.state = storedState
|
||||||
end
|
end
|
||||||
|
|||||||
@ -15,11 +15,12 @@ function element:layout()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function element:draw()
|
function element:draw()
|
||||||
love.graphics.rectangle("line", self._offset_.x, self._offset_.y, self._size_.x, self._size_.y)
|
love.graphics.setLineStyle("rough")
|
||||||
love.graphics.line(self._offset_.x, self._offset_.y, self._offset_.x + self._size_.x, self._offset_.y + self._size_
|
love.graphics.rectangle("line", 0, 0, self._size_.x, self._size_.y)
|
||||||
.y)
|
|
||||||
love.graphics.line(self._offset_.x, self._offset_.y + self._size_.y, self._offset_.x + self._size_.x, self._offset_
|
love.graphics.line(0, 0, self._size_.x, self._size_.y)
|
||||||
.y)
|
love.graphics.line(0, self._size_.y, self._size_.x, 0)
|
||||||
|
love.graphics.setLineStyle("smooth")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @return Placeholder
|
--- @return Placeholder
|
||||||
|
|||||||
26
lib/simple_ui/elements/scale.lua
Normal file
26
lib/simple_ui/elements/scale.lua
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
local SingleChildElement = require "lib.simple_ui.core.single_child_element"
|
||||||
|
|
||||||
|
--- @class Scale : SingleChildElement
|
||||||
|
--- @field sx number
|
||||||
|
--- @field sy number
|
||||||
|
local element = setmetatable({}, SingleChildElement)
|
||||||
|
element.__index = element
|
||||||
|
element.type = "Scale"
|
||||||
|
|
||||||
|
function element:draw()
|
||||||
|
love.graphics.push("transform")
|
||||||
|
love.graphics.translate(self._offset_.x, self._offset_.y)
|
||||||
|
love.graphics.scale(self.sx, self.sy)
|
||||||
|
if self._child_ then self._child_:draw() end
|
||||||
|
love.graphics.pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return Scale
|
||||||
|
--- @param values {sx: number?, sy: number?, child: UIElement?}
|
||||||
|
function element:new(values)
|
||||||
|
values.sx = values.sx or 1
|
||||||
|
values.sy = values.sy or 1
|
||||||
|
return SingleChildElement.new(self, values)
|
||||||
|
end
|
||||||
|
|
||||||
|
return element
|
||||||
@ -1,13 +1,26 @@
|
|||||||
local Constraints = require "lib.simple_ui.core.constraints"
|
local Constraints = require "lib.simple_ui.core.constraints"
|
||||||
local SingleChildElement = require "lib.simple_ui.core.single_child_element"
|
local Rect = require "lib.simple_ui.core.rect"
|
||||||
|
local StatefulElement = require "lib.simple_ui.core.stateful_element"
|
||||||
|
|
||||||
--- @class ScreenArea : SingleChildElement
|
|
||||||
local element = setmetatable({}, SingleChildElement)
|
--- @class ScreenArea : StatefulElement
|
||||||
|
--- @field dimensions Rect
|
||||||
|
--- @field filter "nearest" | "linear"
|
||||||
|
local element = setmetatable({}, StatefulElement)
|
||||||
element.__index = element
|
element.__index = element
|
||||||
element.type = "ScreenArea"
|
element.type = "ScreenArea"
|
||||||
|
|
||||||
|
function element:build()
|
||||||
|
local cw, ch = self.state.canvas:getDimensions()
|
||||||
|
if cw ~= self.dimensions.width or ch ~= self.dimensions.height then
|
||||||
|
self.state.canvas = self:initState().canvas -- в реальном мире оно не будет пересоздаваться каждый кадр
|
||||||
|
end
|
||||||
|
return self.child
|
||||||
|
end
|
||||||
|
|
||||||
function element:layout()
|
function element:layout()
|
||||||
local screenW, screenH = love.graphics.getWidth(), love.graphics.getHeight()
|
local screenW, screenH = self.state.canvas:getDimensions()
|
||||||
|
|
||||||
self._constraints_ = Constraints {
|
self._constraints_ = Constraints {
|
||||||
maxWidth = screenW,
|
maxWidth = screenW,
|
||||||
maxHeight = screenH
|
maxHeight = screenH
|
||||||
@ -20,10 +33,37 @@ function element:layout()
|
|||||||
self._child_._offset_ = Vec3 {}
|
self._child_._offset_ = Vec3 {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function element:draw()
|
||||||
|
local oldCanvas = love.graphics.getCanvas()
|
||||||
|
|
||||||
|
love.graphics.push()
|
||||||
|
love.graphics.origin()
|
||||||
|
love.graphics.setCanvas(self.state.canvas)
|
||||||
|
love.graphics.clear()
|
||||||
|
if self._child_ then self._child_:draw() end
|
||||||
|
love.graphics.pop()
|
||||||
|
|
||||||
|
love.graphics.setCanvas(oldCanvas)
|
||||||
|
love.graphics.push("transform")
|
||||||
|
love.graphics.translate(self._offset_.x, self._offset_.y)
|
||||||
|
love.graphics.draw(self.state.canvas)
|
||||||
|
love.graphics.pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:initState()
|
||||||
|
local canvas = love.graphics.newCanvas(self.dimensions.width, self.dimensions.height)
|
||||||
|
canvas:setFilter(self.filter, self.filter)
|
||||||
|
return {
|
||||||
|
canvas = canvas
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
--- @return ScreenArea
|
--- @return ScreenArea
|
||||||
--- @param values {child: UIElement?}
|
--- @param values {key: any, dimensions: Rect?, filter: "nearest" | "linear" | nil, child: UIElement?}
|
||||||
function element:new(values)
|
function element:new(values)
|
||||||
return SingleChildElement.new(self, values)
|
if not values.dimensions then values.dimensions = Rect { width = love.graphics.getWidth(), height = love.graphics.getHeight() } end
|
||||||
|
if not values.filter then values.filter = "linear" end
|
||||||
|
return StatefulElement.new(self, values)
|
||||||
end
|
end
|
||||||
|
|
||||||
return element
|
return element
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
|
local Rect = require "lib.simple_ui.core.rect"
|
||||||
local ScreenArea = require "lib.simple_ui.elements.screen_area"
|
local ScreenArea = require "lib.simple_ui.elements.screen_area"
|
||||||
local Placeholder = require "lib.simple_ui.elements.placeholder"
|
local Placeholder = require "lib.simple_ui.elements.placeholder"
|
||||||
local Padding = require "lib.simple_ui.elements.padding"
|
local Padding = require "lib.simple_ui.elements.padding"
|
||||||
local Builder = require "lib.simple_ui.core.builder"
|
local Builder = require "lib.simple_ui.core.builder"
|
||||||
local Flex = require "lib.simple_ui.elements.flex"
|
local Flex = require "lib.simple_ui.elements.flex"
|
||||||
local Center = require "lib.simple_ui.elements.center"
|
local Scale = require "lib.simple_ui.elements.scale"
|
||||||
local SizedBox = require "lib.simple_ui.elements.sized_box"
|
local SizedBox = require "lib.simple_ui.elements.sized_box"
|
||||||
local StatefulElement = require "lib.simple_ui.core.stateful_element"
|
local StatefulElement = require "lib.simple_ui.core.stateful_element"
|
||||||
|
|
||||||
@ -77,7 +78,6 @@ function MyWidget:build()
|
|||||||
height = 100,
|
height = 100,
|
||||||
child = Placeholder:new {}
|
child = Placeholder:new {}
|
||||||
},
|
},
|
||||||
|
|
||||||
SizedBox:new {
|
SizedBox:new {
|
||||||
width = 100,
|
width = 100,
|
||||||
height = 100,
|
height = 100,
|
||||||
@ -86,20 +86,29 @@ function MyWidget:build()
|
|||||||
SizedBox:new {
|
SizedBox:new {
|
||||||
width = 100,
|
width = 100,
|
||||||
height = 100,
|
height = 100,
|
||||||
child = Placeholder:new {}
|
child = Placeholder:new {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return Builder {
|
return Builder {
|
||||||
debugDraw = true,
|
-- debugDraw = true,
|
||||||
builder = function()
|
builder = function()
|
||||||
return ScreenArea:new {
|
return Scale:new {
|
||||||
child = MyWidget:new {}
|
sx = 2,
|
||||||
|
sy = 2,
|
||||||
|
child = ScreenArea:new {
|
||||||
|
key = "screen",
|
||||||
|
dimensions = Rect {
|
||||||
|
width = love.graphics.getWidth() / 2,
|
||||||
|
height = love.graphics.getHeight() / 2
|
||||||
|
},
|
||||||
|
filter = "nearest",
|
||||||
|
child = MyWidget:new {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|||||||
2
main.lua
2
main.lua
@ -12,6 +12,8 @@ end
|
|||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
love.window.setMode(1280, 720, { resizable = true, msaa = 4, vsync = true })
|
love.window.setMode(1280, 720, { resizable = true, msaa = 4, vsync = true })
|
||||||
|
love.graphics.setDefaultFilter("nearest")
|
||||||
|
|
||||||
require "lib/tree" -- важно это сделать после настройки окна
|
require "lib/tree" -- важно это сделать после настройки окна
|
||||||
testLayout = require "lib.simple_ui.level.test"
|
testLayout = require "lib.simple_ui.level.test"
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user