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) {
|
void guiEventsDo(void) {
|
||||||
EventT event = { 0 };
|
EventT event = { 0 };
|
||||||
|
|
||||||
#ifndef NEW_RENDERER
|
|
||||||
// Paint desktop.
|
|
||||||
surfaceSet(__guiBackBuffer);
|
|
||||||
surfaceClear(GUI_CYAN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Read mouse & keyboard.
|
// Read mouse & keyboard.
|
||||||
platformEventGet(&event);
|
platformEventGet(&event);
|
||||||
|
|
||||||
// Handle GUI window manager and widgets.
|
// Handle GUI window manager and widgets.
|
||||||
wmUpdate(&event);
|
wmUpdate(&event);
|
||||||
|
|
||||||
#ifdef NEW_RENDERER
|
|
||||||
// Draw.
|
// Draw.
|
||||||
wmRender();
|
wmRender();
|
||||||
#endif
|
|
||||||
|
|
||||||
// Paint mouse pointer.
|
// Paint mouse pointer.
|
||||||
surfaceSet(__guiBackBuffer);
|
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.x = win->bounds.x2 - win->bounds.x + 1;
|
||||||
visibleSize.y = win->bounds.y2 - win->bounds.y + 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 the window is resizable, we need to get two more arguments for the content size.
|
||||||
if (win->flags & WIN_RESIZE) {
|
if (win->flags & WIN_RESIZE) {
|
||||||
va_start(args, flags);
|
va_start(args, flags);
|
||||||
|
@ -313,6 +316,8 @@ static void windowDestroy(struct WidgetS *widget, ...) {
|
||||||
arrfree(window->base.children);
|
arrfree(window->base.children);
|
||||||
// Free cached surface.
|
// Free cached surface.
|
||||||
if (window->cached) surfaceDestroy(&window->cached);
|
if (window->cached) surfaceDestroy(&window->cached);
|
||||||
|
// Free icon surface.
|
||||||
|
surfaceDestroy(&window->icon);
|
||||||
// Delete the window.
|
// Delete the window.
|
||||||
DEL(window);
|
DEL(window);
|
||||||
// Fixup focus.
|
// Fixup focus.
|
||||||
|
@ -531,22 +536,20 @@ static void windowPaint(struct WidgetS *widget, ...) {
|
||||||
if (mode == WINDOW_PAINT_ICONS) {
|
if (mode == WINDOW_PAINT_ICONS) {
|
||||||
// Are we minimized?
|
// Are we minimized?
|
||||||
if (w->flags & WIN_IS_ICON) {
|
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.
|
// Render icon into window's icon surface.
|
||||||
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE;
|
surfaceSet(w->icon);
|
||||||
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE;
|
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE; // Y Sample increment.
|
||||||
py = videoDisplayHeightGet() - ICON_SIZE;
|
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE; // X Sample increment.
|
||||||
y = 0;
|
y = 0;
|
||||||
x = 0;
|
x = 0;
|
||||||
for (yc=0; yc<ICON_SIZE; yc++) {
|
for (yc=0; yc<ICON_SIZE; yc++) {
|
||||||
y += yi;
|
y += yi;
|
||||||
px = (ICON_SIZE + 1) * _iconCount;
|
|
||||||
for (xc=0; xc<ICON_SIZE; xc++) {
|
for (xc=0; xc<ICON_SIZE; xc++) {
|
||||||
x += xi;
|
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
|
} else { // WINDOW_PAINT_ICONS
|
||||||
// Are we not minimized?
|
// Are we not minimized?
|
||||||
|
@ -558,10 +561,6 @@ static void windowPaint(struct WidgetS *widget, ...) {
|
||||||
}
|
}
|
||||||
// Did a widget or the window chrome need redrawn?
|
// Did a widget or the window chrome need redrawn?
|
||||||
if (x || widgetChildrenDirty(widget)) windowCache(w, x);
|
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) {
|
void wmRender(void) {
|
||||||
|
uint8_t found;
|
||||||
|
uint8_t pass;
|
||||||
int16_t i;
|
int16_t i;
|
||||||
int16_t j;
|
int16_t j;
|
||||||
int16_t k;
|
int16_t k;
|
||||||
int16_t x2;
|
int16_t x2;
|
||||||
int16_t y2;
|
int16_t y2;
|
||||||
|
WidgetT *widget = NULL;
|
||||||
WindowT *win = NULL;
|
WindowT *win = NULL;
|
||||||
WindowT *win2 = NULL;
|
WindowT *win2 = NULL;
|
||||||
RectT *rect;
|
RectT *rect = NULL;
|
||||||
RectT **rects = NULL;
|
RectT **rects = NULL;
|
||||||
DamageListT **damageList = NULL;
|
DamageListT **damageList = NULL;
|
||||||
DamageListT *damageItem = NULL;
|
DamageListT *damageItem = NULL;
|
||||||
uint8_t found;
|
|
||||||
|
|
||||||
// ***TODO*** We still calculate the desktop in the damage list below.
|
// ***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
|
// There's some odd off-by-one when rendering that needs fixed. For now
|
||||||
// we just draw the desktop and then window contents.
|
// 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.
|
// Draw the desktop.
|
||||||
surfaceSet(__guiBackBuffer);
|
surfaceSet(__guiBackBuffer);
|
||||||
surfaceClear(GUI_CYAN);
|
surfaceClear(GUI_CYAN);
|
||||||
|
@ -699,28 +716,45 @@ void wmRender(void) {
|
||||||
//
|
//
|
||||||
// Finally do the same as the remaining windows with the entire screen.
|
// 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.
|
// 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 rectangle.
|
||||||
NEW(RectT, rect);
|
NEW(RectT, rect);
|
||||||
|
|
||||||
// Are we comparing the desktop?
|
// Are we comparing the desktop?
|
||||||
if (i == -1) {
|
if (win == NULL) {
|
||||||
// Yes. Fake a window.
|
// Yes. Fake a window.
|
||||||
win = NULL;
|
|
||||||
rect->x = 0;
|
rect->x = 0;
|
||||||
rect->y = 0;
|
rect->y = 0;
|
||||||
rect->x2 = videoDisplayWidthGet() - 1;
|
rect->x2 = videoDisplayWidthGet() - 1;
|
||||||
rect->y2 = videoDisplayHeightGet() - 1;
|
rect->y2 = videoDisplayHeightGet() - 1;
|
||||||
} else {
|
} else {
|
||||||
// Get this window.
|
// 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->x = win->base.r.x;
|
||||||
rect->y = win->base.r.y;
|
rect->y = win->base.r.y;
|
||||||
rect->x2 = win->base.r.x + win->base.r.w;
|
rect->x2 = win->base.r.x + win->base.r.w;
|
||||||
rect->y2 = win->base.r.y + win->base.r.h;
|
rect->y2 = win->base.r.y + win->base.r.h;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clip to screen bounds.
|
// Clip to screen bounds.
|
||||||
if (rect->x < 0) rect->x = 0;
|
if (rect->x < 0) rect->x = 0;
|
||||||
|
@ -827,6 +861,8 @@ void wmRender(void) {
|
||||||
|
|
||||||
} // Window list.
|
} // Window list.
|
||||||
|
|
||||||
|
} // Pass.
|
||||||
|
|
||||||
// Merge adjacent damage areas.
|
// Merge adjacent damage areas.
|
||||||
// For areas to be adjacent they need matching X coordinates with a
|
// For areas to be adjacent they need matching X coordinates with a
|
||||||
// shared Y coordinate or matching Y coordinates with a shared X as
|
// shared Y coordinate or matching Y coordinates with a shared X as
|
||||||
|
@ -906,13 +942,22 @@ void wmRender(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (damageList[k]->window != NULL) {
|
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.
|
// Window content.
|
||||||
surfaceBlit(
|
surfaceBlit(
|
||||||
damageList[k]->rect.x, damageList[k]->rect.y,
|
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.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.x2 - damageList[k]->rect.x, damageList[k]->rect.y2 - damageList[k]->rect.y,
|
||||||
damageList[k]->rect.y2 - damageList[k]->rect.y,
|
|
||||||
damageList[k]->window->cached);
|
damageList[k]->window->cached);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Desktop.
|
// Desktop.
|
||||||
//surfaceBoxFilled(damageList[k]->rect.x, damageList[k]->rect.y, damageList[k]->rect.x2, damageList[k]->rect.y2, GUI_CYAN);
|
//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.
|
// Mouse is always the default pointer unless something changes it for this frame.
|
||||||
guiMousePointerSet(MOUSE_POINTER);
|
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.
|
// Get top window.
|
||||||
win = _windowTop;
|
win = _windowTop;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ typedef struct WindowS {
|
||||||
PointT restoreOffset; // Scroll position 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 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 *cached; // Once rendered, keep a cached copy for faster redrawing.
|
||||||
|
SurfaceT *icon; // Needed for damaged region drawing.
|
||||||
} WindowT;
|
} WindowT;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
|
|
||||||
#define MEMORY_CHECK_ENABLED
|
#define MEMORY_CHECK_ENABLED
|
||||||
|
|
||||||
#define NEW_RENDERER
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
Loading…
Add table
Reference in a new issue