opus/sys/modules/opus/ui/components/DropMenu.lua

107 lines
2.4 KiB
Lua

local class = require('opus.class')
local UI = require('opus.ui')
local Util = require('opus.util')
UI.DropMenu = class(UI.MenuBar)
UI.DropMenu.defaults = {
UIElement = 'DropMenu',
backgroundColor = 'white',
buttonClass = 'DropMenuItem',
}
function UI.DropMenu:layout()
UI.MenuBar.layout(self)
local maxWidth = 1
for y,child in ipairs(self.children) do
child.x = 1
child.y = y
if #(child.text or '') > maxWidth then
maxWidth = #child.text
end
end
for _,child in ipairs(self.children) do
child.width = maxWidth + 2
if child.spacer then
child.inactive = true
child.text = string.rep('-', child.width - 2)
end
end
self.height = #self.children + 1
self.width = maxWidth + 2
if self.x + self.width > self.parent.width then
self.x = self.parent.width - self.width + 1
end
self:reposition(self.x, self.y, self.width, self.height)
end
function UI.DropMenu:enable()
local menuBar = self.parent:find(self.menuUid)
local hasActive
for _,c in pairs(self.children) do
if not c.spacer and menuBar then
c.inactive = not menuBar:getActive(c)
end
if not c.inactive then
hasActive = true
end
end
-- jump through a lot of hoops if all selections are inactive
-- there's gotta be a better way
-- lots of exception code just to handle drop menus
self.focus = not hasActive and function() end
UI.Window.enable(self)
if self.focus then
self:setFocus(self)
else
self:focusFirst()
end
self:draw()
end
function UI.DropMenu:disable()
UI.Window.disable(self)
self:remove()
end
function UI.DropMenu:eventHandler(event)
if event.type == 'focus_lost' and self.enabled then
if not (Util.contains(self.children, event.focused) or event.focused == self) then
self:disable()
end
elseif event.type == 'mouse_out' and self.enabled then
self:disable()
self:setFocus(self.parent:find(self.lastFocus))
else
return UI.MenuBar.eventHandler(self, event)
end
return true
end
function UI.DropMenu.example()
return UI.MenuBar {
buttons = {
{ text = 'File', dropdown = {
{ text = 'Run', event = 'run' },
{ text = 'Shell s', event = 'shell' },
{ spacer = true },
{ text = 'Quit ^q', event = 'quit' },
} },
{ text = 'Edit', dropdown = {
{ text = 'Copy', event = 'run' },
{ text = 'Paste s', event = 'shell' },
} },
{ text = '\187',
x = -3,
dropdown = {
{ text = 'Associations', event = 'associate' },
} },
}
}
end