--oo/controls/waitemlist: accelerator item list --Written by Cosmin Apreutesei. Public Domain. setfenv(1, require'winapi') require'winapi.itemlist' require'winapi.accelerator' local modifier_masks = { shift = FSHIFT, control = FCONTROL, ctrl = FCONTROL, alt = FALT, } local function parse_hotkey(s) --parse hotkeys like "shift + alt + F5" or "ctrl + C"; note: say "C" instead of "shift + c" local key, modifiers = nil, 0 for k in s:gmatch'([^%+]+)' do k = trim(k) local m = modifier_masks[k:lower()] if m then modifiers = bit.bor(modifiers, m) elseif #k == 1 then key = k else key = flags('VK_'..k:upper()) end end assert(key, 'invalid hotkey') return key, modifiers end WAItemList = class(ItemList) function WAItemList:__init(window) WAItemList.__index.__init(self, window) self.__items = {} end function WAItemList:checkrange(i) assert(i >= 1 and i <= #self.__items + 1, 'index out of range') end function WAItemList:__changed() if self.haccel then DestroyAcceleratorTable(self.haccel) self.haccel = nil end local t = {} for i,v in ipairs(self.__items) do local key, modifiers = parse_hotkey(v.hotkey) t[i] = ACCEL{id = i, key = key, modifiers = modifiers} end self.haccel = CreateAcceleratorTable(t) end function WAItemList:add(i, item) if not item then i,item = nil,i end --i is optional if i then self:checkrange(i) table.insert(self.__items, i, item) else table.insert(self.__items, item) end self:__changed() end function WAItemList:add_items(items) if not items then return end for i=1,#items do table.insert(self.__items, items[i]) end self:__changed() end function WAItemList:remove(i) self:checkrange(i) table.remove(self.__items, i) self:__changed() end function WAItemList:set(i, item) self:checkrange(i) self.__items[i] = item self:__changed() end function WAItemList:get(i) self:checkrange(i) return self.__items[i] end function WAItemList:get_count() return #self.__items end function WAItemList:clear() self.__items = {} self:__changed() end function WAItemList:WM_COMMAND(i) self:checkrange(i) self.__items[i].handler(self.window) end