Added image lists to Tables and added them to the Windows backend... mostly. There are a few kinks to work out...
This commit is contained in:
parent
5d69bc2534
commit
d5f9c237b7
|
@ -36,10 +36,10 @@ HIMAGELIST newImageList(int width, int height)
|
||||||
return il;
|
return il;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addImage(HIMAGELIST il, HBITMAP bitmap, int origwid, int oright, int width, int height)
|
void addImage(HIMAGELIST il, HWND hwnd, HBITMAP bitmap, int origwid, int oright, int width, int height)
|
||||||
{
|
{
|
||||||
BOOL wasScaled = FALSE;
|
BOOL wasScaled = FALSE;
|
||||||
HDC scaledDC, origDC;
|
HDC winDC, scaledDC, origDC;
|
||||||
HBITMAP scaled;
|
HBITMAP scaled;
|
||||||
HBITMAP prevscaled, prevorig;
|
HBITMAP prevscaled, prevorig;
|
||||||
|
|
||||||
|
@ -49,33 +49,38 @@ void addImage(HIMAGELIST il, HBITMAP bitmap, int origwid, int oright, int width,
|
||||||
goto noscale;
|
goto noscale;
|
||||||
}
|
}
|
||||||
wasScaled = TRUE;
|
wasScaled = TRUE;
|
||||||
scaledDC = GetDC(NULL);
|
winDC = GetDC(hwnd);
|
||||||
|
if (winDC == NULL)
|
||||||
|
xpanic("error getting DC for window", GetLastError());
|
||||||
|
origDC = CreateCompatibleDC(winDC);
|
||||||
|
if (winDC == NULL)
|
||||||
|
xpanic("error getting DC for original ImageList bitmap", GetLastError());
|
||||||
|
prevorig = SelectObject(origDC, bitmap);
|
||||||
|
if (prevorig == NULL)
|
||||||
|
xpanic("error selecting original ImageList bitmap into DC", GetLastError());
|
||||||
|
scaledDC = CreateCompatibleDC(origDC);
|
||||||
if (scaledDC == NULL)
|
if (scaledDC == NULL)
|
||||||
xpanic("error getting screen DC for scaled ImageList bitmap", GetLastError());
|
xpanic("error getting DC for scaled ImageList bitmap", GetLastError());
|
||||||
scaled = CreateCompatibleBitmap(scaledDC, width, height);
|
scaled = CreateCompatibleBitmap(origDC, width, height);
|
||||||
if (scaled == NULL)
|
if (scaled == NULL)
|
||||||
xpanic("error creating scaled ImageList bitmap", GetLastError());
|
xpanic("error creating scaled ImageList bitmap", GetLastError());
|
||||||
prevscaled = SelectObject(scaledDC, scaled);
|
prevscaled = SelectObject(scaledDC, scaled);
|
||||||
if (prevscaled == NULL)
|
if (prevscaled == NULL)
|
||||||
xpanic("error selecting scaled ImageList bitmap into screen DC", GetLastError());
|
xpanic("error selecting scaled ImageList bitmap into DC", GetLastError());
|
||||||
origDC = GetDC(NULL);
|
|
||||||
if (origDC == NULL)
|
|
||||||
xpanic("error getting screen DC for original ImageList bitmap", GetLastError());
|
|
||||||
prevorig = SelectObject(origDC, bitmap);
|
|
||||||
if (prevorig == NULL)
|
|
||||||
xpanic("error selecting original ImageList bitmap into screen DC", GetLastError());
|
|
||||||
if (StretchBlt(scaledDC, 0, 0, width, height,
|
if (StretchBlt(scaledDC, 0, 0, width, height,
|
||||||
origDC, 0, 0, origwid, oright,
|
origDC, 0, 0, origwid, oright,
|
||||||
SRCCOPY) == 0)
|
SRCCOPY) == 0)
|
||||||
xpanic("error scaling ImageList bitmap down", GetLastError());
|
xpanic("error scaling ImageList bitmap down", GetLastError());
|
||||||
if (SelectObject(origDC, prevorig) != bitmap)
|
if (SelectObject(origDC, prevorig) != bitmap)
|
||||||
xpanic("error selecting previous bitmap into original image's screen DC", GetLastError());
|
xpanic("error selecting previous bitmap into original image's DC", GetLastError());
|
||||||
if (DeleteDC(origDC) == 0)
|
if (DeleteDC(origDC) == 0)
|
||||||
xpanic("error deleting original image's screen DC", GetLastError());
|
xpanic("error deleting original image's DC", GetLastError());
|
||||||
if (SelectObject(scaledDC, prevscaled) != scaled)
|
if (SelectObject(scaledDC, prevscaled) != scaled)
|
||||||
xpanic("error selecting previous bitmap into scaled image's screen DC", GetLastError());
|
xpanic("error selecting previous bitmap into scaled image's DC", GetLastError());
|
||||||
if (DeleteDC(scaledDC) == 0)
|
if (DeleteDC(scaledDC) == 0)
|
||||||
xpanic("error deleting scaled image's screen DC", GetLastError());
|
xpanic("error deleting scaled image's DC", GetLastError());
|
||||||
|
if (DeleteDC(winDC) == 0)
|
||||||
|
xpanic("error deleting window DC", GetLastError());
|
||||||
|
|
||||||
noscale:
|
noscale:
|
||||||
if ((*fv_ImageList_Add)(il, scaled, NULL) == -1)
|
if ((*fv_ImageList_Add)(il, scaled, NULL) == -1)
|
||||||
|
@ -84,3 +89,10 @@ noscale:
|
||||||
if (DeleteObject(scaled) == 0)
|
if (DeleteObject(scaled) == 0)
|
||||||
xpanic("error deleting scaled bitmap", GetLastError());
|
xpanic("error deleting scaled bitmap", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void applyImageList(HWND hwnd, UINT uMsg, WPARAM wParam, HIMAGELIST il)
|
||||||
|
{
|
||||||
|
if (SendMessageW(hwnd, uMsg, wParam, (LPARAM) il) == (LRESULT) NULL)
|
||||||
|
;// xpanic("error setting image list", GetLastError());
|
||||||
|
// TODO free old one here if any
|
||||||
|
}
|
||||||
|
|
|
@ -31,15 +31,15 @@ func (i *imagelist) Len() ImageIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
type imageListApply interface {
|
type imageListApply interface {
|
||||||
apply()
|
apply(C.HWND, C.UINT, C.WPARAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imagelist) apply() {
|
func (i *imagelist) apply(hwnd C.HWND, uMsg C.UINT, wParam C.WPARAM) {
|
||||||
width := C.GetSystemMetrics(C.SM_CXSMICON)
|
width := C.GetSystemMetrics(C.SM_CXSMICON)
|
||||||
height := C.GetSystemMetrics(C.SM_CYSMICON)
|
height := C.GetSystemMetrics(C.SM_CYSMICON)
|
||||||
il := C.newImageList(width, height)
|
il := C.newImageList(width, height)
|
||||||
for index := range i.list {
|
for index := range i.list {
|
||||||
C.addImage(il, i.list[index], C.int(i.width[index]), C.int(i.height[index]), width, height)
|
C.addImage(il, hwnd, i.list[index], C.int(i.width[index]), C.int(i.height[index]), width, height)
|
||||||
}
|
}
|
||||||
// TODO do stuff
|
C.applyImageList(hwnd, uMsg, wParam, il)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,10 @@ type Table interface {
|
||||||
// The returned value will contain an object of type pointer to slice of some structure; use a type assertion to get the properly typed object out.
|
// The returned value will contain an object of type pointer to slice of some structure; use a type assertion to get the properly typed object out.
|
||||||
// Do not call this outside a Lock()..Unlock() or RLock()..RUnlock() pair.
|
// Do not call this outside a Lock()..Unlock() or RLock()..RUnlock() pair.
|
||||||
Data() interface{}
|
Data() interface{}
|
||||||
|
|
||||||
|
// LoadImageList loads the given ImageList into the Table.
|
||||||
|
// This function copies; changes to the ImageList made later will not be reflected by the Table.
|
||||||
|
LoadImageList(ImageList)
|
||||||
}
|
}
|
||||||
|
|
||||||
type tablebase struct {
|
type tablebase struct {
|
||||||
|
|
|
@ -15,7 +15,7 @@ static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
case msgNOTIFY:
|
case msgNOTIFY:
|
||||||
switch (nmhdr->code) {
|
switch (nmhdr->code) {
|
||||||
case LVN_GETDISPINFO:
|
case LVN_GETDISPINFO:
|
||||||
tableGetCellText((void *) data, fill->item.iItem, fill->item.iSubItem, &(fill->item.pszText));
|
tableGetCell((void *) data, &(fill->item));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
||||||
|
|
|
@ -49,15 +49,28 @@ func (t *table) Unlock() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
//export tableGetCellText
|
func (t *table) LoadImageList(il ImageList) {
|
||||||
func tableGetCellText(data unsafe.Pointer, row C.int, col C.int, str *C.LPWSTR) {
|
il.apply(t._hwnd, C.LVM_SETIMAGELIST, C.LVSIL_SMALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export tableGetCell
|
||||||
|
func tableGetCell(data unsafe.Pointer, item *C.LVITEMW) {
|
||||||
t := (*table)(data)
|
t := (*table)(data)
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
d := reflect.Indirect(reflect.ValueOf(t.data))
|
d := reflect.Indirect(reflect.ValueOf(t.data))
|
||||||
datum := d.Index(int(row)).Field(int(col))
|
datum := d.Index(int(item.iItem)).Field(int(item.iSubItem))
|
||||||
|
switch d := datum.Interface().(type) {
|
||||||
|
case ImageIndex:
|
||||||
|
item.mask |= C.LVIF_IMAGE
|
||||||
|
item.mask &^= C.LVIF_TEXT
|
||||||
|
item.iImage = C.int(d)
|
||||||
|
default:
|
||||||
|
item.mask |= C.LVIF_TEXT
|
||||||
|
item.mask &^= C.LVIF_IMAGE
|
||||||
s := fmt.Sprintf("%v", datum)
|
s := fmt.Sprintf("%v", datum)
|
||||||
*str = toUTF16(s)
|
item.pszText = toUTF16(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the column autoresize policy is simple:
|
// the column autoresize policy is simple:
|
||||||
|
|
|
@ -117,6 +117,7 @@ extern HWND newArea(void *);
|
||||||
// imagelist_windows.c
|
// imagelist_windows.c
|
||||||
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);
|
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);
|
||||||
extern HIMAGELIST newImageList(int, int);
|
extern HIMAGELIST newImageList(int, int);
|
||||||
extern void addImage(HIMAGELIST, HBITMAP, int, int, int, int);
|
extern void addImage(HIMAGELIST, HWND, HBITMAP, int, int, int, int);
|
||||||
|
extern void applyImageList(HWND, UINT, WPARAM, HIMAGELIST);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,6 +34,7 @@ type testwin struct {
|
||||||
w Window
|
w Window
|
||||||
icons []icon
|
icons []icon
|
||||||
il ImageList
|
il ImageList
|
||||||
|
icontbl Table
|
||||||
group2 Group
|
group2 Group
|
||||||
group Group
|
group Group
|
||||||
grid Grid
|
grid Grid
|
||||||
|
@ -74,6 +75,13 @@ func (tw *testwin) make(done chan struct{}) {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
tw.icons, tw.il = readIcons()
|
tw.icons, tw.il = readIcons()
|
||||||
|
tw.icontbl = NewTable(reflect.TypeOf(icon{}))
|
||||||
|
tw.icontbl.Lock()
|
||||||
|
idq := tw.icontbl.Data().(*[]icon)
|
||||||
|
*idq = tw.icons
|
||||||
|
tw.icontbl.Unlock()
|
||||||
|
tw.icontbl.LoadImageList(tw.il)
|
||||||
|
tw.t.Append("Image List Table", tw.icontbl)
|
||||||
tw.group2 = NewGroup("Group", NewButton("Button in Group"))
|
tw.group2 = NewGroup("Group", NewButton("Button in Group"))
|
||||||
tw.t.Append("Filled Group", tw.group2)
|
tw.t.Append("Filled Group", tw.group2)
|
||||||
tw.group = NewGroup("Group", NewVerticalStack(NewCheckbox("Checkbox in Group")))
|
tw.group = NewGroup("Group", NewVerticalStack(NewCheckbox("Checkbox in Group")))
|
||||||
|
|
Loading…
Reference in New Issue