aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/_abort/windowevents
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
committerStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
commit70e4841d311d68689724768157cc9cbfbde7a9fc (patch)
treeba9499f77d1258530a7e60aa6e1732c41d98161c /src/libui_sdl/libui/_abort/windowevents
parent81747d6c34eb159481a6ca3f283d065fa3568617 (diff)
another UI attempt, I guess.
sorry.
Diffstat (limited to 'src/libui_sdl/libui/_abort/windowevents')
-rw-r--r--src/libui_sdl/libui/_abort/windowevents/darwin_window.m90
-rw-r--r--src/libui_sdl/libui/_abort/windowevents/page15.c65
-rw-r--r--src/libui_sdl/libui/_abort/windowevents/ui.h6
-rw-r--r--src/libui_sdl/libui/_abort/windowevents/unix_window.c97
-rw-r--r--src/libui_sdl/libui/_abort/windowevents/windows_window.cpp86
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);
+}