1-- @docclass
2UIPopupScrollMenu = extends(UIWidget, "UIPopupScrollMenu")
3
4local currentMenu
5
6function UIPopupScrollMenu.create()
7 local menu = UIPopupScrollMenu.internalCreate()
8
9 local scrollArea = g_ui.createWidget('UIScrollArea', menu)
10 scrollArea:setLayout(UIVerticalLayout.create(menu))
11 scrollArea:setId('scrollArea')
12
13 local scrollBar = g_ui.createWidget('VerticalScrollBar', menu)
14 scrollBar:setId('scrollBar')
15 scrollBar.pixelsScroll = false
16
17 scrollBar:addAnchor(AnchorRight, 'parent', AnchorRight)
18 scrollBar:addAnchor(AnchorTop, 'parent', AnchorTop)
19 scrollBar:addAnchor(AnchorBottom, 'parent', AnchorBottom)
20
21 scrollArea:addAnchor(AnchorLeft, 'parent', AnchorLeft)
22 scrollArea:addAnchor(AnchorTop, 'parent', AnchorTop)
23 scrollArea:addAnchor(AnchorBottom, 'parent', AnchorBottom)
24 scrollArea:addAnchor(AnchorRight, 'next', AnchorLeft)
25 scrollArea:setVerticalScrollBar(scrollBar)
26
27 menu.scrollArea = scrollArea
28 menu.scrollBar = scrollBar
29 return menu
30end
31
32function UIPopupScrollMenu:setScrollbarStep(step)
33 self.scrollBar:setStep(step)
34end
35
36function UIPopupScrollMenu:display(pos)
37 -- don't display if not options was added
38 if self.scrollArea:getChildCount() == 0 then
39 self:destroy()
40 return
41 end
42
43 if g_ui.isMouseGrabbed() then
44 self:destroy()
45 return
46 end
47
48 if currentMenu then
49 currentMenu:destroy()
50 end
51
52 if pos == nil then
53 pos = g_window.getMousePosition()
54 end
55
56 rootWidget:addChild(self)
57 self:setPosition(pos)
58 self:grabMouse()
59 currentMenu = self
60end
61
62function UIPopupScrollMenu:onGeometryChange(oldRect, newRect)
63 local parent = self:getParent()
64 if not parent then return end
65 local ymax = parent:getY() + parent:getHeight()
66 local xmax = parent:getX() + parent:getWidth()
67 if newRect.y + newRect.height > ymax then
68 local newy = newRect.y - newRect.height
69 if newy > 0 and newy + newRect.height < ymax then self:setY(newy) end
70 end
71 if newRect.x + newRect.width > xmax then
72 local newx = newRect.x - newRect.width
73 if newx > 0 and newx + newRect.width < xmax then self:setX(newx) end
74 end
75 self:bindRectToParent()
76end
77
78function UIPopupScrollMenu:addOption(optionName, optionCallback, shortcut)
79 local optionWidget = g_ui.createWidget(self:getStyleName() .. 'Button', self.scrollArea)
80 optionWidget.onClick = function(widget)
81 self:destroy()
82 optionCallback()
83 end
84 optionWidget:setText(optionName)
85 local width = optionWidget:getTextSize().width + optionWidget:getMarginLeft() + optionWidget:getMarginRight() + 15
86
87 if shortcut then
88 local shortcutLabel = g_ui.createWidget(self:getStyleName() .. 'ShortcutLabel', optionWidget)
89 shortcutLabel:setText(shortcut)
90 width = width + shortcutLabel:getTextSize().width + shortcutLabel:getMarginLeft() + shortcutLabel:getMarginRight()
91 end
92
93 self:setWidth(math.max(self:getWidth(), width))
94end
95
96function UIPopupScrollMenu:addSeparator()
97 g_ui.createWidget(self:getStyleName() .. 'Separator', self.scrollArea)
98end
99
100function UIPopupScrollMenu:onDestroy()
101 if currentMenu == self then
102 currentMenu = nil
103 end
104 self:ungrabMouse()
105end
106
107function UIPopupScrollMenu:onMousePress(mousePos, mouseButton)
108 -- clicks outside menu area destroys the menu
109 if not self:containsPoint(mousePos) then
110 self:destroy()
111 end
112 return true
113end
114
115function UIPopupScrollMenu:onKeyPress(keyCode, keyboardModifiers)
116 if keyCode == KeyEscape then
117 self:destroy()
118 return true
119 end
120 return false
121end
122
123-- close all menus when the window is resized
124local function onRootGeometryUpdate()
125 if currentMenu then
126 currentMenu:destroy()
127 end
128end
129connect(rootWidget, { onGeometryChange = onRootGeometryUpdate} )
130