mirror of
https://github.com/airstruck/luigi.git
synced 2026-01-10 08:18:22 +00:00
Scrolling improvements, fixes #13
This commit is contained in:
@@ -29,12 +29,16 @@ layout.mainCanvas.text = [[
|
|||||||
This program demonstrates some features of the Luigi UI library.
|
This program demonstrates some features of the Luigi UI library.
|
||||||
|
|
||||||
Luigi is a widget toolkit that runs under Love or LuaJIT.
|
Luigi is a widget toolkit that runs under Love or LuaJIT.
|
||||||
]]
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]
|
||||||
|
|
||||||
|
|
||||||
layout.mainCanvas.align = 'top'
|
layout.mainCanvas.align = 'top'
|
||||||
|
|
||||||
layout.mainCanvas.wrap = true
|
layout.mainCanvas.wrap = true
|
||||||
|
|
||||||
|
layout.mainCanvas.scroll = true
|
||||||
|
|
||||||
-- help dialogs
|
-- help dialogs
|
||||||
|
|
||||||
layout.about:onPress(function()
|
layout.about:onPress(function()
|
||||||
|
|||||||
@@ -245,20 +245,4 @@ function Font:getAdvance (text)
|
|||||||
return w[0]
|
return w[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
function Font:getWrappedHeight (text)
|
|
||||||
--[[
|
|
||||||
-- TTF_Font *font, const char *text, int wrapLength, int *w, int *h, int *lineCount
|
|
||||||
local w, h, lineCount = IntOut(), IntOut(), IntOut()
|
|
||||||
|
|
||||||
SDL2_ttf.TTF_SizeUTF8_Wrapped(self.sdlFont, text, self.width,
|
|
||||||
w, h, lineCount)
|
|
||||||
|
|
||||||
return self:getLineHeight() * lineCount
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local w, h = IntOut(), IntOut()
|
|
||||||
SDL2_ttf.TTF_SizeUTF8(self.sdlFont, text, w, h)
|
|
||||||
return h[0]
|
|
||||||
end
|
|
||||||
|
|
||||||
return Font
|
return Font
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ local function renderMulti (self, font, text, color, align, limit)
|
|||||||
sdl.setTextureAlphaMod(self.sdlTexture, alphaMod)
|
sdl.setTextureAlphaMod(self.sdlTexture, alphaMod)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.width, self.height = surface.w, surface.h
|
self.width, self.height = limit, height
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text:constructor (renderer, font, text, color, align, limit)
|
function Text:constructor (renderer, font, text, color, align, limit)
|
||||||
|
|||||||
@@ -50,16 +50,4 @@ function Font:getAdvance (text)
|
|||||||
return (self.loveFont:getWidth(text))
|
return (self.loveFont:getWidth(text))
|
||||||
end
|
end
|
||||||
|
|
||||||
if love._version_minor < 10 then
|
|
||||||
function Font:getWrappedHeight (text)
|
|
||||||
local _, lines = self.loveFont:getWrap(text, self.width)
|
|
||||||
return lines * self.loveFont:getHeight()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
function Font:getWrappedHeight (text)
|
|
||||||
local _, lines = self.loveFont:getWrap(text, self.width)
|
|
||||||
return #lines * self.loveFont:getHeight()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return Font
|
return Font
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ function Layout:constructor (data, master)
|
|||||||
self.root = data
|
self.root = data
|
||||||
|
|
||||||
Widget(self, data)
|
Widget(self, data)
|
||||||
|
|
||||||
|
self.isReady = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function clearWidget (widget)
|
local function clearWidget (widget)
|
||||||
@@ -321,24 +323,7 @@ function Layout:addDefaultHandlers ()
|
|||||||
self:onWheelMove(function (event)
|
self:onWheelMove(function (event)
|
||||||
if not event.hit then return end
|
if not event.hit then return end
|
||||||
for widget in event.target:eachAncestor(true) do
|
for widget in event.target:eachAncestor(true) do
|
||||||
if widget.scroll then
|
if widget:scrollBy(nil, event.y) then return false end
|
||||||
if not widget.scrollY then
|
|
||||||
widget.scrollY = 0
|
|
||||||
end
|
|
||||||
local scrollY = widget.scrollY - event.y * 10
|
|
||||||
local maxY = widget:getContentHeight() - widget:getHeight()
|
|
||||||
if scrollY > maxY then
|
|
||||||
scrollY = maxY
|
|
||||||
end
|
|
||||||
if scrollY < 0 then
|
|
||||||
scrollY = 0
|
|
||||||
end
|
|
||||||
if scrollY ~= widget.scrollY then
|
|
||||||
widget.scrollY = scrollY
|
|
||||||
widget:reshape()
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end -- if widget.scroll
|
|
||||||
end -- ancestor loop
|
end -- ancestor loop
|
||||||
return false
|
return false
|
||||||
end) -- wheel move
|
end) -- wheel move
|
||||||
|
|||||||
@@ -267,7 +267,9 @@ function Painter:paintIconAndText ()
|
|||||||
|
|
||||||
-- draw the text
|
-- draw the text
|
||||||
if text and textX and textY and w > 1 then
|
if text and textX and textY and w > 1 then
|
||||||
textX, textY = math.floor(textX), math.floor(textY)
|
widget.innerHeight = textY - y + widget.textData:getHeight()
|
||||||
|
textX = math.floor(textX - (widget.scrollX or 0))
|
||||||
|
textY = math.floor(textY - (widget.scrollY or 0))
|
||||||
Backend.draw(widget.textData, textX, textY)
|
Backend.draw(widget.textData, textX, textY)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ the `Input` class, and should generally be treated as read-only.
|
|||||||
Widget.hovered = false
|
Widget.hovered = false
|
||||||
|
|
||||||
--[[--
|
--[[--
|
||||||
Whether the pointer was pressed on this widget and not yet released.
|
Table of mouse buttons pressed on this widget and not yet released,
|
||||||
|
keyed by mouse button name with booleans as values.
|
||||||
|
|
||||||
Can be used by styles and themes. This value is automatically set by
|
Can be used by styles and themes. Values are automatically set by
|
||||||
the `Input` class, and should generally be treated as read-only.
|
the `Input` class, and should generally be treated as read-only.
|
||||||
--]]--
|
--]]--
|
||||||
Widget.pressed = nil
|
Widget.pressed = nil
|
||||||
@@ -614,9 +615,16 @@ Gets the combined width of the widget's children.
|
|||||||
The content width.
|
The content width.
|
||||||
--]]--
|
--]]--
|
||||||
function Widget:getContentWidth ()
|
function Widget:getContentWidth ()
|
||||||
|
if not self.layout.isReady then return 0 end
|
||||||
local width = 0
|
local width = 0
|
||||||
for _, child in ipairs(self) do
|
if self.flow == 'x' then
|
||||||
width = width + child:getWidth()
|
for _, child in ipairs(self) do
|
||||||
|
width = width + child:getWidth()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _, child in ipairs(self) do
|
||||||
|
width = math.max(width, child:getWidth())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return width
|
return width
|
||||||
end
|
end
|
||||||
@@ -630,9 +638,16 @@ Gets the combined height of the widget's children.
|
|||||||
The content height.
|
The content height.
|
||||||
--]]--
|
--]]--
|
||||||
function Widget:getContentHeight ()
|
function Widget:getContentHeight ()
|
||||||
|
if not self.layout.isReady then return 0 end
|
||||||
local height = 0
|
local height = 0
|
||||||
for _, child in ipairs(self) do
|
if self.flow ~= 'x' then
|
||||||
height = height + child:getHeight()
|
for _, child in ipairs(self) do
|
||||||
|
height = height + child:getHeight()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _, child in ipairs(self) do
|
||||||
|
height = math.max(height, child:getHeight())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return height
|
return height
|
||||||
end
|
end
|
||||||
@@ -738,21 +753,39 @@ fires a Reshape event (does not bubble). Called recursively for each child.
|
|||||||
When setting a widget's width or height, this function is automatically called
|
When setting a widget's width or height, this function is automatically called
|
||||||
on the parent widget.
|
on the parent widget.
|
||||||
--]]--
|
--]]--
|
||||||
function Widget:reshape ()
|
function Widget:reshape (keepText)
|
||||||
if self.isReshaping then return end
|
if self.isReshaping then return end
|
||||||
self.isReshaping = true
|
self.isReshaping = true
|
||||||
|
|
||||||
|
self:scrollBy(0, 0)
|
||||||
|
|
||||||
self.position = {}
|
self.position = {}
|
||||||
self.dimensions = {}
|
self.dimensions = {}
|
||||||
|
|
||||||
self.textData = nil
|
if not keepText then self.textData = nil end
|
||||||
|
|
||||||
Event.Reshape:emit(self, { target = self })
|
Event.Reshape:emit(self, { target = self })
|
||||||
for i, widget in ipairs(self) do
|
for i, widget in ipairs(self) do
|
||||||
if widget.reshape then
|
if widget.reshape then
|
||||||
widget:reshape()
|
widget:reshape(keepText)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.isReshaping = nil
|
self.isReshaping = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Widget:scrollBy (x, y)
|
||||||
|
if not self.scroll then return end
|
||||||
|
if not self.scrollY then self.scrollY = 0 end
|
||||||
|
local scrollY = self.scrollY - y * 10
|
||||||
|
local inner = math.max(self:getContentHeight(), self.innerHeight or 0)
|
||||||
|
local maxY = inner - self:getHeight()
|
||||||
|
+ (self.padding or 0) * 2 + (self.margin or 0) * 2
|
||||||
|
scrollY = math.max(math.min(scrollY, maxY), 0)
|
||||||
|
if scrollY ~= self.scrollY then
|
||||||
|
self.scrollY = scrollY
|
||||||
|
self:reshape(true)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return setmetatable(Widget, { __call = metaCall })
|
return setmetatable(Widget, { __call = metaCall })
|
||||||
|
|||||||
Reference in New Issue
Block a user