Icons working with damage renderer!

This commit is contained in:
Scott Duensing 2024-04-14 19:25:32 -05:00
parent ac60a82c65
commit 272978b9ad
4 changed files with 183 additions and 162 deletions

View file

@ -70,22 +70,14 @@ static void guiDeleteListProcess(void) {
void guiEventsDo(void) {
EventT event = { 0 };
#ifndef NEW_RENDERER
// Paint desktop.
surfaceSet(__guiBackBuffer);
surfaceClear(GUI_CYAN);
#endif
// Read mouse & keyboard.
platformEventGet(&event);
// Handle GUI window manager and widgets.
wmUpdate(&event);
#ifdef NEW_RENDERER
// Draw.
wmRender();
#endif
// Paint mouse pointer.
surfaceSet(__guiBackBuffer);

View file

@ -257,6 +257,9 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
visibleSize.x = win->bounds.x2 - win->bounds.x + 1;
visibleSize.y = win->bounds.y2 - win->bounds.y + 1;
// Create icon surface.
win->icon = surfaceCreate(ICON_SIZE, ICON_SIZE);
// If the window is resizable, we need to get two more arguments for the content size.
if (win->flags & WIN_RESIZE) {
va_start(args, flags);
@ -313,6 +316,8 @@ static void windowDestroy(struct WidgetS *widget, ...) {
arrfree(window->base.children);
// Free cached surface.
if (window->cached) surfaceDestroy(&window->cached);
// Free icon surface.
surfaceDestroy(&window->icon);
// Delete the window.
DEL(window);
// Fixup focus.
@ -531,22 +536,20 @@ static void windowPaint(struct WidgetS *widget, ...) {
if (mode == WINDOW_PAINT_ICONS) {
// Are we minimized?
if (w->flags & WIN_IS_ICON) {
// Draw iconized version of contents. There are too many counters here but it's the only way it worked reliably.
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE;
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE;
py = videoDisplayHeightGet() - ICON_SIZE;
// 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;
px = (ICON_SIZE + 1) * _iconCount;
for (xc=0; xc<ICON_SIZE; xc++) {
x += xi;
surfacePixelSet(px++, py, surfacePixelGet(w->scroll->area, x, y));
surfacePixelSet(xc, yc, surfacePixelGet(w->scroll->area, x, y));
}
py++;
}
_iconCount++;
surfaceBox(0, 0, ICON_SIZE - 1, ICON_SIZE - 1, GUI_BLACK);
}
} else { // WINDOW_PAINT_ICONS
// Are we not minimized?
@ -558,10 +561,6 @@ static void windowPaint(struct WidgetS *widget, ...) {
}
// Did a widget or the window chrome need redrawn?
if (x || widgetChildrenDirty(widget)) windowCache(w, x);
// By now we have a valid cached window. Blit it.
#ifndef NEW_RENDERER
surfaceBlit(w->base.r.x, w->base.r.y, 0, 0, w->base.r.w, w->base.r.h, w->cached);
#endif
}
}
}
@ -662,23 +661,41 @@ static WidgetT *windowWidgetFinder(WidgetT *widget, uint16_t x, uint16_t y, int1
void wmRender(void) {
uint8_t found;
uint8_t pass;
int16_t i;
int16_t j;
int16_t k;
int16_t x2;
int16_t y2;
WidgetT *widget = NULL;
WindowT *win = NULL;
WindowT *win2 = NULL;
RectT *rect;
RectT *rect = NULL;
RectT **rects = NULL;
DamageListT **damageList = NULL;
DamageListT *damageItem = NULL;
uint8_t found;
// ***TODO*** We still calculate the desktop in the damage list below.
// There's some odd off-by-one when rendering that needs fixed. For now
// we just draw the desktop and then window contents.
// 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);
}
// This is global so we can click on them later.
_iconCount = 0;
// Draw the desktop.
surfaceSet(__guiBackBuffer);
surfaceClear(GUI_CYAN);
@ -699,28 +716,45 @@ void wmRender(void) {
//
// Finally do the same as the remaining windows with the entire screen.
// Make two passes over the window list. First for regular windows,
// second for iconized windows.
for (pass=0; pass<2; pass++) {
// Iterate over all windows, top to bottom.
for (i=arrlen(_windowList)-1; i>=-1; i--) {
for (i=arrlen(_windowList)-1; i>=0-pass; i--) {
// Is this the desktop?
win = (i == -1) ? NULL : (WindowT *)_windowList[i];
// Skip windows depending on pass and window state.
if ((pass == 0) && (win->flags & WIN_IS_ICON)) continue;
if ((pass == 1) && (win != NULL) && !(win->flags & WIN_IS_ICON)) continue;
// New rectangle.
NEW(RectT, rect);
// Are we comparing the desktop?
if (i == -1) {
if (win == NULL) {
// Yes. Fake a window.
win = NULL;
rect->x = 0;
rect->y = 0;
rect->x2 = videoDisplayWidthGet() - 1;
rect->y2 = videoDisplayHeightGet() - 1;
} else {
// Get this window.
win = (WindowT *)_windowList[i];
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++;
} else {
rect->x = win->base.r.x;
rect->y = win->base.r.y;
rect->x2 = win->base.r.x + win->base.r.w;
rect->y2 = win->base.r.y + win->base.r.h;
}
}
// Clip to screen bounds.
if (rect->x < 0) rect->x = 0;
@ -827,6 +861,8 @@ void wmRender(void) {
} // Window list.
} // Pass.
// Merge adjacent damage areas.
// For areas to be adjacent they need matching X coordinates with a
// shared Y coordinate or matching Y coordinates with a shared X as
@ -906,13 +942,22 @@ void wmRender(void) {
*/
if (damageList[k]->window != NULL) {
// Icon or Window?
if (damageList[k]->window->flags & WIN_IS_ICON) {
// Icon.
surfaceBlit(
damageList[k]->rect.x, damageList[k]->rect.y,
0, 0,
ICON_SIZE, ICON_SIZE,
damageList[k]->window->icon);
} else {
// Window content.
surfaceBlit(
damageList[k]->rect.x, damageList[k]->rect.y,
damageList[k]->rect.x - damageList[k]->window->base.r.x, damageList[k]->rect.y - damageList[k]->window->base.r.y,
damageList[k]->rect.x2 - damageList[k]->rect.x,
damageList[k]->rect.y2 - damageList[k]->rect.y,
damageList[k]->rect.x2 - damageList[k]->rect.x, damageList[k]->rect.y2 - damageList[k]->rect.y,
damageList[k]->window->cached);
}
} else {
// Desktop.
//surfaceBoxFilled(damageList[k]->rect.x, damageList[k]->rect.y, damageList[k]->rect.x2, damageList[k]->rect.y2, GUI_CYAN);
@ -974,21 +1019,6 @@ void wmUpdate(EventT *event) {
// Mouse is always the default pointer unless something changes it for this frame.
guiMousePointerSet(MOUSE_POINTER);
// Paint all minimized windows.
surfaceSet(__guiBackBuffer);
_iconCount = 0;
for (i=0; i<arrlen(_windowList); i++) {
widget = (WidgetT *)_windowList[i];
widget->reg->paint(widget, WINDOW_PAINT_ICONS);
}
// Paint all windows.
for (i=0; i<arrlen(_windowList); i++) {
surfaceSet(__guiBackBuffer);
widget = (WidgetT *)_windowList[i];
widget->reg->paint(widget, WINDOW_PAINT_NORMAL);
}
// Get top window.
win = _windowTop;

View file

@ -66,6 +66,7 @@ typedef struct WindowS {
PointT restoreOffset; // Scroll position if they restore from maximized.
RectT bounds; // Window contents in screen space. Does not include titlebar or window chrome.
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
SurfaceT *icon; // Needed for damaged region drawing.
} WindowT;

View file

@ -29,8 +29,6 @@
#define MEMORY_CHECK_ENABLED
#define NEW_RENDERER
#include <stdint.h>
#include <stdarg.h>