From f3cc0d50505c25163c19c391a8ca66e9e379170a Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Mon, 20 Jun 2022 18:09:51 -0500 Subject: [PATCH] Maximize and Restore working. --- client/src/gui/wmwindow.c | 107 +++++++++++++++++++++++++++++++------- client/src/gui/wmwindow.h | 19 ++++--- 2 files changed, 100 insertions(+), 26 deletions(-) diff --git a/client/src/gui/wmwindow.c b/client/src/gui/wmwindow.c index 2539ef0..b7b453b 100644 --- a/client/src/gui/wmwindow.c +++ b/client/src/gui/wmwindow.c @@ -18,6 +18,7 @@ static void windowCache(WindowT *w); static void windowCache(WindowT *w) { + char c; int16_t i; int16_t x1; int16_t y1; @@ -134,8 +135,19 @@ static void windowCache(WindowT *w) { if (w->title) { fontSet(__guiFontVGA8x16); fontColorSet(GUI_WHITE, titleBackgroundColor); - // ***TODO*** Does not clip! - fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2); + // How many characters do we have room for? + i = ((w->titlebar.x2 - w->titlebar.x) >> 3) - 2; + // Does the title fit? + if ((int16_t)strlen(w->title) <= i) { + // Render entire title. + fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2); + } else { + // Render partial title. + c = w->title[i]; + w->title[i] = 0; + fontRender(w->title, w->titlebar.x + 12, w->titlebar.y + 2); + w->title[i] = c; + } } surfaceBoxHighlight(w->titlebar.x, w->titlebar.y, w->titlebar.x2, w->titlebar.y2, GUI_WHITE, GUI_BLACK); } else { @@ -192,18 +204,10 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl NEW(WindowT, win); + memset(win, 0, sizeof(WindowT)); guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, x, y, w, h); win->title = strdup(title); win->flags = (uint8_t)flags; - win->close.x = win->close.y = win->close.x2 = win->close.y2 = 0; - win->titlebar.x = win->titlebar.y = win->titlebar.x2 = win->titlebar.y2 = 0; - win->minimize.x = win->minimize.y = win->minimize.x2 = win->minimize.y2 = 0; - win->maximize.x = win->maximize.y = win->maximize.x2 = win->maximize.y2 = 0; - win->resize1.x = win->resize1.y = win->resize1.x2 = win->resize1.y2 = 0; - win->resize2.x = win->resize2.y = win->resize2.x2 = win->resize2.y2 = 0; - win->bounds.x = win->bounds.y = win->bounds.x2 = win->bounds.y2 = 0; - win->cached = NULL; - win->content = NULL; //***DEBUG*** Hackery to get contents before we have widgets. static uint8_t image = 1; @@ -337,6 +341,63 @@ void windowFocusSet(WindowT *win) { } +void windowMaximizeRestore(WindowT *win) { + int16_t i; + + // Are we maximized? + if (win->flags & WIN_IS_MAX) { + + // Restore to previous size. + win->flags &= ~WIN_IS_MAX; + win->base.r = win->restore; + + } else { // Maximized? + + // Maximize window. Reposition if needed. + win->flags |= WIN_IS_MAX; + + // Remember current size and position. + win->restore = win->base.r; + + // Expand to full contents. + win->base.r.w = (win->base.r.w - (win->bounds.x2 - win->bounds.x) + surfaceWidthGet(win->content)); + win->base.r.h = (win->base.r.h - (win->bounds.y2 - win->bounds.y) + surfaceHeightGet(win->content)); + + // Does this go off the screen to the right? + if (win->base.r.x + win->base.r.w >= videoDisplayWidthGet()) { + // Can we move it left to fit? + i = videoDisplayWidthGet() - (win->base.r.x + win->base.r.w); + if (i <= win->base.r.x) { + // Yes, go left! + win->base.r.x += i; + } else { + // Nope. Go all the way left and resize to fit on desktop. + win->base.r.x = 0; + win->base.r.w = videoDisplayWidthGet(); + } + } + + // Does this go off the screen to the bottom? + if (win->base.r.y + win->base.r.h >= videoDisplayHeightGet()) { + // Can we move it up to fit? + i = videoDisplayHeightGet() - (win->base.r.y + win->base.r.h); + if (i <= win->base.r.y) { + // Yes, go up! + win->base.r.y += i; + } else { + // Nope. Go all the way up and resize to fit on desktop. + win->base.r.y = 0; + win->base.r.h = videoDisplayHeightGet(); + } + } + + } // Maximized? + + // Update. + windowCache(win); +} + + void windowMinimize(WindowT *win) { // Minimize. win->flags |= WIN_IS_ICON; @@ -460,18 +521,25 @@ RegisterT *windowRegister(uint8_t magic) { void windowResizeTo(WindowT *win, uint16_t width, uint16_t height) { + // Too small? - if (width < 80) width = 80; + if (width < 95) width = 95; if (height < 80) height = 80; // Too big? if (win->bounds.w - win->bounds.x + (width - win->base.r.w) > surfaceWidthGet(win->content)) width = (win->base.r.w - (win->bounds.x2 - win->bounds.x) + surfaceWidthGet(win->content)); if (win->bounds.h - win->bounds.y + (height - win->base.r.h) > surfaceHeightGet(win->content)) height = (win->base.r.h - (win->bounds.y2 - win->bounds.y) + surfaceHeightGet(win->content)); - // Do resize. - win->base.r.w = width; - win->base.r.h =height; - windowCache(win); + // Did the size change? + if (win->base.r.w != width || win->base.r.h !=height) { + // Yes! If we were maximized, clear it - can't restore after resizing. + win->flags &= ~WIN_IS_MAX; + + // Do resize. + win->base.r.w = width; + win->base.r.h =height; + windowCache(win); + } } @@ -561,7 +629,9 @@ void wmUpdate(EventT *event) { } else { // Dragging. if (resizing) { - + // If they try to resize outside the window bounds, cancel it. + if (event->x < win->base.r.x || event->y < win->base.r.y) break; + // Resize it. windowResizeTo(win, event->x - resizeOffset.x, event->y - resizeOffset.y); break; @@ -607,7 +677,8 @@ void wmUpdate(EventT *event) { // Are we inside the maximize button? Does not include button frame on purpose. if (win->flags & WIN_MAXIMIZE &&event->x < win->maximize.x2 && event->x > win->maximize.x && event->y < win->maximize.y2 && event->y > win->maximize.y) { - //***TODO*** Maximize. + windowMaximizeRestore(win); + break; } } else { // On topmost window. diff --git a/client/src/gui/wmwindow.h b/client/src/gui/wmwindow.h index c497148..f4fa7d8 100644 --- a/client/src/gui/wmwindow.h +++ b/client/src/gui/wmwindow.h @@ -5,14 +5,15 @@ #include "gui.h" -#define WIN_NONE 0 -#define WIN_CLOSE 1 -#define WIN_MAXIMIZE 2 -#define WIN_MINIMIZE 4 -#define WIN_RESIZE 8 -#define WIN_SCROLL_V 16 -#define WIN_SCROLL_H 32 -#define WIN_IS_ICON 64 +#define WIN_NONE 0 +#define WIN_CLOSE 1 +#define WIN_MAXIMIZE 2 +#define WIN_MINIMIZE 4 +#define WIN_RESIZE 8 +#define WIN_SCROLL_V 16 +#define WIN_SCROLL_H 32 +#define WIN_IS_ICON 64 +#define WIN_IS_MAX 128 typedef struct WindowS { @@ -26,6 +27,7 @@ typedef struct WindowS { RectT resize1; // First resize area. RectT resize2; // Second resize area. RectT bounds; // Inside edge of window frame. + RectT restore; // Size of window if they restore from maximized. SurfaceT *content; // Actual window contents - widgets and such. SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing. } WindowT; @@ -37,6 +39,7 @@ extern uint8_t __MAGIC_WINDOW; // Magic ID assigned to us from the GUI. WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title, int flags, ...); void windowDestroy(struct WidgetS *widget, ...); void windowFocusSet(WindowT *win); +void windowMaximizeRestore(WindowT *win); void windowMinimize(WindowT *win); void windowMoveTo(WindowT *win, uint16_t x, uint16_t y); void windowPaint(struct WidgetS *widget, ...);