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. 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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 })