Scrolling improvements, fixes #13

This commit is contained in:
airstruck
2015-12-21 12:26:07 -05:00
parent 73e9a10b15
commit 147de8e010
7 changed files with 54 additions and 58 deletions

View File

@@ -29,12 +29,16 @@ layout.mainCanvas.text = [[
This program demonstrates some features of the Luigi UI library.
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.wrap = true
layout.mainCanvas.scroll = true
-- help dialogs
layout.about:onPress(function()

View File

@@ -245,20 +245,4 @@ function Font:getAdvance (text)
return w[0]
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

View File

@@ -77,7 +77,7 @@ local function renderMulti (self, font, text, color, align, limit)
sdl.setTextureAlphaMod(self.sdlTexture, alphaMod)
end
self.width, self.height = surface.w, surface.h
self.width, self.height = limit, height
end
function Text:constructor (renderer, font, text, color, align, limit)

View File

@@ -50,16 +50,4 @@ function Font:getAdvance (text)
return (self.loveFont:getWidth(text))
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

View File

@@ -56,6 +56,8 @@ function Layout:constructor (data, master)
self.root = data
Widget(self, data)
self.isReady = true
end
local function clearWidget (widget)
@@ -321,24 +323,7 @@ function Layout:addDefaultHandlers ()
self:onWheelMove(function (event)
if not event.hit then return end
for widget in event.target:eachAncestor(true) do
if widget.scroll then
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
if widget:scrollBy(nil, event.y) then return false end
end -- ancestor loop
return false
end) -- wheel move

View File

@@ -267,7 +267,9 @@ function Painter:paintIconAndText ()
-- draw the text
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)
end

View File

@@ -43,9 +43,10 @@ the `Input` class, and should generally be treated as read-only.
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.
--]]--
Widget.pressed = nil
@@ -614,9 +615,16 @@ Gets the combined width of the widget's children.
The content width.
--]]--
function Widget:getContentWidth ()
if not self.layout.isReady then return 0 end
local width = 0
for _, child in ipairs(self) do
width = width + child:getWidth()
if self.flow == 'x' then
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
return width
end
@@ -630,9 +638,16 @@ Gets the combined height of the widget's children.
The content height.
--]]--
function Widget:getContentHeight ()
if not self.layout.isReady then return 0 end
local height = 0
for _, child in ipairs(self) do
height = height + child:getHeight()
if self.flow ~= 'x' then
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
return height
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
on the parent widget.
--]]--
function Widget:reshape ()
function Widget:reshape (keepText)
if self.isReshaping then return end
self.isReshaping = true
self:scrollBy(0, 0)
self.position = {}
self.dimensions = {}
self.textData = nil
if not keepText then self.textData = nil end
Event.Reshape:emit(self, { target = self })
for i, widget in ipairs(self) do
if widget.reshape then
widget:reshape()
widget:reshape(keepText)
end
end
self.isReshaping = nil
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 })