Icons working with damage renderer!
This commit is contained in:
parent
ac60a82c65
commit
272978b9ad
4 changed files with 183 additions and 162 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
#define MEMORY_CHECK_ENABLED
|
||||
|
||||
#define NEW_RENDERER
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue