From c89b7a606ef03a7775c1985baf6774077d9a577d Mon Sep 17 00:00:00 2001 From: Angelo Haller Date: Wed, 20 Jun 2018 10:47:57 -0500 Subject: [PATCH] Add new API function to set table row double click callback. uiTableOnRowDoubleClicked Implementations provided for darwin, unix, and windows. --- darwin/table.h | 2 ++ darwin/table.m | 26 ++++++++++++++++++++++++++ test/page16.c | 7 +++++++ ui.h | 6 ++++++ unix/table.c | 24 ++++++++++++++++++++++++ windows/table.cpp | 22 ++++++++++++++++++++++ windows/table.hpp | 2 ++ 7 files changed, 89 insertions(+) diff --git a/darwin/table.h b/darwin/table.h index 4146ab71a..bd285f7db 100644 --- a/darwin/table.h +++ b/darwin/table.h @@ -16,6 +16,8 @@ struct uiTable { uiprivScrollViewData *d; int backgroundColumn; uiTableModel *m; + void (*onRowDoubleClicked)(uiTable *, int, void *); + void *onRowDoubleClickedData; }; // tablecolumn.m diff --git a/darwin/table.m b/darwin/table.m index 1bdc7f8da..7f0df35b1 100644 --- a/darwin/table.m +++ b/darwin/table.m @@ -16,6 +16,7 @@ @interface uiprivTableView : NSTableView { uiTableModel *uiprivM; } - (id)initWithFrame:(NSRect)r uiprivT:(uiTable *)t uiprivM:(uiTableModel *)m; +- (void)onDoubleAction:(id)sender; @end @implementation uiprivTableView @@ -30,6 +31,17 @@ - (id)initWithFrame:(NSRect)r uiprivT:(uiTable *)t uiprivM:(uiTableModel *)m return self; } +- (void)onDoubleAction:(id)sender +{ + uiTable *t = self->uiprivT; + NSInteger row = [self clickedRow]; + + if (row < 0) + return; + + (*(t->onRowDoubleClicked))(t, row, t->onRowDoubleClickedData); +} + // TODO is this correct for overflow scrolling? static void setBackgroundColor(uiprivTableView *t, NSTableRowView *rv, NSInteger row) { @@ -170,6 +182,17 @@ static void uiTableDestroy(uiControl *c) uiFreeControl(uiControl(t)); } +static void defaultOnRowDoubleClicked(uiTable *table, int row, void *data) +{ + // do nothing +} + +void uiTableOnRowDoubleClicked(uiTable *t, void (*f)(uiTable *, int, void *), void *data) +{ + t->onRowDoubleClicked = f; + t->onRowDoubleClickedData = data; +} + uiTable *uiNewTable(uiTableParams *p) { uiTable *t; @@ -198,6 +221,9 @@ static void uiTableDestroy(uiControl *c) [t->tv setAllowsTypeSelect:YES]; // TODO floatsGroupRows — do we even allow group rows? + uiTableOnRowDoubleClicked(t, defaultOnRowDoubleClicked, NULL); + [t->tv setDoubleAction: @selector(onDoubleAction:)]; + memset(&sp, 0, sizeof (uiprivScrollViewCreateParams)); sp.DocumentView = t->tv; // this is what Interface Builder sets it to diff --git a/test/page16.c b/test/page16.c index f28ba3c7b..e504013c0 100644 --- a/test/page16.c +++ b/test/page16.c @@ -98,6 +98,11 @@ static void modelSetCellValue(uiTableModelHandler *mh, uiTableModel *m, int row, checkStates[row] = uiTableValueInt(val); } +static void onRowDoubleClicked(uiTable *table, int row, void *data) +{ + printf("Double clicked row %d\n", row); +} + static uiTableModel *m; uiBox *makePage16(void) @@ -152,6 +157,8 @@ uiBox *makePage16(void) uiTableAppendProgressBarColumn(t, "Progress Bar", 8); + uiTableOnRowDoubleClicked(t, onRowDoubleClicked, NULL); + return page16; } diff --git a/ui.h b/ui.h index 40aea9498..fb6767204 100644 --- a/ui.h +++ b/ui.h @@ -1455,6 +1455,12 @@ _UI_EXTERN void uiTableAppendButtonColumn(uiTable *t, int buttonModelColumn, int buttonClickableModelColumn); +// uiTableOnRowDoubleClicked sets a callback to be called when the user +// double clicks a table row. +_UI_EXTERN void uiTableOnRowDoubleClicked(uiTable *t, + void (*f)(uiTable *t, int row, void *data), + void *data); + // uiNewTable() creates a new uiTable with the specified parameters. _UI_EXTERN uiTable *uiNewTable(uiTableParams *params); diff --git a/unix/table.c b/unix/table.c index e29ada07c..6820a11a6 100644 --- a/unix/table.c +++ b/unix/table.c @@ -18,6 +18,8 @@ struct uiTable { // TODO document this properly GHashTable *indeterminatePositions; guint indeterminateTimer; + void (*onRowDoubleClicked)(uiTable *, int, void *); + void *onRowDoubleClickedData; }; // use the same size as GtkFileChooserWidget's treeview @@ -494,6 +496,25 @@ static void uiTableDestroy(uiControl *c) uiFreeControl(uiControl(t)); } +static void onRowDoubleClicked(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) +{ + uiTable *t = uiTable(data); + gint row = gtk_tree_path_get_indices(path)[0]; + + (*(t->onRowDoubleClicked))(t, row, t->onRowDoubleClickedData); +} + +static void defaultOnRowDoubleClicked(uiTable *table, int row, void *data) +{ + // do nothing +} + +void uiTableOnRowDoubleClicked(uiTable *t, void (*f)(uiTable *, int, void *), void *data) +{ + t->onRowDoubleClicked = f; + t->onRowDoubleClickedData = data; +} + uiTable *uiNewTable(uiTableParams *p) { uiTable *t; @@ -511,7 +532,10 @@ uiTable *uiNewTable(uiTableParams *p) t->treeWidget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(t->model)); t->tv = GTK_TREE_VIEW(t->treeWidget); + // TODO set up t->tv + uiTableOnRowDoubleClicked(t, defaultOnRowDoubleClicked, NULL); + g_signal_connect(t->tv, "row-activated", G_CALLBACK(onRowDoubleClicked), t); gtk_container_add(t->scontainer, t->treeWidget); // and make the tree view visible; only the scrolled window's visibility is controlled by libui diff --git a/windows/table.cpp b/windows/table.cpp index 85a51c1a3..b6a59e952 100644 --- a/windows/table.cpp +++ b/windows/table.cpp @@ -79,6 +79,17 @@ void uiTableModelRowDeleted(uiTableModel *m, int oldIndex) } } +static void defaultOnRowDoubleClicked(uiTable *table, int row, void *data) +{ + // do nothing +} + +void uiTableOnRowDoubleClicked(uiTable *t, void (*f)(uiTable *, int, void *), void *data) +{ + t->onRowDoubleClicked = f; + t->onRowDoubleClickedData = data; +} + uiTableModelHandler *uiprivTableModelHandler(uiTableModel *m) { return m->mh; @@ -278,6 +289,15 @@ static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult) } return TRUE; #endif + case NM_DBLCLK: + { + LVHITTESTINFO ht = {}; + ht.pt = ((NMITEMACTIVATE *)nmhdr)->ptAction; + if (ListView_SubItemHitTest(t->hwnd, &ht) == -1) + return FALSE; + (*(t->onRowDoubleClicked))(t, ht.iItem, t->onRowDoubleClickedData); + return TRUE; + } case LVN_ITEMCHANGED: { NMLISTVIEW *nm = (NMLISTVIEW *) nmhdr; @@ -518,5 +538,7 @@ uiTable *uiNewTable(uiTableParams *p) if (SetWindowSubclass(t->hwnd, tableSubProc, 0, (DWORD_PTR) t) == FALSE) logLastError(L"SetWindowSubclass()"); + uiTableOnRowDoubleClicked(t, defaultOnRowDoubleClicked, NULL); + return t; } diff --git a/windows/table.hpp b/windows/table.hpp index 71946d623..4528d73b4 100644 --- a/windows/table.hpp +++ b/windows/table.hpp @@ -40,6 +40,8 @@ struct uiTable { HWND edit; int editedItem; int editedSubitem; + void (*onRowDoubleClicked)(uiTable *, int, void *); + void *onRowDoubleClickedData; }; extern int uiprivTableProgress(uiTable *t, int item, int subitem, int modelColumn, LONG *pos);