--oo/resources/imagelist: image lists --Written by Cosmin Apreutesei. Public Domain. setfenv(1, require'winapi') require'winapi.itemlist' require'winapi.handlelist' require'winapi.imagelist' ImageLists = HandleList'himl' ImageList = subclass({ __defaults = { w=32, h=32, initial_size = 0, --if > 0 you'll have to use set() instead of add() grow_size = 1, --if > 1 you'll have to use set() instead of add() }, __flags_bitmask = bitmask{ masked = ILC_MASK, colors = { default = ILC_COLOR, ddb = ILC_COLORDDB, ['16bit'] = ILC_COLOR4, ['256bit'] = ILC_COLOR8, ['16bit'] = ILC_COLOR16, ['24bit'] = ILC_COLOR24, ['32bit'] = ILC_COLOR32, }, mirror = { none = 0, all = ILC_MIRROR, item = ILC_PERITEMMIRROR, }, preserve_size = ILC_ORIGINALSIZE, --vista+ }, }, ItemList) function ImageList:__init(t) if ffi.istype('HIMAGELIST', t) then self.himl = t else self.himl = ImageList_Create{ w = t.w or t[1], h = t.h or t[2], flags = self.__flags_bitmask:set(bit.bor(ILC_COLOR32, ILC_MASK), t), initial_size = t.initial_size or self.__defaults.initial_size, grow_size = t.grow_size or self.__defaults.grow_size, } if t.bk_color then self.bk_color = t.bk_color end end ImageLists:add(self) end function ImageList:destroy() ImageList_Destroy(self.himl) ImageLists:remove(self) self.himl = nil end function ImageList:set(i,t) if t.icon then ImageList_ReplaceIcon(self.himl, i, t.icon) elseif t.transparent_color then --there's no ImageList_ReplaceMasked ImageList_AddMasked(self.himl, t.image, t.transparent_color) ImageList_Copy(self.himl, i, self.count, ILCF_MOVE) ImageList_Remove(self.himl, self.count) else ImageList_Replace(self.himl, i, t.image, t.mask_image) end end function ImageList:move(to, from) if to == from then return end if to < from then for k=from,to+1,-1 do ImageList_Copy(self.himl, k, k-1, ILCF_SWAP) end else for k=to,from-1 do ImageList_Copy(self.himl, k, k+1, ILCF_SWAP) end end end function ImageList:add(i,t) --mask is an image or a color number if not t then i,t = nil,i end if t.icon then ImageList_AddIcon(self.himl, t.icon) elseif t.transparent_color then ImageList_AddMasked(self.himl, t.image, t.transparent_color) else ImageList_Add(self.himl, t.image, t.mask_image) end if i then self:move(self.count, i) end end function ImageList:remove(i) return ImageList_Remove(self.himl, i) end function ImageList:get(i, ILD) return {icon = ImageList_GetIcon(self.himl, i, ILD)} end function ImageList:clear() return ImageList_RemoveAll(self.himl) end function ImageList:get_count() return ImageList_GetImageCount(self.himl) end function ImageList:set_count(count) return ImageList_SetImageCount(self.himl, count) end function ImageList:get_bk_color() return ImageList_GetBkColor(self.himl) end function ImageList:set_bk_color(color) ImageList_SetBkColor(self.himl, color) end function ImageList:set_overlay(i, ioverlay) return ImageList_SetOverlayImage(self.himl, i, ioverlay) end function ImageList:get_size() local w,h = ImageList_GetIconSize(self.himl) return {w=w,h=h} end function ImageList:set_size(size) ImageList_SetIconSize(self.himl, size.w, size.h) end function ImageList:draw(i, dc, x, y, IDL) ImageList_Draw(self.himl, i, dc, x, y, IDL) end --showcase if not ... then require'winapi.showcase' require'winapi.icon' require'winapi.resource' local window = ShowcaseWindow{w=300,h=200} local m = ImageList{w=32,h=32,colors='32bit'} --m.bk_color = 234234 m:add{icon = LoadIconFromInstance(IDI_WARNING)} m:add{icon = LoadIconFromInstance(IDI_INFORMATION)} m:add(2, {icon = LoadIconFromInstance(IDI_ERROR)}) m:set(3, {icon = LoadIconFromInstance(IDI_ERROR)}) m.count = m.count + 1 print(m.count) print(m.size) function window:WM_PAINT() local p = ffi.new'PAINTSTRUCT' local hdc = C.BeginPaint(window.hwnd, p) for i=1,m.count do m:draw(i, hdc, 50+i*34, 50, ILD_NORMAL) end C.EndPaint(window.hwnd, p) end window:invalidate() MessageLoop() m:destroy() end