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) {
|
||||
EventT event = { 0 };
|
||||
|
||||
// Read mouse & keyboard.
|
||||
platformEventGet(&event);
|
||||
|
||||
// Paint desktop.
|
||||
surfaceSet(__guiBackBuffer);
|
||||
surfaceClear(GUI_CYAN);
|
||||
|
||||
// Paint GUI.
|
||||
// Read mouse & keyboard.
|
||||
platformEventGet(&event);
|
||||
|
||||
// Handle GUI window manager and widgets.
|
||||
wmUpdate(&event);
|
||||
|
||||
// Paint mouse pointer.
|
||||
surfaceBlitWithTransparency(__guiBackBuffer, event.x, event.y, _mousePointer, _mouseTransparency);
|
||||
surfaceSet(__guiBackBuffer);
|
||||
surfaceBlitWithTransparency(event.x, event.y, _mousePointer, _mouseTransparency);
|
||||
|
||||
// Copy to screen.
|
||||
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]);
|
||||
}
|
||||
|
||||
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
|
||||
surfaceSet(__guiBackBuffer);
|
||||
|
||||
_mousePointer = imageLoad("mouse.png");
|
||||
_mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet(_mousePointer) - 2, 0); // Find our transparency color.
|
||||
_mousePointer = imageLoad("mouse.png");
|
||||
surfaceSet(_mousePointer);
|
||||
_mouseTransparency = surfacePixelGet(_mousePointer, surfaceWidthGet() - 2, 0); // Find our transparency color.
|
||||
|
||||
__guiFontVGA8x8 = fontLoad("vga8x8.dat");
|
||||
__guiFontVGA8x14 = fontLoad("vga8x14.dat");
|
||||
|
@ -130,6 +129,9 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
|
|||
fontSet(__guiFontVGA8x14);
|
||||
fontColorSet(GUI_WHITE, GUI_BLACK);
|
||||
|
||||
__guiBackBuffer = surfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());
|
||||
surfaceSet(__guiBackBuffer);
|
||||
|
||||
wmStartup();
|
||||
|
||||
// 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 surfacePixelSet32(uint16_t x, uint16_t y, ColorT color);
|
||||
|
||||
#include "gui.h"
|
||||
|
||||
void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source) {
|
||||
uint16_t y1;
|
||||
void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source) {
|
||||
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 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.
|
||||
memcpy(target->buffer.bits8, source->buffer.bits8, source->bytes);
|
||||
memcpy(__surfaceActive->buffer.bits8, source->buffer.bits8, source->bytes);
|
||||
} else {
|
||||
// Blit into larger surface.
|
||||
offsetTarget = targetY * __surfaceActive->scanline + targetX * __surfaceBytesPerPixel;
|
||||
offsetSource = 0;
|
||||
for (y1=targetY; y1<targetY+source->height; y1++) {
|
||||
memcpy(&target->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], source->scanline);
|
||||
offsetTarget += target->scanline;
|
||||
offsetTarget = (targetY + y1) * __surfaceActive->scanline + (targetX + x1) * __surfaceBytesPerPixel;
|
||||
offsetSource = y1 * source->scanline + x1 * __surfaceBytesPerPixel;
|
||||
bytes = (x2 - x1) * __surfaceBytesPerPixel;
|
||||
for (y=y1; y<y2; y++) {
|
||||
memcpy(&__surfaceActive->buffer.bits8[offsetTarget], &source->buffer.bits8[offsetSource], bytes);
|
||||
offsetTarget += __surfaceActive->scanline;
|
||||
offsetSource += source->scanline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
|
||||
uint16_t x1;
|
||||
uint16_t y1;
|
||||
uint16_t x2 = source->width;
|
||||
uint16_t y2 = source->height;
|
||||
void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t x1 = 0;
|
||||
int16_t y1 = 0;
|
||||
int16_t x2 = source->width;
|
||||
int16_t y2 = source->height;
|
||||
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
|
||||
if (targetX + x2 > target->width) x2 -= targetX + x2 - target->width;
|
||||
if (targetY + y2 > target->height) y2 -= targetY + y2 - target->height;
|
||||
// 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;
|
||||
|
||||
for (y1=0; y1<y2; y1++) {
|
||||
for (x1=0; x1<x2; x1++) {
|
||||
pixel = surfacePixelGet(source, x1, y1);
|
||||
// Are we still on the screen?
|
||||
if (x1 < 0 || y1 < 0 || x2 < x1 || y2 < y1) return;
|
||||
|
||||
// Blit.
|
||||
for (y=y1; y<y2; y++) {
|
||||
for (x=x1; x<x2; x++) {
|
||||
pixel = surfacePixelGet(source, x, y);
|
||||
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) {
|
||||
return surface->height;
|
||||
int16_t surfaceHeightGet(void) {
|
||||
return __surfaceActive->height;
|
||||
}
|
||||
|
||||
|
||||
|
@ -381,8 +404,8 @@ void surfaceStartup(uint8_t bits) {
|
|||
}
|
||||
|
||||
|
||||
int16_t surfaceWidthGet(SurfaceT *surface) {
|
||||
return surface->width;
|
||||
int16_t surfaceWidthGet() {
|
||||
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);
|
||||
|
||||
|
||||
void surfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source);
|
||||
void surfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
|
||||
void surfaceBlit(int16_t targetX, int16_t targetY, SurfaceT *source);
|
||||
void surfaceBlitWithTransparency(int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent);
|
||||
void surfaceClear(ColorT color);
|
||||
ColorT surfaceColorMake(uint8_t r, uint8_t g, uint8_t b);
|
||||
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 surfaceDestroy(SurfaceT **surface);
|
||||
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 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 surfaceSet(SurfaceT *surface);
|
||||
void surfaceShutdown(void);
|
||||
void surfaceStartup(uint8_t bits);
|
||||
int16_t surfaceWidthGet(SurfaceT *surface);
|
||||
int16_t surfaceWidthGet(void);
|
||||
|
||||
|
||||
#endif // SURFACE_H
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
#include "font.h"
|
||||
|
||||
|
||||
#define USE_CACHING
|
||||
|
||||
|
||||
uint8_t __MAGIC_WINDOW = 0;
|
||||
|
||||
static WindowT **_windowList = NULL;
|
||||
|
@ -172,7 +169,6 @@ void windowPaint(struct WidgetS *widget, ...) {
|
|||
target = surfaceGet();
|
||||
w = (WindowT *)widget;
|
||||
|
||||
#ifdef USE_CACHING
|
||||
// Do we need redrawn?
|
||||
if (guiWidgetDirtyGet(widget)) {
|
||||
guiWidgetDirtySet(widget, 0);
|
||||
|
@ -186,7 +182,8 @@ void windowPaint(struct WidgetS *widget, ...) {
|
|||
// Do we have a cached surface already?
|
||||
if (w->cached) {
|
||||
// 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.
|
||||
surfaceDestroy(&w->cached);
|
||||
}
|
||||
|
@ -198,7 +195,6 @@ void windowPaint(struct WidgetS *widget, ...) {
|
|||
|
||||
// Draw into cache.
|
||||
surfaceSet(w->cached);
|
||||
#endif
|
||||
|
||||
// Determine some colors.
|
||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
|
@ -314,14 +310,13 @@ void windowPaint(struct WidgetS *widget, ...) {
|
|||
// Fake Window contents.
|
||||
surfaceBoxFilled(w->bounds.x, w->bounds.y, w->bounds.x2, w->bounds.y2, GUI_BLACK);
|
||||
|
||||
#ifdef USE_CACHING
|
||||
// Fixup all the widget coordinates.
|
||||
windowMoveTo(w, originalX, originalY);
|
||||
}
|
||||
|
||||
// By now we have a valid cached window. Blit it.
|
||||
surfaceBlit(target, w->base.r.x, w->base.r.y, w->cached);
|
||||
#endif
|
||||
surfaceSet(target);
|
||||
surfaceBlit(w->base.r.x, w->base.r.y, w->cached);
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,8 +354,6 @@ void wmUpdate(EventT *event) {
|
|||
widget->reg->paint(widget);
|
||||
}
|
||||
|
||||
if (dragging) sleep(1);
|
||||
|
||||
// Get top window.
|
||||
win = _windowList[arrlen(_windowList) - 1];
|
||||
|
||||
|
@ -373,6 +366,7 @@ void wmUpdate(EventT *event) {
|
|||
// Is the left mouse button down?
|
||||
if (event->buttons & BUTTON_LEFT) {
|
||||
|
||||
/*
|
||||
// DEBUG - draw active regions. ***TODO*** No resize grabber here.
|
||||
surfaceSet(__guiBackBuffer);
|
||||
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->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);
|
||||
*/
|
||||
|
||||
// Are we currently dragging?
|
||||
if (dragging) {
|
||||
|
|
Loading…
Add table
Reference in a new issue