Clipping working.
This commit is contained in:
parent
9155594947
commit
3c51c33430
4 changed files with 74 additions and 54 deletions
|
@ -28,18 +28,19 @@ static ColorT _mouseTransparency;
|
||||||
void guiEventsDo(void) {
|
void guiEventsDo(void) {
|
||||||
EventT event = { 0 };
|
EventT event = { 0 };
|
||||||
|
|
||||||
// Read mouse & keyboard.
|
|
||||||
platformEventGet(&event);
|
|
||||||
|
|
||||||
// Paint desktop.
|
// Paint desktop.
|
||||||
surfaceSet(__guiBackBuffer);
|
surfaceSet(__guiBackBuffer);
|
||||||
surfaceClear(GUI_CYAN);
|
surfaceClear(GUI_CYAN);
|
||||||
|
|
||||||
// Paint GUI.
|
// Read mouse & keyboard.
|
||||||
|
platformEventGet(&event);
|
||||||
|
|
||||||
|
// Handle GUI window manager and widgets.
|
||||||
wmUpdate(&event);
|
wmUpdate(&event);
|
||||||
|
|
||||||
// Paint mouse pointer.
|
// Paint mouse pointer.
|
||||||
surfaceBlitWithTransparency(__guiBackBuffer, event.x, event.y, _mousePointer, _mouseTransparency);
|
surfaceSet(__guiBackBuffer);
|
||||||
|
surfaceBlitWithTransparency(event.x, event.y, _mousePointer, _mouseTransparency);
|
||||||
|
|
||||||
// Copy to screen.
|
// Copy to screen.
|
||||||
videoBlit(0, 0, __guiBackBuffer);
|
videoBlit(0, 0, __guiBackBuffer);
|
||||||
|
@ -118,11 +119,9 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
|
||||||
__guiBaseColors[i] = surfaceColorMake(EGA[i][0], EGA[i][1], EGA[i][2]);
|
__guiBaseColors[i] = surfaceColorMake(EGA[i][0], EGA[i][1], EGA[i][2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
|
|
||||||
surfaceSet(__guiBackBuffer);
|
|
||||||
|
|
||||||
_mousePointer = imageLoad("mouse.png");
|
_mousePointer = imageLoad("mouse.png");
|
||||||
_mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet(_mousePointer) - 2, 0); // Find our transparency color.
|
surfaceSet(_mousePointer);
|
||||||
|
_mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet() - 2, 0); // Find our transparency color.
|
||||||
|
|
||||||
__guiFontVGA8x8 = fontLoad("vga8x8.dat");
|
__guiFontVGA8x8 = fontLoad("vga8x8.dat");
|
||||||
__guiFontVGA8x14 = fontLoad("vga8x14.dat");
|
__guiFontVGA8x14 = fontLoad("vga8x14.dat");
|
||||||
|
@ -130,6 +129,9 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
|
||||||
fontSet(__guiFontVGA8x14);
|
fontSet(__guiFontVGA8x14);
|
||||||
fontColorSet(GUI_WHITE, GUI_BLACK);
|
fontColorSet(GUI_WHITE, GUI_BLACK);
|
||||||
|
|
||||||
|
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
|
||||||
|
surfaceSet(__guiBackBuffer);
|
||||||
|
|
||||||
wmStartup();
|
wmStartup();
|
||||||
|
|
||||||
// Register all known widgets with the GUI.
|
// Register all known widgets with the GUI.
|
||||||
|
|
|
@ -19,52 +19,75 @@ static void surfacePixelSet8(uint16_t x, uint16_t y, ColorT color);
|
||||||
static void surfacePixelSet16(uint16_t x, uint16_t y, ColorT color);
|
static void surfacePixelSet16(uint16_t x, uint16_t y, ColorT color);
|
||||||
static void surfacePixelSet32(uint16_t x, uint16_t y, ColorT color);
|
static void surfacePixelSet32(uint16_t x, uint16_t y, ColorT color);
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source) {
|
void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source) {
|
||||||
uint16_t y1;
|
int16_t y;
|
||||||
|
int16_t x1 = 0;
|
||||||
|
int16_t y1 = 0;
|
||||||
|
int16_t x2 = source->width;
|
||||||
|
int16_t y2 = source->height;
|
||||||
|
size_t bytes;
|
||||||
size_t offsetTarget;
|
size_t offsetTarget;
|
||||||
size_t offsetSource;
|
size_t offsetSource;
|
||||||
|
|
||||||
if (targetX == 0 && targetY == 0 && target->width == source->width && target->height == source->height) {
|
// Clip on top and left. x1 & y1 are pixel locations inside the source bitmap.
|
||||||
|
if (targetX < 0) x1 = -targetX;
|
||||||
|
if (targetY < 0) y1 = -targetY;
|
||||||
|
|
||||||
|
// Clip on right and bottom.
|
||||||
|
if (targetX + x2 > __surfaceActive->width) x2 -= targetX + x2 - __surfaceActive->width;
|
||||||
|
if (targetY + y2 > __surfaceActive->height) y2 -= targetY + y2 - __surfaceActive->height;
|
||||||
|
|
||||||
|
// Are we still on the screen?
|
||||||
|
if (x1 < 0 || y1 < 0 || x2 < x1 || y2 < y1) return;
|
||||||
|
|
||||||
|
if (targetX == 0 && targetY == 0 && __surfaceActive->width == source->width && __surfaceActive->height == source->height) {
|
||||||
// Direct blit of entire surface.
|
// Direct blit of entire surface.
|
||||||
memcpy(target->buffer.bits8, source->buffer.bits8, source->bytes);
|
memcpy(__surfaceActive->buffer.bits8, source->buffer.bits8, source->bytes);
|
||||||
} else {
|
} else {
|
||||||
// Blit into larger surface.
|
// Blit into larger surface.
|
||||||
offsetTarget = targetY * __surfaceActive->scanline + targetX * __surfaceBytesPerPixel;
|
offsetTarget = (targetY + y1) * __surfaceActive->scanline + (targetX + x1) * __surfaceBytesPerPixel;
|
||||||
offsetSource = 0;
|
offsetSource = y1 * source->scanline + x1 * __surfaceBytesPerPixel;
|
||||||
for (y1=targetY; y1<targetY+source->height; y1++) {
|
bytes = (x2 - x1) * __surfaceBytesPerPixel;
|
||||||
memcpy(&target->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline);
|
for (y=y1; y<y2; y++) {
|
||||||
offsetTarget += target->scanline;
|
memcpy(&__surfaceActive->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], bytes);
|
||||||
|
offsetTarget += __surfaceActive->scanline;
|
||||||
offsetSource += source->scanline;
|
offsetSource += source->scanline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
|
void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
|
||||||
uint16_t x1;
|
int16_t x;
|
||||||
uint16_t y1;
|
int16_t y;
|
||||||
uint16_t x2 = source->width;
|
int16_t x1 = 0;
|
||||||
uint16_t y2 = source->height;
|
int16_t y1 = 0;
|
||||||
|
int16_t x2 = source->width;
|
||||||
|
int16_t y2 = source->height;
|
||||||
ColorT pixel;
|
ColorT pixel;
|
||||||
SurfaceT *t = surfaceGet();
|
|
||||||
|
|
||||||
surfaceSet(target);
|
// Clip on top and left. x1 & y1 are pixel locations inside the source bitmap. ox & oy offset those into screen coordinates.
|
||||||
|
if (targetX < 0) x1 = -targetX;
|
||||||
|
if (targetY < 0) y1 = -targetY;
|
||||||
|
|
||||||
// Clip on right and bottom
|
// Clip on right and bottom.
|
||||||
if (targetX + x2 > target->width) x2 -= targetX + x2 - target->width;
|
if (targetX + x2 > __surfaceActive->width) x2 -= targetX + x2 - __surfaceActive->width;
|
||||||
if (targetY + y2 > target->height) y2 -= targetY + y2 - target->height;
|
if (targetY + y2 > __surfaceActive->height) y2 -= targetY + y2 - __surfaceActive->height;
|
||||||
|
|
||||||
for (y1=0; y1<y2; y1++) {
|
// Are we still on the screen?
|
||||||
for (x1=0; x1<x2; x1++) {
|
if (x1 < 0 || y1 < 0 || x2 < x1 || y2 < y1) return;
|
||||||
pixel = surfacePixelGet(source, x1, y1);
|
|
||||||
|
// Blit.
|
||||||
|
for (y=y1; y<y2; y++) {
|
||||||
|
for (x=x1; x<x2; x++) {
|
||||||
|
pixel = surfacePixelGet(source, x, y);
|
||||||
if (transparent != pixel) {
|
if (transparent != pixel) {
|
||||||
surfacePixelSet(targetX + x1, targetY + y1, pixel);
|
surfacePixelSet(targetX + x, targetY + y, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
surfaceSet(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,8 +202,8 @@ SurfaceT *surfaceGet(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int16_t surfaceHeightGet(SurfaceT *surface) {
|
int16_t surfaceHeightGet(void) {
|
||||||
return surface->height;
|
return __surfaceActive->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,8 +404,8 @@ void surfaceStartup(uint8_t bits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int16_t surfaceWidthGet(SurfaceT *surface) {
|
int16_t surfaceWidthGet() {
|
||||||
return surface->width;
|
return __surfaceActive->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,8 @@ extern ColorT (*surfacePixelGet)(SurfaceT *surface, int16_t x, int16_t y);
|
||||||
extern void (*surfacePixelSet)(uint16_t x, uint16_t y, ColorT color);
|
extern void (*surfacePixelSet)(uint16_t x, uint16_t y, ColorT color);
|
||||||
|
|
||||||
|
|
||||||
void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source);
|
void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source);
|
||||||
void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
|
void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
|
||||||
void surfaceClear(ColorT color);
|
void surfaceClear(ColorT color);
|
||||||
ColorT surfaceColorMake(uint8_t r, uint8_t g, uint8_t b);
|
ColorT surfaceColorMake(uint8_t r, uint8_t g, uint8_t b);
|
||||||
SurfaceT *surfaceCreate(int16_t width, int16_t height);
|
SurfaceT *surfaceCreate(int16_t width, int16_t height);
|
||||||
|
@ -55,14 +55,14 @@ void surfaceBoxFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, Color
|
||||||
void surfaceBoxHighlight(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT highlight, ColorT shadow);
|
void surfaceBoxHighlight(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT highlight, ColorT shadow);
|
||||||
void surfaceDestroy(SurfaceT **surface);
|
void surfaceDestroy(SurfaceT **surface);
|
||||||
SurfaceT *surfaceGet(void);
|
SurfaceT *surfaceGet(void);
|
||||||
int16_t surfaceHeightGet(SurfaceT *surface);
|
int16_t surfaceHeightGet(void);
|
||||||
void surfaceLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
|
void surfaceLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
|
||||||
void surfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c);
|
void surfaceLineH(int16_t x1, int16_t x2, int16_t y, ColorT c);
|
||||||
void surfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c);
|
void surfaceLineV(int16_t x, int16_t y1, int16_t y2, ColorT c);
|
||||||
void surfaceSet(SurfaceT *surface);
|
void surfaceSet(SurfaceT *surface);
|
||||||
void surfaceShutdown(void);
|
void surfaceShutdown(void);
|
||||||
void surfaceStartup(uint8_t bits);
|
void surfaceStartup(uint8_t bits);
|
||||||
int16_t surfaceWidthGet(SurfaceT *surface);
|
int16_t surfaceWidthGet(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // SURFACE_H
|
#endif // SURFACE_H
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
|
|
||||||
#define USE_CACHING
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t __MAGIC_WINDOW = 0;
|
uint8_t __MAGIC_WINDOW = 0;
|
||||||
|
|
||||||
static WindowT **_windowList = NULL;
|
static WindowT **_windowList = NULL;
|
||||||
|
@ -172,7 +169,6 @@ void windowPaint(struct WidgetS *widget, ...) {
|
||||||
target = surfaceGet();
|
target = surfaceGet();
|
||||||
w = (WindowT *)widget;
|
w = (WindowT *)widget;
|
||||||
|
|
||||||
#ifdef USE_CACHING
|
|
||||||
// Do we need redrawn?
|
// Do we need redrawn?
|
||||||
if (guiWidgetDirtyGet(widget)) {
|
if (guiWidgetDirtyGet(widget)) {
|
||||||
guiWidgetDirtySet(widget, 0);
|
guiWidgetDirtySet(widget, 0);
|
||||||
|
@ -186,7 +182,8 @@ void windowPaint(struct WidgetS *widget, ...) {
|
||||||
// Do we have a cached surface already?
|
// Do we have a cached surface already?
|
||||||
if (w->cached) {
|
if (w->cached) {
|
||||||
// Did the size change?
|
// Did the size change?
|
||||||
if ((surfaceWidthGet(w->cached) != w->base.r.w) || (surfaceHeightGet(w->cached) != w->base.r.h)) {
|
surfaceSet(w->cached);
|
||||||
|
if ((surfaceWidthGet() != w->base.r.w) || (surfaceHeightGet() != w->base.r.h)) {
|
||||||
// Yeah. We will recreate it.
|
// Yeah. We will recreate it.
|
||||||
surfaceDestroy(&w->cached);
|
surfaceDestroy(&w->cached);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +195,6 @@ void windowPaint(struct WidgetS *widget, ...) {
|
||||||
|
|
||||||
// Draw into cache.
|
// Draw into cache.
|
||||||
surfaceSet(w->cached);
|
surfaceSet(w->cached);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Determine some colors.
|
// Determine some colors.
|
||||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||||
|
@ -314,14 +310,13 @@ void windowPaint(struct WidgetS *widget, ...) {
|
||||||
// Fake Window contents.
|
// Fake Window contents.
|
||||||
surfaceBoxFilled(w->bounds.x, w->bounds.y, w->bounds.x2, w->bounds.y2, GUI_BLACK);
|
surfaceBoxFilled(w->bounds.x, w->bounds.y, w->bounds.x2, w->bounds.y2, GUI_BLACK);
|
||||||
|
|
||||||
#ifdef USE_CACHING
|
|
||||||
// Fixup all the widget coordinates.
|
// Fixup all the widget coordinates.
|
||||||
windowMoveTo(w, originalX, originalY);
|
windowMoveTo(w, originalX, originalY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// By now we have a valid cached window. Blit it.
|
// By now we have a valid cached window. Blit it.
|
||||||
surfaceBlit(target, w->base.r.x, w->base.r.y, w->cached);
|
surfaceSet(target);
|
||||||
#endif
|
surfaceBlit(w->base.r.x, w->base.r.y, w->cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,8 +354,6 @@ void wmUpdate(EventT *event) {
|
||||||
widget->reg->paint(widget);
|
widget->reg->paint(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragging) sleep(1);
|
|
||||||
|
|
||||||
// Get top window.
|
// Get top window.
|
||||||
win = _windowList[arrlen(_windowList) - 1];
|
win = _windowList[arrlen(_windowList) - 1];
|
||||||
|
|
||||||
|
@ -373,6 +366,7 @@ void wmUpdate(EventT *event) {
|
||||||
// Is the left mouse button down?
|
// Is the left mouse button down?
|
||||||
if (event->buttons & BUTTON_LEFT) {
|
if (event->buttons & BUTTON_LEFT) {
|
||||||
|
|
||||||
|
/*
|
||||||
// DEBUG - draw active regions. ***TODO*** No resize grabber here.
|
// DEBUG - draw active regions. ***TODO*** No resize grabber here.
|
||||||
surfaceSet(__guiBackBuffer);
|
surfaceSet(__guiBackBuffer);
|
||||||
surfaceBox(win->base.r.x, win->base.r.y, x2, y2, GUI_YELLOW);
|
surfaceBox(win->base.r.x, win->base.r.y, x2, y2, GUI_YELLOW);
|
||||||
|
@ -381,6 +375,7 @@ void wmUpdate(EventT *event) {
|
||||||
surfaceBox(win->titlebar.x, win->titlebar.y, win->titlebar.x2, win->titlebar.y2, GUI_LIGHTCYAN);
|
surfaceBox(win->titlebar.x, win->titlebar.y, win->titlebar.x2, win->titlebar.y2, GUI_LIGHTCYAN);
|
||||||
surfaceBox(win->minimize.x, win->minimize.y, win->minimize.x2, win->minimize.y2, GUI_LIGHTGREEN);
|
surfaceBox(win->minimize.x, win->minimize.y, win->minimize.x2, win->minimize.y2, GUI_LIGHTGREEN);
|
||||||
surfaceBox(win->maximize.x, win->maximize.y, win->maximize.x2, win->maximize.y2, GUI_RED);
|
surfaceBox(win->maximize.x, win->maximize.y, win->maximize.x2, win->maximize.y2, GUI_RED);
|
||||||
|
*/
|
||||||
|
|
||||||
// Are we currently dragging?
|
// Are we currently dragging?
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue