diff --git a/common/control.c b/common/control.c index 98cb94aa..83254ef2 100644 --- a/common/control.c +++ b/common/control.c @@ -57,6 +57,11 @@ void uiControlDisable(uiControl *c) (*(c->Disable))(c); } +void uiControlSetFocus(uiControl *c) +{ + (*(c->SetFocus))(c); +} + #define uiprivControlSignature 0x7569436F uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr) diff --git a/darwin/box.m b/darwin/box.m index 72b5a71d..f4763e44 100644 --- a/darwin/box.m +++ b/darwin/box.m @@ -380,6 +380,7 @@ uiDarwinControlDefaultHide(uiBox, view) uiDarwinControlDefaultEnabled(uiBox, view) uiDarwinControlDefaultEnable(uiBox, view) uiDarwinControlDefaultDisable(uiBox, view) +uiDarwinControlDefaultSetFocus(uiBox, view) static void uiBoxSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/darwin/form.m b/darwin/form.m index af50e363..5ea481be 100644 --- a/darwin/form.m +++ b/darwin/form.m @@ -482,6 +482,7 @@ uiDarwinControlDefaultHide(uiForm, view) uiDarwinControlDefaultEnabled(uiForm, view) uiDarwinControlDefaultEnable(uiForm, view) uiDarwinControlDefaultDisable(uiForm, view) +uiDarwinControlDefaultSetFocus(uiForm, view) static void uiFormSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/darwin/grid.m b/darwin/grid.m index 4cbf34c2..5e828c65 100644 --- a/darwin/grid.m +++ b/darwin/grid.m @@ -694,6 +694,7 @@ uiDarwinControlDefaultHide(uiGrid, view) uiDarwinControlDefaultEnabled(uiGrid, view) uiDarwinControlDefaultEnable(uiGrid, view) uiDarwinControlDefaultDisable(uiGrid, view) +uiDarwinControlDefaultSetFocus(uiGrid, view) static void uiGridSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/darwin/group.m b/darwin/group.m index 2cfcdf47..8268dca9 100644 --- a/darwin/group.m +++ b/darwin/group.m @@ -43,6 +43,7 @@ uiDarwinControlDefaultHide(uiGroup, box) uiDarwinControlDefaultEnabled(uiGroup, box) uiDarwinControlDefaultEnable(uiGroup, box) uiDarwinControlDefaultDisable(uiGroup, box) +uiDarwinControlDefaultSetFocus(uiGroup, box) static void uiGroupSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/darwin/tab.m b/darwin/tab.m index 28c38318..35c8dd96 100644 --- a/darwin/tab.m +++ b/darwin/tab.m @@ -115,6 +115,7 @@ uiDarwinControlDefaultHide(uiTab, tabview) uiDarwinControlDefaultEnabled(uiTab, tabview) uiDarwinControlDefaultEnable(uiTab, tabview) uiDarwinControlDefaultDisable(uiTab, tabview) +uiDarwinControlDefaultSetFocus(uiTab, tabview) static void uiTabSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/darwin/window.m b/darwin/window.m index 1a048207..e052b7df 100644 --- a/darwin/window.m +++ b/darwin/window.m @@ -189,6 +189,7 @@ static void uiWindowHide(uiControl *c) uiDarwinControlDefaultEnabled(uiWindow, window) uiDarwinControlDefaultEnable(uiWindow, window) uiDarwinControlDefaultDisable(uiWindow, window) +uiDarwinControlDefaultSetFocus(uiWindow, window) static void uiWindowSyncEnableState(uiDarwinControl *c, int enabled) { diff --git a/examples/controlgallery/main.c b/examples/controlgallery/main.c index 4ba5cc8a..526eefd3 100644 --- a/examples/controlgallery/main.c +++ b/examples/controlgallery/main.c @@ -17,6 +17,13 @@ static int onShouldQuit(void *data) return 1; } +static uiEntry *focusable = NULL; +static void wideOnClicked(uiButton *b, void *data) +{ + if (focusable) + uiControlSetFocus(uiControl(focusable)); +} + static uiControl *makeBasicControlsPage(void) { uiBox *vbox; @@ -42,6 +49,7 @@ static uiControl *makeBasicControlsPage(void) uiBoxAppend(hbox, uiControl(btn), 0); + uiButtonOnClicked(btn, wideOnClicked, NULL); uiBoxAppend(vbox, uiControl(uiNewLabel("This is a label. Right now, labels can only span one line.")), @@ -59,9 +67,12 @@ static uiControl *makeBasicControlsPage(void) uiFormSetPadded(entryForm, 1); uiGroupSetChild(group, uiControl(entryForm)); + + focusable = uiNewEntry(); + uiFormAppend(entryForm, "Entry", - uiControl(uiNewEntry()), + uiControl(focusable), 0); uiFormAppend(entryForm, "Password Entry", diff --git a/ui.h b/ui.h index 9ce47d34..022178e4 100644 --- a/ui.h +++ b/ui.h @@ -97,6 +97,7 @@ struct uiControl { int (*Enabled)(uiControl *); void (*Enable)(uiControl *); void (*Disable)(uiControl *); + void (*SetFocus)(uiControl *); }; // TOOD add argument names to all arguments #define uiControl(this) ((uiControl *) (this)) @@ -111,6 +112,7 @@ _UI_EXTERN void uiControlHide(uiControl *); _UI_EXTERN int uiControlEnabled(uiControl *); _UI_EXTERN void uiControlEnable(uiControl *); _UI_EXTERN void uiControlDisable(uiControl *); +_UI_EXTERN void uiControlSetFocus(uiControl *); _UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr); _UI_EXTERN void uiFreeControl(uiControl *); diff --git a/ui_darwin.h b/ui_darwin.h index c9c6ad54..440204fe 100644 --- a/ui_darwin.h +++ b/ui_darwin.h @@ -100,6 +100,11 @@ _UI_EXTERN void uiDarwinControlChildVisibilityChanged(uiDarwinControl *); uiDarwinControl(c)->enabled = NO; \ uiDarwinControlSyncEnableState(uiDarwinControl(c), uiControlEnabledToUser(c)); \ } +#define uiDarwinControlDefaultSetFocus(type, handlefield) \ + static void type ## SetFocus(uiControl *c) \ + { \ + return; \ + } #define uiDarwinControlDefaultSyncEnableState(type, handlefield) \ static void type ## SyncEnableState(uiDarwinControl *c, int enabled) \ { \ @@ -159,6 +164,7 @@ _UI_EXTERN void uiDarwinControlChildVisibilityChanged(uiDarwinControl *); uiDarwinControlDefaultEnabled(type, handlefield) \ uiDarwinControlDefaultEnable(type, handlefield) \ uiDarwinControlDefaultDisable(type, handlefield) \ + uiDarwinControlDefaultSetFocus(type, handlefield) \ uiDarwinControlDefaultSyncEnableState(type, handlefield) \ uiDarwinControlDefaultSetSuperview(type, handlefield) \ uiDarwinControlDefaultHugsTrailingEdge(type, handlefield) \ @@ -186,6 +192,7 @@ _UI_EXTERN void uiDarwinControlChildVisibilityChanged(uiDarwinControl *); uiControl(var)->Enabled = type ## Enabled; \ uiControl(var)->Enable = type ## Enable; \ uiControl(var)->Disable = type ## Disable; \ + uiControl(var)->SetFocus = type ## SetFocus; \ uiDarwinControl(var)->SyncEnableState = type ## SyncEnableState; \ uiDarwinControl(var)->SetSuperview = type ## SetSuperview; \ uiDarwinControl(var)->HugsTrailingEdge = type ## HugsTrailingEdge; \ diff --git a/ui_unix.h b/ui_unix.h index ed019260..44ba9ef5 100644 --- a/ui_unix.h +++ b/ui_unix.h @@ -83,6 +83,11 @@ _UI_EXTERN void uiUnixControlSetContainer(uiUnixControl *, GtkContainer *, gbool { \ gtk_widget_set_sensitive(type(c)->widget, FALSE); \ } +#define uiUnixControlDefaultSetFocus(type) \ + static void type ## SetFocus(uiControl *c) \ + { \ + gtk_widget_grab_focus(type(c)->widget); \ + } // TODO this whole addedBefore stuff is a MASSIVE HACK. #define uiUnixControlDefaultSetContainer(type) \ static void type ## SetContainer(uiUnixControl *c, GtkContainer *container, gboolean remove) \ @@ -110,6 +115,7 @@ _UI_EXTERN void uiUnixControlSetContainer(uiUnixControl *, GtkContainer *, gbool uiUnixControlDefaultEnabled(type) \ uiUnixControlDefaultEnable(type) \ uiUnixControlDefaultDisable(type) \ + uiUnixControlDefaultSetFocus(type) \ uiUnixControlDefaultSetContainer(type) #define uiUnixControlAllDefaults(type) \ @@ -130,6 +136,7 @@ _UI_EXTERN void uiUnixControlSetContainer(uiUnixControl *, GtkContainer *, gbool uiControl(var)->Enabled = type ## Enabled; \ uiControl(var)->Enable = type ## Enable; \ uiControl(var)->Disable = type ## Disable; \ + uiControl(var)->SetFocus = type ## SetFocus; \ uiUnixControl(var)->SetContainer = type ## SetContainer; // TODO document _UI_EXTERN uiUnixControl *uiUnixAllocControl(size_t n, uint32_t typesig, const char *typenamestr); diff --git a/ui_windows.h b/ui_windows.h index 69dda366..46cd9eee 100644 --- a/ui_windows.h +++ b/ui_windows.h @@ -102,6 +102,11 @@ _UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *); uiWindowsControl(c)->enabled = 0; \ uiWindowsControlSyncEnableState(uiWindowsControl(c), uiControlEnabledToUser(c)); \ } +#define uiWindowsControlDefaultSetFocus(type) \ + static void type ## SetFocus(uiControl *c) \ + { \ + uiWindowsSetFocus(type(c)->hwnd); \ + } #define uiWindowsControlDefaultSyncEnableState(type) \ static void type ## SyncEnableState(uiWindowsControl *c, int enabled) \ { \ @@ -152,6 +157,7 @@ _UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *); uiWindowsControlDefaultEnabled(type) \ uiWindowsControlDefaultEnable(type) \ uiWindowsControlDefaultDisable(type) \ + uiWindowsControlDefaultSetFocus(type) \ uiWindowsControlDefaultSyncEnableState(type) \ uiWindowsControlDefaultSetParentHWND(type) \ uiWindowsControlDefaultMinimumSizeChanged(type) \ @@ -177,6 +183,7 @@ _UI_EXTERN void uiWindowsControlChildVisibilityChanged(uiWindowsControl *); uiControl(var)->Enabled = type ## Enabled; \ uiControl(var)->Enable = type ## Enable; \ uiControl(var)->Disable = type ## Disable; \ + uiControl(var)->SetFocus = type ## SetFocus; \ uiWindowsControl(var)->SyncEnableState = type ## SyncEnableState; \ uiWindowsControl(var)->SetParentHWND = type ## SetParentHWND; \ uiWindowsControl(var)->MinimumSize = type ## MinimumSize; \ @@ -199,6 +206,8 @@ _UI_EXTERN void uiWindowsEnsureDestroyWindow(HWND hwnd); // TODO document that this should only be used in SetParentHWND() implementations _UI_EXTERN void uiWindowsEnsureSetParentHWND(HWND hwnd, HWND parent); +_UI_EXTERN void uiWindowsSetFocus(HWND hwnd); + // TODO document _UI_EXTERN void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR *controlID, HWND *insertAfter); diff --git a/unix/window.c b/unix/window.c index c5ba2038..a4b469d4 100644 --- a/unix/window.c +++ b/unix/window.c @@ -112,6 +112,7 @@ uiUnixControlDefaultHide(uiWindow) uiUnixControlDefaultEnabled(uiWindow) uiUnixControlDefaultEnable(uiWindow) uiUnixControlDefaultDisable(uiWindow) +uiUnixControlDefaultSetFocus(uiWindow) // TODO? uiUnixControlDefaultSetContainer(uiWindow) diff --git a/windows/box.cpp b/windows/box.cpp index 9567954b..c3069895 100644 --- a/windows/box.cpp +++ b/windows/box.cpp @@ -143,6 +143,7 @@ uiWindowsControlDefaultHide(uiBox) uiWindowsControlDefaultEnabled(uiBox) uiWindowsControlDefaultEnable(uiBox) uiWindowsControlDefaultDisable(uiBox) +uiWindowsControlDefaultSetFocus(uiBox) static void uiBoxSyncEnableState(uiWindowsControl *c, int enabled) { diff --git a/windows/form.cpp b/windows/form.cpp index ed194671..6cd2923b 100644 --- a/windows/form.cpp +++ b/windows/form.cpp @@ -147,6 +147,7 @@ uiWindowsControlDefaultHide(uiForm) uiWindowsControlDefaultEnabled(uiForm) uiWindowsControlDefaultEnable(uiForm) uiWindowsControlDefaultDisable(uiForm) +uiWindowsControlDefaultSetFocus(uiForm) static void uiFormSyncEnableState(uiWindowsControl *c, int enabled) { diff --git a/windows/grid.cpp b/windows/grid.cpp index cac87aff..a412a950 100644 --- a/windows/grid.cpp +++ b/windows/grid.cpp @@ -436,6 +436,7 @@ uiWindowsControlDefaultHide(uiGrid) uiWindowsControlDefaultEnabled(uiGrid) uiWindowsControlDefaultEnable(uiGrid) uiWindowsControlDefaultDisable(uiGrid) +uiWindowsControlDefaultSetFocus(uiGrid) static void uiGridSyncEnableState(uiWindowsControl *c, int enabled) { diff --git a/windows/group.cpp b/windows/group.cpp index 1a2cc6ed..d40c78bc 100644 --- a/windows/group.cpp +++ b/windows/group.cpp @@ -75,6 +75,7 @@ uiWindowsControlDefaultHide(uiGroup) uiWindowsControlDefaultEnabled(uiGroup) uiWindowsControlDefaultEnable(uiGroup) uiWindowsControlDefaultDisable(uiGroup) +uiWindowsControlDefaultSetFocus(uiGroup) static void uiGroupSyncEnableState(uiWindowsControl *c, int enabled) { diff --git a/windows/tab.cpp b/windows/tab.cpp index e7239585..03017a2c 100644 --- a/windows/tab.cpp +++ b/windows/tab.cpp @@ -112,6 +112,7 @@ uiWindowsControlDefaultHide(uiTab) uiWindowsControlDefaultEnabled(uiTab) uiWindowsControlDefaultEnable(uiTab) uiWindowsControlDefaultDisable(uiTab) +uiWindowsControlDefaultSetFocus(uiTab) static void uiTabSyncEnableState(uiWindowsControl *c, int enabled) { diff --git a/windows/window.cpp b/windows/window.cpp index 2ea5b7ce..66452009 100644 --- a/windows/window.cpp +++ b/windows/window.cpp @@ -236,6 +236,7 @@ uiWindowsControlDefaultDisable(uiWindow) uiWindowsControlDefaultSyncEnableState(uiWindow) // TODO uiWindowsControlDefaultSetParentHWND(uiWindow) +uiWindowsControlDefaultSetFocus(uiWindow) static void uiWindowMinimumSize(uiWindowsControl *c, int *width, int *height) { diff --git a/windows/winpublic.cpp b/windows/winpublic.cpp index 397a3b54..e4da9d66 100644 --- a/windows/winpublic.cpp +++ b/windows/winpublic.cpp @@ -59,3 +59,9 @@ void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r) r->bottom = 0; } } + +void uiWindowsSetFocus(HWND hwnd) +{ + if (SetFocus(hwnd) == 0) + logLastError(L"error setting ficus"); +}