diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-09-09 02:30:51 +0200 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-09-09 02:30:51 +0200 |
commit | 70e4841d311d68689724768157cc9cbfbde7a9fc (patch) | |
tree | ba9499f77d1258530a7e60aa6e1732c41d98161c /src/libui_sdl/libui/_abort/windowevents | |
parent | 81747d6c34eb159481a6ca3f283d065fa3568617 (diff) |
another UI attempt, I guess.
sorry.
Diffstat (limited to 'src/libui_sdl/libui/_abort/windowevents')
5 files changed, 344 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/_abort/windowevents/darwin_window.m b/src/libui_sdl/libui/_abort/windowevents/darwin_window.m new file mode 100644 index 0000000..76180d8 --- /dev/null +++ b/src/libui_sdl/libui/_abort/windowevents/darwin_window.m @@ -0,0 +1,90 @@ +struct uiWindow { + // constraints + void (*onPositionChanged)(uiWindow *, void *); + void *onPositionChangedData; + BOOL suppressPositionChanged; + // onContentSizeChanged +}; + +@interface windowDelegateClass : NSObject<NSWindowDelegate> { +// windowShouldClose: +- (void)windowDidMove:(NSNotification *)note; +// windowDidResize: +@end + +@implementation windowDelegateClass + +// - (BOOL)windowShouldClose:(id)sender + +// TODO doesn't happen live +- (void)windowDidMove:(NSNotification *)note +{ + uiWindow *w; + + w = [self lookupWindow:((NSWindow *) [note object])]; + if (!w->suppressPositionChanged) + (*(w->onPositionChanged))(w, w->onPositionChangedData); +} + +// - (void)windowDidResize:(NSNotification *)note + +// void uiWindowSetTitle(uiWindow *w, const char *title) + +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ + NSScreen *screen; + NSRect r; + + r = [w->window frame]; + *x = r.origin.x; + // this is the right screen to use; thanks mikeash in irc.freenode.net/#macdev + // -mainScreen is useless for positioning (it's just the key window's screen) + // and we use -frame, not -visibleFrame, for dealing with absolute positions + screen = (NSScreen *) [[NSScreen screens] objectAtIndex:0]; + *y = ([screen frame].size.height - r.origin.y) - r.size.height; +} + +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ + // -[NSWindow setFrameTopLeftPoint:] is acting weird so... + NSRect r; + NSScreen *screen; + + // this fires windowDidMove: + w->suppressPositionChanged = YES; + r = [w->window frame]; + r.origin.x = x; + screen = (NSScreen *) [[NSScreen screens] objectAtIndex:0]; + r.origin.y = [screen frame].size.height - (y + r.size.height); + [w->window setFrameOrigin:r.origin]; + w->suppressPositionChanged = NO; +} + +void uiWindowCenter(uiWindow *w) +{ + w->suppressPositionChanged = YES; + [w->window center]; + w->suppressPositionChanged = NO; +} + +void uiWindowOnPositionChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) +{ + w->onPositionChanged = f; + w->onPositionChangedData = data; +} + +// void uiWindowContentSize(uiWindow *w, int *width, int *height) + +// static int defaultOnClosing(uiWindow *w, void *data) + +static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) +{ + // do nothing +} + +uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) +{ +// uiWindowOnClosing(w, defaultOnClosing, NULL); + uiWindowOnPositionChanged(w, defaultOnPositionContentSizeChanged, NULL); +// uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); +} diff --git a/src/libui_sdl/libui/_abort/windowevents/page15.c b/src/libui_sdl/libui/_abort/windowevents/page15.c new file mode 100644 index 0000000..0cceba8 --- /dev/null +++ b/src/libui_sdl/libui/_abort/windowevents/page15.c @@ -0,0 +1,65 @@ +static uiSpinbox *x, *y; + +static void moveX(uiSpinbox *s, void *data) +{ + uiWindow *w = uiWindow(data); + int xp, yp; + + uiWindowPosition(w, &xp, &yp); + xp = uiSpinboxValue(x); + uiWindowSetPosition(w, xp, yp); +} + +static void moveY(uiSpinbox *s, void *data) +{ + uiWindow *w = uiWindow(data); + int xp, yp; + + uiWindowPosition(w, &xp, &yp); + yp = uiSpinboxValue(y); + uiWindowSetPosition(w, xp, yp); +} + +static void updatepos(uiWindow *w) +{ + int xp, yp; + + uiWindowPosition(w, &xp, &yp); + uiSpinboxSetValue(x, xp); + uiSpinboxSetValue(y, yp); +} + +static void center(uiButton *b, void *data) +{ + uiWindow *w = uiWindow(data); + + uiWindowCenter(w); + updatepos(w); +} + +void onMove(uiWindow *w, void *data) +{ + printf("move\n"); + updatepos(w); +} + +uiBox *makePage15(uiWindow *w) +{ + hbox = newHorizontalBox(); + // TODO if I make this 1 and not add anything else AND not call uiWindowOnPositionChanged(), on OS X the box won't be able to grow vertically + uiBoxAppend(page15, uiControl(hbox), 0); + + uiBoxAppend(hbox, uiControl(uiNewLabel("Position")), 0); + x = uiNewSpinbox(INT_MIN, INT_MAX); + uiBoxAppend(hbox, uiControl(x), 1); + y = uiNewSpinbox(INT_MIN, INT_MAX); + uiBoxAppend(hbox, uiControl(y), 1); + button = uiNewButton("Center"); + uiBoxAppend(hbox, uiControl(button), 0); + + uiSpinboxOnChanged(x, moveX, w); + uiSpinboxOnChanged(y, moveY, w); + uiButtonOnClicked(button, center, w); + uiWindowOnPositionChanged(w, onMove, NULL); + updatepos(w); +} diff --git a/src/libui_sdl/libui/_abort/windowevents/ui.h b/src/libui_sdl/libui/_abort/windowevents/ui.h new file mode 100644 index 0000000..e0d24c7 --- /dev/null +++ b/src/libui_sdl/libui/_abort/windowevents/ui.h @@ -0,0 +1,6 @@ +// uiWindowSetTitle +_UI_EXTERN void uiWindowPosition(uiWindow *w, int *x, int *y); +_UI_EXTERN void uiWindowSetPosition(uiWindow *w, int x, int y); +_UI_EXTERN void uiWindowCenter(uiWindow *w); +_UI_EXTERN void uiWindowOnPositionChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data); +// uiWindowContentSize diff --git a/src/libui_sdl/libui/_abort/windowevents/unix_window.c b/src/libui_sdl/libui/_abort/windowevents/unix_window.c new file mode 100644 index 0000000..96af26a --- /dev/null +++ b/src/libui_sdl/libui/_abort/windowevents/unix_window.c @@ -0,0 +1,97 @@ +struct uiWindow { +// void *onClosingData; + void (*onPositionChanged)(uiWindow *, void *); + void *onPositionChangedData; + gboolean changingPosition; +// void (*onContentSizeChanged)(uiWindow *, void *); +}; + +// static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data) + +static gboolean onConfigure(GtkWidget *win, GdkEvent *e, gpointer data) +{ + uiWindow *w = uiWindow(data); + + // there doesn't seem to be a way to determine if only moving or only resizing is happening :/ + if (w->changingPosition) + w->changingPosition = FALSE; + else + (*(w->onPositionChanged))(w, w->onPositionChangedData); + // always continue handling + return FALSE; +} + +// static void onSizeAllocate(GtkWidget *widget, GdkRectangle *allocation, gpointer data) + +// static int defaultOnClosing(uiWindow *w, void *data) + +static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) +{ + // do nothing +} + +// static void uiWindowDestroy(uiControl *c) + +// void uiWindowSetTitle(uiWindow *w, const char *title) + +// TODO allow specifying either as NULL on all platforms +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ + gint rx, ry; + + gtk_window_get_position(w->window, &rx, &ry); + *x = rx; + *y = ry; +} + +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ + w->changingPosition = TRUE; + gtk_window_move(w->window, x, y); + // gtk_window_move() is asynchronous + // we need to wait for a configure-event + // thanks to hergertme in irc.gimp.net/#gtk+ + while (w->changingPosition) + if (!uiMainStep(1)) + break; // stop early if uiQuit() called +} + +void uiWindowCenter(uiWindow *w) +{ + gint x, y; + GtkAllocation winalloc; + GdkWindow *gdkwin; + GdkScreen *screen; + GdkRectangle workarea; + + gtk_widget_get_allocation(w->widget, &winalloc); + gdkwin = gtk_widget_get_window(w->widget); + screen = gdk_window_get_screen(gdkwin); + gdk_screen_get_monitor_workarea(screen, + gdk_screen_get_monitor_at_window(screen, gdkwin), + &workarea); + + x = (workarea.width - winalloc.width) / 2; + y = (workarea.height - winalloc.height) / 2; + // TODO move up slightly? see what Mutter or GNOME Shell or GNOME Terminal do(es)? + uiWindowSetPosition(w, x, y); +} + +// TODO this and size changed get set during uiWindowDestroy +void uiWindowOnPositionChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) +{ + w->onPositionChanged = f; + w->onPositionChangedData = data; +} + +// void uiWindowContentSize(uiWindow *w, int *width, int *height) + +uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) +{ +// g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w); + g_signal_connect(w->widget, "configure-event", G_CALLBACK(onConfigure), w); +// g_signal_connect(w->childHolderWidget, "size-allocate", G_CALLBACK(onSizeAllocate), w); +// uiWindowOnClosing(w, defaultOnClosing, NULL); + uiWindowOnPositionChanged(w, defaultOnPositionContentSizeChanged, NULL); +// uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); +} diff --git a/src/libui_sdl/libui/_abort/windowevents/windows_window.cpp b/src/libui_sdl/libui/_abort/windowevents/windows_window.cpp new file mode 100644 index 0000000..769c6db --- /dev/null +++ b/src/libui_sdl/libui/_abort/windowevents/windows_window.cpp @@ -0,0 +1,86 @@ +struct uiWindow { +// BOOL hasMenubar; + void (*onPositionChanged)(uiWindow *, void *); + void *onPositionChangedData; + BOOL changingPosition; // to avoid triggering the above when programmatically doing this +// void (*onContentSizeChanged)(uiWindow *, void *); +}; + +static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + case WM_WINDOWPOSCHANGED: + if ((wp->flags & SWP_NOMOVE) == 0) + if (!w->changingPosition) + (*(w->onPositionChanged))(w, w->onPositionChangedData); + // and continue anyway +// if ((wp->flags & SWP_NOSIZE) != 0) +} + +// static int defaultOnClosing(uiWindow *w, void *data) + +static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data) +{ + // do nothing +} + +// static std::map<uiWindow *, bool> windows; + +// void uiWindowSetTitle(uiWindow *w, const char *title) + +void uiWindowPosition(uiWindow *w, int *x, int *y) +{ + RECT r; + + uiWindowsEnsureGetWindowRect(w->hwnd, &r); + *x = r.left; + *y = r.top; +} + +void uiWindowSetPosition(uiWindow *w, int x, int y) +{ + w->changingPosition = TRUE; + if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER) == 0) + logLastError(L"error moving window"); + w->changingPosition = FALSE; +} + +// static void windowMonitorRect(HWND hwnd, RECT *r) + +// TODO use the work rect instead? +void uiWindowCenter(uiWindow *w) +{ + RECT wr, mr; + int x, y; + LONG wwid, mwid; + LONG wht, mht; + + uiWindowsEnsureGetWindowRect(w->hwnd, &wr); + windowMonitorRect(w->hwnd, &mr); + wwid = wr.right - wr.left; + mwid = mr.right - mr.left; + x = (mwid - wwid) / 2; + wht = wr.bottom - wr.top; + mht = mr.bottom - mr.top; + y = (mht - wht) / 2; + // y is now evenly divided, however https://msdn.microsoft.com/en-us/library/windows/desktop/dn742502(v=vs.85).aspx says that 45% should go above and 55% should go below + // so just move 5% of the way up + // TODO should this be on the work area? + // TODO is this calculation correct? + y -= y / 20; + uiWindowSetPosition(w, x, y); +} + +void uiWindowOnPositionChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data) +{ + w->onPositionChanged = f; + w->onPositionChangedData = data; +} + +// void uiWindowContentSize(uiWindow *w, int *width, int *height) + +uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) +{ +// uiWindowOnClosing(w, defaultOnClosing, NULL); + uiWindowOnPositionChanged(w, defaultOnPositionContentSizeChanged, NULL); +// uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL); +} |