Minimized windows actually render now.

This commit is contained in:
Scott Duensing 2025-01-01 17:48:48 -06:00
parent 3559734d4f
commit be6c0a9439
3 changed files with 67 additions and 61 deletions

View file

@ -520,43 +520,31 @@ static void windowPaint(struct WidgetS *widget, ...) {
int16_t xc;
int16_t yc;
WindowT *w = (WindowT *)widget;
va_list args;
uint8_t mode;
// What paint mode are we in?
va_start(args, widget);
mode = va_arg(args, int);
va_end(args);
if (mode == WINDOW_PAINT_ICONS) {
// Are we minimized?
if (w->flags & WIN_IS_ICON) {
// Render icon into window's icon surface.
surfaceSet(w->icon);
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE; // Y Sample increment.
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE; // X Sample increment.
y = 0;
x = 0;
for (yc=0; yc<ICON_SIZE; yc++) {
y += yi;
for (xc=0; xc<ICON_SIZE; xc++) {
x += xi;
surfacePixelSet(xc, yc, surfacePixelGet(w->scroll->area, x, y));
}
// Are we minimized?
if (w->flags & WIN_IS_ICON) {
// Render icon into window's icon surface.
surfaceSet(w->icon);
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE; // Y Sample increment.
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE; // X Sample increment.
y = 0;
x = 0;
for (yc=0; yc<ICON_SIZE; yc++) {
y += yi;
for (xc=0; xc<ICON_SIZE; xc++) {
x += xi;
surfacePixelSet(xc, yc, surfacePixelGet(w->scroll->area, x, y));
}
surfaceBox(0, 0, ICON_SIZE - 1, ICON_SIZE - 1, GUI_BLACK);
}
} else { // WINDOW_PAINT_ICONS
// Are we not minimized?
if (!(w->flags & WIN_IS_ICON)) {
// Does the window chrome itself need redrawn?
if (widgetDirtyGet(widget)) {
widgetDirtySet(widget, 0);
x = 1; // This is a flag for later that we need to update the cached surface.
}
// Did a widget or the window chrome need redrawn?
if (x || widgetChildrenDirty(widget)) windowCache(w, x);
surfaceBox(0, 0, ICON_SIZE - 1, ICON_SIZE - 1, GUI_BLACK);
} else {
// Does the window chrome itself need redrawn?
if (widgetDirtyGet(widget)) {
widgetDirtySet(widget, 0);
x = 1; // This is a flag for later that we need to update the cached surface.
}
// Did a widget or the window chrome need redrawn?
if (x || widgetChildrenDirty(widget)) windowCache(w, x);
}
}
@ -666,22 +654,16 @@ void wmRender(void) {
WidgetT *widget = NULL;
WindowT *win = NULL;
WindowT *win2 = NULL;
RectWT win2R;
RectT *rect = NULL;
RectT **rects = NULL;
DamageListT **damageList = NULL;
DamageListT *damageItem = NULL;
// Update all minimized windows.
surfaceSet(__guiBackBuffer);
for (i=0; i<arrlen(_windowList); i++) {
widget = (WidgetT *)_windowList[i];
widget->reg->paint(widget, WINDOW_PAINT_ICONS);
}
// Update all windows.
for (i=0; i<arrlen(_windowList); i++) {
widget = (WidgetT *)_windowList[i];
widget->reg->paint(widget, WINDOW_PAINT_NORMAL);
widget->reg->paint(widget);
}
surfaceSet(__guiBackBuffer);
@ -730,13 +712,18 @@ void wmRender(void) {
rect->x2 = videoDisplayWidthGet() - 1;
rect->y2 = videoDisplayHeightGet() - 1;
} else {
// Get this window.
// Get this window. Minimized?
if (win->flags & WIN_IS_ICON) {
rect->x = _iconCount * (ICON_SIZE + 1);
rect->y = videoDisplayHeightGet() - ICON_SIZE;
rect->x2 = rect->x + ICON_SIZE;
rect->y2 = rect->y + ICON_SIZE;
_iconCount++;
// Save this for later.
win->iconR.x = rect->x;
win->iconR.x2 = rect->x2;
win->iconR.y = rect->y;
win->iconR.y2 = rect->y2;
} else {
rect->x = win->base.r.x;
rect->y = win->base.r.y;
@ -754,27 +741,40 @@ void wmRender(void) {
// Add this window to the rectangle list.
arrput(rects, rect);
// Iterate over all the other windows to slice this window.
// Iterate over all the other windows to slice this window. ***TODO*** Does not properly handle minimized windows.
for (j=arrlen(_windowList)-1; j>=0; j--) {
win2 = (WindowT *)_windowList[j];
if (win != win2) {
// Are we minimized?
if (win2->flags & WIN_IS_ICON) {
win2R.x = win2->iconR.x;
win2R.y = win2->iconR.y;
win2R.w = ICON_SIZE;
win2R.h = ICON_SIZE;
} else {
win2R.x = win2->base.r.x;
win2R.y = win2->base.r.y;
win2R.w = win2->base.r.w;
win2R.h = win2->base.r.h;
}
// Get win2 extents.
x2 = win2->base.r.x + win2->base.r.w;
y2 = win2->base.r.y + win2->base.r.h;
x2 = win2R.x + win2R.w;
y2 = win2R.y + win2R.h;
// Check the edges of this window against all the
// rectangles in the current rectangle list. Split
// and create new rectangles on any lines that intersect.
for (k=0; k<arrlen(rects); k++) {
// Compare Window Top
if ((win2->base.r.y > rects[k]->y) && (win2->base.r.y < rects[k]->y2)) {
if ((win2R.y > rects[k]->y) && (win2R.y < rects[k]->y2)) {
NEW(RectT, rect);
rect->x = rects[k]->x;
rect->x2 = rects[k]->x2;
rect->y2 = rects[k]->y2;
rects[k]->y2 = win2->base.r.y;
rect->y = win2->base.r.y;
rects[k]->y2 = win2R.y;
rect->y = win2R.y;
arrput(rects, rect);
}
// Compare Window Bottom
@ -788,13 +788,13 @@ void wmRender(void) {
arrput(rects, rect);
}
// Compare Window Left
if ((win2->base.r.x > rects[k]->x) && (win2->base.r.x < rects[k]->x2)) {
if ((win2R.x > rects[k]->x) && (win2R.x < rects[k]->x2)) {
NEW(RectT, rect);
rect->y = rects[k]->y;
rect->x2 = rects[k]->x2;
rect->y2 = rects[k]->y2;
rects[k]->x2 = win2->base.r.x;
rect->x = win2->base.r.x;
rects[k]->x2 = win2R.x;
rect->x = win2R.x;
arrput(rects, rect);
}
// Compare Window Right
@ -928,11 +928,19 @@ void wmRender(void) {
for (k=0; k<arrlen(damageList); k++) {
/*
// ***DEBUG***
if (damageList[k]->window != NULL) {
surfaceBox(
damageList[k]->window->bounds.x, damageList[k]->window->bounds.y,
damageList[k]->window->bounds.x2, damageList[k]->window->bounds.y2,
GUI_RED);
if (damageList[k]->window->flags & WIN_IS_ICON) {
surfaceBox(
damageList[k]->rect.x, damageList[k]->rect.y,
ICON_SIZE, ICON_SIZE,
GUI_RED);
} else {
surfaceBox(
damageList[k]->window->bounds.x, damageList[k]->window->bounds.y,
damageList[k]->window->bounds.x2, damageList[k]->window->bounds.y2,
GUI_RED);
}
}
*/
@ -942,8 +950,8 @@ void wmRender(void) {
// Icon.
surfaceBlit(
damageList[k]->rect.x, damageList[k]->rect.y,
0, 0,
ICON_SIZE, ICON_SIZE,
damageList[k]->rect.x - damageList[k]->window->iconR.x, damageList[k]->rect.y - damageList[k]->window->iconR.y,
damageList[k]->rect.x2 - damageList[k]->rect.x, damageList[k]->rect.y2 - damageList[k]->rect.y,
damageList[k]->window->icon);
} else {
// Window content.

View file

@ -35,9 +35,6 @@
#define ICON_SIZE 32
#define GADGET_SIZE 20
#define WINDOW_PAINT_ICONS 0
#define WINDOW_PAINT_NORMAL 1
#define WIN_NONE 0
#define WIN_CLOSE 1
#define WIN_MAXIMIZE 2
@ -65,6 +62,7 @@ typedef struct WindowS {
RectWT restore; // Size of window if they restore from maximized.
PointT restoreOffset; // Scroll position if they restore from maximized.
RectT bounds; // Window contents in screen space. Does not include titlebar or window chrome.
RectT iconR; // Position when iconized.
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
SurfaceT *icon; // Needed for damaged region drawing.
} WindowT;

View file

@ -54,7 +54,7 @@ int main(int argc, char *argv[]) {
if (guiStartup(800, 600, 16) == SUCCESS) {
for (i=1; i<2; i++) {
for (i=1; i<4; i++) {
sprintf(title, "Testing %d", i);
w = windowCreate(i * 50, i * 50, 500, 300, title, WIN_STANDARD, 640, 480);