You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
5.5 KiB

-- @docclass
UIScrollArea = extends(UIWidget, "UIScrollArea")
-- public functions
function UIScrollArea.create()
local scrollarea = UIScrollArea.internalCreate()
scrollarea:setClipping(true)
scrollarea.inverted = false
scrollarea.alwaysScrollMaximum = false
return scrollarea
end
function UIScrollArea:onStyleApply(styleName, styleNode)
for name,value in pairs(styleNode) do
if name == 'vertical-scrollbar' then
addEvent(function()
local parent = self:getParent()
if parent then
self:setVerticalScrollBar(parent:getChildById(value))
end
end)
elseif name == 'horizontal-scrollbar' then
addEvent(function()
local parent = self:getParent()
if parent then
self:setHorizontalScrollBar(self:getParent():getChildById(value))
end
end)
elseif name == 'inverted-scroll' then
self:setInverted(value)
elseif name == 'always-scroll-maximum' then
self:setAlwaysScrollMaximum(value)
end
end
end
function UIScrollArea:updateScrollBars()
local scrollWidth = math.max(self:getChildrenRect().width - self:getPaddingRect().width, 0)
local scrollHeight = math.max(self:getChildrenRect().height - self:getPaddingRect().height, 0)
local scrollbar = self.verticalScrollBar
if scrollbar then
if self.inverted then
scrollbar:setMinimum(-scrollHeight)
scrollbar:setMaximum(0)
else
scrollbar:setMinimum(0)
scrollbar:setMaximum(scrollHeight)
end
end
local scrollbar = self.horizontalScrollBar
if scrollbar then
if self.inverted then
scrollbar:setMinimum(-scrollWidth)
scrollbar:setMaximum(0)
else
scrollbar:setMinimum(0)
scrollbar:setMaximum(scrollWidth)
end
end
if self.lastScrollWidth ~= scrollWidth then
self:onScrollWidthChange()
end
if self.lastScrollHeight ~= scrollHeight then
self:onScrollHeightChange()
end
self.lastScrollWidth = scrollWidth
self.lastScrollHeight = scrollHeight
end
function UIScrollArea:setVerticalScrollBar(scrollbar)
self.verticalScrollBar = scrollbar
connect(self.verticalScrollBar, 'onValueChange', function(scrollbar, value)
local virtualOffset = self:getVirtualOffset()
virtualOffset.y = value
self:setVirtualOffset(virtualOffset)
signalcall(self.onScrollChange, self, virtualOffset)
end)
self:updateScrollBars()
end
function UIScrollArea:setHorizontalScrollBar(scrollbar)
self.horizontalScrollBar = scrollbar
connect(self.horizontalScrollBar, 'onValueChange', function(scrollbar, value)
local virtualOffset = self:getVirtualOffset()
virtualOffset.x = value
self:setVirtualOffset(virtualOffset)
signalcall(self.onScrollChange, self, virtualOffset)
end)
self:updateScrollBars()
end
function UIScrollArea:setInverted(inverted)
self.inverted = inverted
end
function UIScrollArea:setAlwaysScrollMaximum(value)
self.alwaysScrollMaximum = value
end
function UIScrollArea:onLayoutUpdate()
self:updateScrollBars()
end
function UIScrollArea:onMouseWheel(mousePos, mouseWheel)
if self.verticalScrollBar then
if not self.verticalScrollBar:isOn() then
return false
end
if mouseWheel == MouseWheelUp then
local minimum = self.verticalScrollBar:getMinimum()
if self.verticalScrollBar:getValue() < minimum then
return false
end
self.verticalScrollBar:decrement()
else
local maximum = self.verticalScrollBar:getMaximum()
if self.verticalScrollBar:getValue() >= maximum then
return false
end
self.verticalScrollBar:increment()
end
elseif self.horizontalScrollBar then
if not self.horizontalScrollBar:isOn() then
return false
end
if mouseWheel == MouseWheelUp then
local maximum = self.horizontalScrollBar:getMaximum()
if self.horizontalScrollBar:getValue() >= maximum then
return false
end
self.horizontalScrollBar:increment()
else
local minimum = self.horizontalScrollBar:getMinimum()
if self.horizontalScrollBar:getValue() < minimum then
return false
end
self.horizontalScrollBar:decrement()
end
end
return true
end
function UIScrollArea:ensureChildVisible(child)
if child then
local paddingRect = self:getPaddingRect()
if self.verticalScrollBar then
local deltaY = paddingRect.y - child:getY()
if deltaY > 0 then
self.verticalScrollBar:decrement(deltaY)
end
deltaY = (child:getY() + child:getHeight()) - (paddingRect.y + paddingRect.height)
if deltaY > 0 then
self.verticalScrollBar:increment(deltaY)
end
elseif self.horizontalScrollBar then
local deltaX = paddingRect.x - child:getX()
if deltaX > 0 then
self.horizontalScrollBar:decrement(deltaX)
end
deltaX = (child:getX() + child:getWidth()) - (paddingRect.x + paddingRect.width)
if deltaX > 0 then
self.horizontalScrollBar:increment(deltaX)
end
end
end
end
function UIScrollArea:onChildFocusChange(focusedChild, oldFocused, reason)
if focusedChild and (reason == MouseFocusReason or reason == KeyboardFocusReason) then
self:ensureChildVisible(focusedChild)
end
end
function UIScrollArea:onScrollWidthChange()
if self.alwaysScrollMaximum and self.horizontalScrollBar then
self.horizontalScrollBar:setValue(self.horizontalScrollBar:getMaximum())
end
end
function UIScrollArea:onScrollHeightChange()
if self.alwaysScrollMaximum and self.verticalScrollBar then
self.verticalScrollBar:setValue(self.verticalScrollBar:getMaximum())
end
end