-- @docclass UIPopupScrollMenu = extends(UIWidget, "UIPopupScrollMenu") local currentMenu function UIPopupScrollMenu.create() local menu = UIPopupScrollMenu.internalCreate() local scrollArea = g_ui.createWidget('UIScrollArea', menu) scrollArea:setLayout(UIVerticalLayout.create(menu)) scrollArea:setId('scrollArea') local scrollBar = g_ui.createWidget('VerticalScrollBar', menu) scrollBar:setId('scrollBar') scrollBar.pixelsScroll = false scrollBar:addAnchor(AnchorRight, 'parent', AnchorRight) scrollBar:addAnchor(AnchorTop, 'parent', AnchorTop) scrollBar:addAnchor(AnchorBottom, 'parent', AnchorBottom) scrollArea:addAnchor(AnchorLeft, 'parent', AnchorLeft) scrollArea:addAnchor(AnchorTop, 'parent', AnchorTop) scrollArea:addAnchor(AnchorBottom, 'parent', AnchorBottom) scrollArea:addAnchor(AnchorRight, 'next', AnchorLeft) scrollArea:setVerticalScrollBar(scrollBar) menu.scrollArea = scrollArea menu.scrollBar = scrollBar return menu end function UIPopupScrollMenu:setScrollbarStep(step) self.scrollBar:setStep(step) end function UIPopupScrollMenu:display(pos) -- don't display if not options was added if self.scrollArea:getChildCount() == 0 then self:destroy() return end if g_ui.isMouseGrabbed() then self:destroy() return end if currentMenu then currentMenu:destroy() end if pos == nil then pos = g_window.getMousePosition() end rootWidget:addChild(self) self:setPosition(pos) self:grabMouse() currentMenu = self end function UIPopupScrollMenu:onGeometryChange(oldRect, newRect) local parent = self:getParent() if not parent then return end local ymax = parent:getY() + parent:getHeight() local xmax = parent:getX() + parent:getWidth() if newRect.y + newRect.height > ymax then local newy = newRect.y - newRect.height if newy > 0 and newy + newRect.height < ymax then self:setY(newy) end end if newRect.x + newRect.width > xmax then local newx = newRect.x - newRect.width if newx > 0 and newx + newRect.width < xmax then self:setX(newx) end end self:bindRectToParent() end function UIPopupScrollMenu:addOption(optionName, optionCallback, shortcut) local optionWidget = g_ui.createWidget(self:getStyleName() .. 'Button', self.scrollArea) optionWidget.onClick = function(widget) self:destroy() optionCallback() end optionWidget:setText(optionName) local width = optionWidget:getTextSize().width + optionWidget:getMarginLeft() + optionWidget:getMarginRight() + 15 if shortcut then local shortcutLabel = g_ui.createWidget(self:getStyleName() .. 'ShortcutLabel', optionWidget) shortcutLabel:setText(shortcut) width = width + shortcutLabel:getTextSize().width + shortcutLabel:getMarginLeft() + shortcutLabel:getMarginRight() end self:setWidth(math.max(self:getWidth(), width)) end function UIPopupScrollMenu:addSeparator() g_ui.createWidget(self:getStyleName() .. 'Separator', self.scrollArea) end function UIPopupScrollMenu:onDestroy() if currentMenu == self then currentMenu = nil end self:ungrabMouse() end function UIPopupScrollMenu:onMousePress(mousePos, mouseButton) -- clicks outside menu area destroys the menu if not self:containsPoint(mousePos) then self:destroy() end return true end function UIPopupScrollMenu:onKeyPress(keyCode, keyboardModifiers) if keyCode == KeyEscape then self:destroy() return true end return false end -- close all menus when the window is resized local function onRootGeometryUpdate() if currentMenu then currentMenu:destroy() end end connect(rootWidget, { onGeometryChange = onRootGeometryUpdate} )