Added Table.OnSelected() and implemented it on Windows.

This commit is contained in:
Pietro Gagliardi 2014-08-20 21:21:45 -04:00
parent f60e888c38
commit b964c564e7
5 changed files with 35 additions and 30 deletions

View File

@ -62,6 +62,7 @@ windows
- OpenFile() not modal
- OpenFile() won't stop Do()
- labels draw over themselves
- fine-tune Table checkbox behavior (especially with regards to selection)
gtk+
- Area: figure out how Enter is processed in Entry
https://git.gnome.org/browse/gtk+/tree/gtk/gtkwindow.c#n1229

View File

@ -47,6 +47,9 @@ type Table interface {
// TODO bounds checking
Selected() int
Select(index int)
// OnSelected is an event that gets triggered after the selection in the Table changes in whatever way (item selected or item deselected).
OnSelected(func())
}
type tablebase struct {

View File

@ -25,39 +25,11 @@ static void handle(HWND hwnd, WPARAM wParam, LPARAM lParam, void (*handler)(void
(*handler)(data, ht.iItem, ht.iSubItem);
}
static struct {int code; char *name;} lvnnames[] = {
{ LVN_ITEMCHANGING, "LVN_ITEMCHANGING" },
{ LVN_ITEMCHANGED, "LVN_ITEMCHANGED" },
{ LVN_INSERTITEM, "LVN_INSERTITEM" },
{ LVN_DELETEITEM, "LVN_DELETEITEM" },
{ LVN_DELETEALLITEMS, "LVN_DELETEALLITEMS" },
{ LVN_BEGINLABELEDITA, "LVN_BEGINLABELEDITA" },
{ LVN_BEGINLABELEDITW, "LVN_BEGINLABELEDITW" },
{ LVN_ENDLABELEDITA, "LVN_ENDLABELEDITA" },
{ LVN_ENDLABELEDITW, "LVN_ENDLABELEDITW" },
{ LVN_COLUMNCLICK, "LVN_COLUMNCLICK" },
{ LVN_BEGINDRAG, "LVN_BEGINDRAG" },
{ LVN_BEGINRDRAG, "LVN_BEGINRDRAG" },
//{ LVN_ODCACHEHINT, "LVN_ODCACHEHINT" },
{ LVN_ODFINDITEMA, "LVN_ODFINDITEMA" },
{ LVN_ODFINDITEMW, "LVN_ODFINDITEMW" },
{ LVN_ITEMACTIVATE, "LVN_ITEMACTIVATE" },
{ LVN_ODSTATECHANGED, "LVN_ODSTATECHANGED" },
{ LVN_SETDISPINFOA, "LVN_SETDISPINFOA" },
{ LVN_SETDISPINFOW, "LVN_SETDISPINFOW" },
//{ LVN_KEYDOWN, "LVN_KEYDOWN" },
{ LVN_MARQUEEBEGIN, "LVN_MARQUEEBEGIN" },
{ LVN_GETINFOTIPA, "LVN_GETINFOTIPA" },
{ LVN_GETINFOTIPW, "LVN_GETINFOTIPW" },
{ LVN_BEGINSCROLL, "LVN_BEGINSCROLL" },
{ LVN_ENDSCROLL, "LVN_ENDSCROLL" },
{ 0, NULL },
};
static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data)
{
NMHDR *nmhdr = (NMHDR *) lParam;
NMLVDISPINFOW *fill = (NMLVDISPINFO *) lParam;
NMLISTVIEW *nlv = (NMLISTVIEW *) lParam;
switch (uMsg) {
case msgNOTIFY:
@ -65,8 +37,15 @@ static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
case LVN_GETDISPINFO:
tableGetCell((void *) data, &(fill->item));
return 0;
case LVN_ITEMCHANGED:
if ((nlv->uChanged & LVIF_STATE) == 0)
break;
// if both old and new states have the same value for the selected bit, then the selection state did not change, regardless of selected or deselected
if ((nlv->uOldState & LVIS_SELECTED) == (nlv->uNewState & LVIS_SELECTED))
break;
tableOnSelected((void *) data);
return 0;
}
for(int i=0;lvnnames[i].code!=0;i++)if(lvnnames[i].code==nmhdr->code)printf("%s\n",lvnnames[i].name);
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
case WM_MOUSEMOVE:
handle(hwnd, wParam, lParam, tableSetHot, (void *) data);

View File

@ -20,6 +20,7 @@ type table struct {
hotcol C.int
pushedrow C.int
pushedcol C.int
selected *event
}
func finishNewTable(b *tablebase, ty reflect.Type) Table {
@ -32,6 +33,7 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table {
hotcol: -1,
pushedrow: -1,
pushedcol: -1,
selected: newEvent(),
}
C.setTableSubclass(t._hwnd, unsafe.Pointer(t))
// LVS_EX_FULLROWSELECT gives us selection across the whole row, not just the leftmost column; this makes the list view work like on other platforms
@ -74,6 +76,10 @@ func (t *table) Select(index int) {
C.tableSelectItem(t._hwnd, C.intptr_t(index))
}
func (t *table) OnSelected(f func()) {
t.selected.set(f)
}
//export tableGetCell
func tableGetCell(data unsafe.Pointer, item *C.LVITEMW) {
t := (*table)(data)
@ -181,6 +187,12 @@ func tableToggled(data unsafe.Pointer, row C.int, col C.int) {
panic(fmt.Errorf("tableSetHot() on non-checkbox at (%d, %d)", row, col))
}
//export tableOnSelected
func tableOnSelected(data unsafe.Pointer) {
t := (*table)(data)
t.selected.fire()
}
func (t *table) hwnd() C.HWND {
return t._hwnd
}

View File

@ -140,6 +140,16 @@ func (tw *testwin) make(done chan struct{}) {
*idq = tw.icons
tw.icontbl.Unlock()
tw.icontbl.LoadImageList(tw.il)
tw.icontbl.OnSelected(func() {
s := fmt.Sprintf("%d ", tw.icontbl.Selected())
tw.icontbl.RLock()
defer tw.icontbl.RUnlock()
idq := tw.icontbl.Data().(*[]icon)
for _, v := range *idq {
s += strings.ToUpper(fmt.Sprintf("%v", v.Bool)[0:1]) + " "
}
tw.w.SetTitle(s)
})
tw.t.Append("Image List Table", tw.icontbl)
tw.group2 = NewGroup("Group", NewButton("Button in Group"))
tw.t.Append("Filled Group", tw.group2)