roo-e/src/gui/widgets/
This commit is contained in:
parent
4923843f38
commit
a8168cd253
10 changed files with 157 additions and 99 deletions
|
@ -52,6 +52,7 @@ HEADERS += \
|
|||
src/gui/gui.h \
|
||||
src/gui/image.h \
|
||||
src/gui/surface.h \
|
||||
src/gui/widgets/button.h \
|
||||
src/gui/widgets/label.h \
|
||||
src/gui/widgets/picture.h \
|
||||
src/gui/wmwindow.h \
|
||||
|
@ -69,6 +70,7 @@ SOURCES += \
|
|||
src/gui/gui.c \
|
||||
src/gui/image.c \
|
||||
src/gui/surface.c \
|
||||
src/gui/widgets/button.c \
|
||||
src/gui/widgets/label.c \
|
||||
src/gui/widgets/picture.c \
|
||||
src/gui/wmwindow.c \
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
#include "array.h"
|
||||
|
||||
#include "wmwindow.h"
|
||||
#include "widgets/button.h"
|
||||
#include "widgets/label.h"
|
||||
#include "widgets/picture.h"
|
||||
|
||||
|
||||
typedef struct WidgetCatalogS {
|
||||
|
@ -191,8 +193,12 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
|
|||
|
||||
wmStartup();
|
||||
|
||||
// Always have to have a window type.
|
||||
// Register standard widgets.
|
||||
guiRegister(windowRegister);
|
||||
guiRegister(labelRegister);
|
||||
guiRegister(pictureRegister);
|
||||
guiRegister(buttonRegister);
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -203,15 +209,13 @@ void guiStop(void) {
|
|||
}
|
||||
|
||||
|
||||
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h) {
|
||||
widget->magic = magic;
|
||||
|
||||
widget->r.x = x;
|
||||
widget->r.y = y;
|
||||
widget->r.w = w;
|
||||
widget->r.h = h;
|
||||
|
||||
widget->reg = hmget(_widgetCatalog, magic);
|
||||
if (!widget->reg) widget->reg = hmget(_widgetCatalog, magic);
|
||||
|
||||
widget->flags |= WIDGET_DIRTY; // Everything starts dirty to force a paint.
|
||||
}
|
||||
|
@ -235,3 +239,14 @@ void guiWidgetDirtySet(WidgetT *widget, uint8_t dirty) {
|
|||
widget->flags &= ~WIDGET_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void guiWidgetPaintManually(WidgetT *widget, int16_t x, int16_t y) {
|
||||
RectT r = widget->r;
|
||||
|
||||
guiWidgetDirtySet(widget, 1);
|
||||
widget->r.x = x;
|
||||
widget->r.y = y;
|
||||
widget->reg->paint(widget);
|
||||
widget->r = r;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,17 @@
|
|||
#define WIDGET_HIDDEN 2
|
||||
#define WIDGET_DISABLED 4
|
||||
|
||||
#define CLICK_LEFT_CANCEL 1
|
||||
#define CLICK_LEFT_DOWN 2
|
||||
#define CLICK_LEFT_UP 3
|
||||
|
||||
|
||||
struct WidgetS;
|
||||
struct WindowS;
|
||||
|
||||
typedef void (*GuiCallbackT)(void *data, ...);
|
||||
typedef void (*WidgetEventT)(struct WidgetS *widget, ...);
|
||||
typedef void (*ClickHandlerT)(struct WidgetS *widget, uint16_t x, uint16_t y, void *data);
|
||||
typedef void (*ClickHandlerT)(struct WidgetS *widget, uint16_t x, uint16_t y, uint8_t event, void *data);
|
||||
|
||||
typedef struct PointS {
|
||||
int16_t x;
|
||||
|
@ -70,11 +75,11 @@ typedef struct RegisterS {
|
|||
} RegisterT;
|
||||
|
||||
typedef struct WidgetS {
|
||||
uint8_t magic; // Magic ID of widget.
|
||||
RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2!
|
||||
RegisterT *reg; // Registration information.
|
||||
void *data; // Pointer to arbitrary data for user.
|
||||
uint8_t flags; // Widget flags (see defines above).
|
||||
uint8_t magic; // Magic ID of widget.
|
||||
RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2!
|
||||
RegisterT *reg; // Registration information.
|
||||
void *data; // Pointer to arbitrary data for user.
|
||||
uint8_t flags; // Widget flags (see defines above).
|
||||
} WidgetT;
|
||||
|
||||
typedef RegisterT *(*WidgetRegisterT)(uint8_t);
|
||||
|
@ -123,10 +128,11 @@ void guiRun(void);
|
|||
void guiShutdown(void);
|
||||
uint8_t guiStartup(int16_t width, int16_t height, int16_t depth);
|
||||
void guiStop(void);
|
||||
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h);
|
||||
void guiWidgetDestroy(WidgetT *widget);
|
||||
uint8_t guiWidgetDirtyGet(WidgetT *widget);
|
||||
void guiWidgetDirtySet(WidgetT *widget, uint8_t dirty);
|
||||
void guiWidgetPaintManually(WidgetT *widget, int16_t x, int16_t y);
|
||||
|
||||
|
||||
#endif // GUI_H
|
||||
|
|
|
@ -46,25 +46,23 @@ void labelColorSet(LabelT *label, ColorT foreground, ColorT background) {
|
|||
}
|
||||
|
||||
|
||||
LabelT *labelCreate(uint16_t x, uint16_t y, uint8_t alignment, FontT *font, char *contents, ...) {
|
||||
LabelT *l = NULL;
|
||||
void labelContentSet(LabelT *label, char *content) {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
|
||||
NEW(LabelT, l);
|
||||
memset(l, 0, sizeof(LabelT));
|
||||
l->font = font;
|
||||
l->text = strdup(contents);
|
||||
l->foreground = GUI_BLACK;
|
||||
l->background = GUI_LIGHTGRAY;
|
||||
l->modsEnabled = 0;
|
||||
l->alignment = alignment;
|
||||
l->pos.x = x;
|
||||
l->pos.y = y;
|
||||
// ***TODO*** This will not redraw properly if the size shrinks.
|
||||
|
||||
width = fontWidthCharactersGet(contents) * fontWidthGet(font);
|
||||
height = fontHeightGet(font);
|
||||
switch (alignment) {
|
||||
if (label->text) DEL(label->text);
|
||||
label->text = strdup(content);
|
||||
|
||||
width = fontWidthCharactersGet(content) * fontWidthGet(label->font);
|
||||
height = fontHeightGet(label->font);
|
||||
x = label->pos.x;
|
||||
y = label->pos.y;
|
||||
|
||||
switch (label->alignment) {
|
||||
case LABEL_ALIGN_LEFT:
|
||||
// Passed in values are fine.
|
||||
break;
|
||||
|
@ -78,7 +76,29 @@ LabelT *labelCreate(uint16_t x, uint16_t y, uint8_t alignment, FontT *font, char
|
|||
break;
|
||||
}
|
||||
|
||||
guiWidgetBaseSet((WidgetT *)l, __MAGIC_LABEL, x, y, width, height);
|
||||
// This is kind of ugly. It moves the actual position to compensate for alignment.
|
||||
label->base.r.x = x;
|
||||
label->base.r.y = y;
|
||||
|
||||
// Fixup width and height.
|
||||
guiWidgetBaseSet(W(label), __MAGIC_LABEL, width, height);
|
||||
}
|
||||
|
||||
|
||||
LabelT *labelCreate(uint8_t alignment, FontT *font, char *contents, ...) {
|
||||
LabelT *l = NULL;
|
||||
|
||||
NEW(LabelT, l);
|
||||
memset(l, 0, sizeof(LabelT));
|
||||
l->font = font;
|
||||
l->foreground = GUI_BLACK;
|
||||
l->background = GUI_LIGHTGRAY;
|
||||
l->modsEnabled = 0;
|
||||
l->alignment = alignment;
|
||||
l->text = strdup(contents);
|
||||
l->pos.x = -1; // Flag for later indicating we need to set up the widget position.
|
||||
|
||||
guiWidgetBaseSet(W(l), __MAGIC_LABEL, 0, 0);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -93,7 +113,19 @@ static void labelDestroy(struct WidgetS *widget, ...) {
|
|||
|
||||
|
||||
static void labelPaint(struct WidgetS *widget, ...) {
|
||||
LabelT *l = (LabelT *)widget;
|
||||
LabelT *l = (LabelT *)widget;
|
||||
char *temp;
|
||||
|
||||
// Do we need to finish setting up?
|
||||
if (l->pos.x < 0) {
|
||||
// Remember our pre-alignment position (or "anchor").
|
||||
l->pos.x = l->base.r.x;
|
||||
l->pos.y = l->base.r.y;
|
||||
// Can't pass l->text to labelContentSet.
|
||||
temp = strdup(l->text);
|
||||
labelContentSet(l, temp);
|
||||
DEL(temp);
|
||||
}
|
||||
|
||||
if (guiWidgetDirtyGet(widget)) {
|
||||
guiWidgetDirtySet(widget, 0);
|
||||
|
|
|
@ -52,7 +52,8 @@ extern uint8_t __MAGIC_LABEL; // Magic ID assigned to us from the GUI.
|
|||
|
||||
void labelClickSet(LabelT *label, ClickHandlerT handler, void *data);
|
||||
void labelColorSet(LabelT *label, ColorT foreground, ColorT background);
|
||||
LabelT *labelCreate(uint16_t x, uint16_t y, uint8_t alignment, FontT *font, char *contents, ...);
|
||||
void labelContentSet(LabelT *label, char *content);
|
||||
LabelT *labelCreate(uint8_t alignment, FontT *font, char *contents, ...);
|
||||
RegisterT *labelRegister(uint8_t magic);
|
||||
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ void pictureClickSet(PictureT *picture, ClickHandlerT handler, void *data) {
|
|||
}
|
||||
|
||||
|
||||
PictureT *pictureCreate(uint16_t x, uint16_t y, char *filename, ...) {
|
||||
PictureT *pictureCreate(char *filename, ...) {
|
||||
PictureT *p = NULL;
|
||||
|
||||
NEW(PictureT, p);
|
||||
|
@ -51,7 +51,7 @@ PictureT *pictureCreate(uint16_t x, uint16_t y, char *filename, ...) {
|
|||
DEL(p);
|
||||
return NULL;
|
||||
}
|
||||
guiWidgetBaseSet((WidgetT *)p, __MAGIC_PICTURE, x, y, surfaceWidthGet(p->picture), surfaceHeightGet(p->picture));
|
||||
guiWidgetBaseSet(W(p), __MAGIC_PICTURE, surfaceWidthGet(p->picture), surfaceHeightGet(p->picture));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ extern uint8_t __MAGIC_PICTURE; // Magic ID assigned to us from the GUI.
|
|||
|
||||
|
||||
void pictureClickSet(PictureT *picture, ClickHandlerT handler, void *data);
|
||||
PictureT *pictureCreate(uint16_t x, uint16_t y, char *filename, ...);
|
||||
PictureT *pictureCreate(char *filename, ...);
|
||||
RegisterT *pictureRegister(uint8_t magic);
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ static void windowPaint(struct WidgetS *widget, ...);
|
|||
static void windowScrollHorizontalHandler(EventT *e, WindowT *w);
|
||||
static void windowScrollVerticalHandler(EventT *e, WindowT *w);
|
||||
|
||||
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY);
|
||||
|
||||
|
||||
static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
||||
char c;
|
||||
|
@ -63,6 +65,8 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
int16_t originalY;
|
||||
double d;
|
||||
RectT originalBounds;
|
||||
ColorT scrollBackgroundColor;
|
||||
ColorT scrollThumbColor;
|
||||
ColorT titleBackgroundColor;
|
||||
ColorT widgetColor;
|
||||
SurfaceT *target = surfaceGet();
|
||||
|
@ -91,8 +95,10 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
|
||||
if (redrawWindow) {
|
||||
// Determine some colors.
|
||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||
scrollBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
scrollThumbColor = GUI_LIGHTGRAY;
|
||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||
|
||||
// Get ready!
|
||||
x1 = w->base.r.x;
|
||||
|
@ -203,13 +209,13 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->scrollv.y = y1;
|
||||
w->scrollv.y2 = y2;
|
||||
// Draw scroll bar.
|
||||
surfaceBoxFilled(w->scrollv.x + 1, w->scrollv.y + 1, w->scrollv.x2 - 1, w->scrollv.y2 - 1, titleBackgroundColor);
|
||||
surfaceBoxFilled(w->scrollv.x + 1, w->scrollv.y + 1, w->scrollv.x2 - 1, w->scrollv.y2 - 1, scrollBackgroundColor);
|
||||
surfaceBoxHighlight(w->scrollv.x, w->scrollv.y, w->scrollv.x2, w->scrollv.y2, GUI_WHITE, GUI_BLACK);
|
||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y + (WIDGET_SIZE - 1), GUI_BLACK);
|
||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y2 - (WIDGET_SIZE - 1), GUI_WHITE);
|
||||
// Prepare font.
|
||||
fontSet(__guiFontVGA8x8);
|
||||
fontColorSet(widgetColor, titleBackgroundColor);
|
||||
fontColorSet(widgetColor, scrollBackgroundColor);
|
||||
// Draw arrows.
|
||||
fontRender("\x1e", w->scrollv.x + 7, w->scrollv.y + 7);
|
||||
fontRender("\x1f", w->scrollv.x + 7, w->scrollv.y2 - 12);
|
||||
|
@ -226,7 +232,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->scrollh.y2 = y2;
|
||||
w->scrollh.y = w->scrollh.y2 - (WIDGET_SIZE - 1);
|
||||
// Draw scroll bar.
|
||||
surfaceBoxFilled(w->scrollh.x + 1, w->scrollh.y + 1, w->scrollh.x2 - 1, w->scrollh.y2 - 1, titleBackgroundColor);
|
||||
surfaceBoxFilled(w->scrollh.x + 1, w->scrollh.y + 1, w->scrollh.x2 - 1, w->scrollh.y2 - 1, scrollBackgroundColor);
|
||||
surfaceBoxHighlight(w->scrollh.x, w->scrollh.y, w->scrollh.x2, w->scrollh.y2, GUI_WHITE, GUI_BLACK);
|
||||
surfaceLineV(w->scrollh.x + (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_BLACK);
|
||||
surfaceLineV(w->scrollh.x2 - (WIDGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_WHITE);
|
||||
|
@ -237,7 +243,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
}
|
||||
// Prepare font.
|
||||
fontSet(__guiFontVGA8x8);
|
||||
fontColorSet(widgetColor, titleBackgroundColor);
|
||||
fontColorSet(widgetColor, scrollBackgroundColor);
|
||||
// Draw arrows.
|
||||
fontRender("\x11", w->scrollh.x + 7, w->scrollh.y + 7);
|
||||
fontRender("\x10", w->scrollh.x2 - 12, w->scrollh.y + 7);
|
||||
|
@ -270,7 +276,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
// Clamp overflow due to doubles and my off-by-one brain.
|
||||
if (w->thumbv.y2 >= w->thumbv.y + i - 1) w->thumbv.y2 = w->thumbv.y + i - 1;
|
||||
// Draw thumb.
|
||||
surfaceBoxFilled(w->thumbv.x + 1, w->thumbv.y + 1, w->thumbv.x2 - 1, w->thumbv.y2 - 1, widgetColor);
|
||||
surfaceBoxFilled(w->thumbv.x + 1, w->thumbv.y + 1, w->thumbv.x2 - 1, w->thumbv.y2 - 1, scrollThumbColor);
|
||||
surfaceBoxHighlight(w->thumbv.x, w->thumbv.y, w->thumbv.x2, w->thumbv.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
||||
|
@ -290,7 +296,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
// Clamp overflow due to doubles and my off-by-one brain.
|
||||
if (w->thumbh.x2 >= w->thumbh.x + i - 1) w->thumbh.x2 = w->thumbh.x + i - 1;
|
||||
// Draw thumb.
|
||||
surfaceBoxFilled(w->thumbh.x + 1, w->thumbh.y + 1, w->thumbh.x2 - 1, w->thumbh.y2 - 1, widgetColor);
|
||||
surfaceBoxFilled(w->thumbh.x + 1, w->thumbh.y + 1, w->thumbh.x2 - 1, w->thumbh.y2 - 1, scrollThumbColor);
|
||||
surfaceBoxHighlight(w->thumbh.x, w->thumbh.y, w->thumbh.x2, w->thumbh.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
||||
|
@ -357,26 +363,11 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
|
|||
|
||||
NEW(WindowT, win);
|
||||
memset(win, 0, sizeof(WindowT));
|
||||
guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, x, y, w, h);
|
||||
win->title = strdup(title);
|
||||
win->flags = (uint8_t)flags;
|
||||
|
||||
/*
|
||||
// ***DEBUG*** Hackery to get contents before we have widgets.
|
||||
static uint8_t image = 1;
|
||||
static char name[16];
|
||||
windowCache(win, 1);
|
||||
width = win->bounds.x2 - win->bounds.x;
|
||||
height = win->bounds.y2 - win->bounds.y;
|
||||
guiWidgetDirtySet(W(win), 1);
|
||||
sprintf(name, "back%d.png", image);
|
||||
win->content = imageLoad(name);
|
||||
if (image == 3) {
|
||||
win->offset.x = 100;//(surfaceWidthGet(win->content) - width) * 0.5;
|
||||
win->offset.y = 100;//(surfaceHeightGet(win->content) - height) * 0.5;
|
||||
}
|
||||
image++;
|
||||
*/
|
||||
guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, w, h);
|
||||
win->base.r.x = x;
|
||||
win->base.r.y = y;
|
||||
win->title = strdup(title);
|
||||
win->flags = (uint8_t)flags;
|
||||
|
||||
// If the window is resizable, we need to get two more arguments for the content size.
|
||||
if (win->flags & WIN_RESIZE) {
|
||||
|
@ -408,13 +399,14 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
|
|||
|
||||
|
||||
static void windowDestroy(struct WidgetS *widget, ...) {
|
||||
uint16_t i;
|
||||
uint16_t c;
|
||||
WindowT *window = (WindowT *)widget;
|
||||
uint16_t i;
|
||||
uint16_t c;
|
||||
WindowT *window = (WindowT *)widget;
|
||||
|
||||
// Remove it from the window list, if it exists there.
|
||||
for (i=0; i<arrlen(_windowList); i++) {
|
||||
if (window == _windowList[i]) {
|
||||
_windowList[i] = NULL;
|
||||
arrdel(_windowList, i);
|
||||
break;
|
||||
}
|
||||
|
@ -863,7 +855,9 @@ static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
|
|||
}
|
||||
|
||||
|
||||
void windowWidgetAdd(WindowT *window, WidgetT *widget) {
|
||||
void windowWidgetAdd(WindowT *window, int16_t x, int16_t y, WidgetT *widget) {
|
||||
widget->r.x = x;
|
||||
widget->r.y = y;
|
||||
arrput(window->children, widget);
|
||||
}
|
||||
|
||||
|
@ -883,7 +877,7 @@ void windowWidgetRemove(WindowT *window, WidgetT *widget) {
|
|||
void wmShutdown(void) {
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i<arrlen(_windowList); i++) guiWidgetDestroy((WidgetT *)_windowList[i]);
|
||||
for (i=0; i<arrlen(_windowList); i++) guiWidgetDestroy(W(_windowList[i]));
|
||||
arrfree(_windowList);
|
||||
}
|
||||
|
||||
|
@ -996,19 +990,11 @@ void wmUpdate(EventT *event) {
|
|||
break;
|
||||
}
|
||||
|
||||
// Are we inside the window content? Most likely, check this first.
|
||||
if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) {
|
||||
// Are we over a widget?
|
||||
x = event->x - win->bounds.x + win->offset.x;
|
||||
y = event->y - win->bounds.y + win->offset.y;
|
||||
for (i=0; i<arrlen(win->children); i++) {
|
||||
widget = win->children[i];
|
||||
if (x >= widget->r.x && x < widget->r.x + widget->r.x2 && y >= widget->r.y && y < widget->r.y + widget->r.y2) {
|
||||
// Remember this widget for when left-up occurs.
|
||||
widgetDown = widget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Are we over a widget?
|
||||
widget = wuWidgetUnderMouseGet(win, event, &x, &y);
|
||||
if (widget) {
|
||||
if (widget->reg->click) widget->reg->click(widget, x - widget->r.x, y - widget->r.y, CLICK_LEFT_DOWN, widget->data);
|
||||
widgetDown = widget;
|
||||
}
|
||||
|
||||
// Are we inside the close button? Does not include button frame on purpose.
|
||||
|
@ -1140,16 +1126,9 @@ void wmUpdate(EventT *event) {
|
|||
// Are we still inside the window content?
|
||||
if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) {
|
||||
// Are we stll over the same widget?
|
||||
x = event->x - win->bounds.x + win->offset.x;
|
||||
y = event->y - win->bounds.y + win->offset.y;
|
||||
for (i=0; i<arrlen(win->children); i++) {
|
||||
widget = win->children[i];
|
||||
if (widget == widgetDown && x >= widget->r.x && x < widget->r.x + widget->r.x2 && y >= widget->r.y && y < widget->r.y + widget->r.y2) {
|
||||
// Send to widget for processing.
|
||||
if (widget->reg->click) widget->reg->click(widget, x - widget->r.x, y - widget->r.y, widget->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
widget = wuWidgetUnderMouseGet(win, event, &x, &y);
|
||||
// Send to widget for processing or send cancel. Convert mouse to widget-local coordinates.
|
||||
if (widgetDown->reg->click) widgetDown->reg->click(widgetDown, x - widgetDown->r.x, y - widgetDown->r.y, (widget == widgetDown) ? CLICK_LEFT_UP : CLICK_LEFT_CANCEL, widgetDown->data);
|
||||
}
|
||||
widgetDown = NULL;
|
||||
} // widgetDown
|
||||
|
@ -1161,5 +1140,27 @@ void wmUpdate(EventT *event) {
|
|||
} // Left button processing.
|
||||
|
||||
} // Do we have windows?
|
||||
|
||||
}
|
||||
|
||||
|
||||
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY) {
|
||||
int16_t i;
|
||||
WidgetT *widget;
|
||||
|
||||
// Are we over the provided window?
|
||||
if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) {
|
||||
// Find window-local mouse coordinates.
|
||||
*localX = event->x - win->bounds.x + win->offset.x;
|
||||
*localY = event->y - win->bounds.y + win->offset.y;
|
||||
// Find widget under mouse.
|
||||
for (i=0; i<arrlen(win->children); i++) {
|
||||
widget = win->children[i];
|
||||
if (*localX >= widget->r.x && *localX < widget->r.x + widget->r.x2 && *localY >= widget->r.y && *localY < widget->r.y + widget->r.y2) {
|
||||
// Return this widget.
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ void windowMinimize(WindowT *win);
|
|||
void windowMove(WindowT *win, uint16_t x, uint16_t y);
|
||||
RegisterT *windowRegister(uint8_t magic);
|
||||
void windowResize(WindowT *win, uint16_t width, uint16_t height);
|
||||
void windowWidgetAdd(WindowT *window, WidgetT *widget);
|
||||
void windowWidgetAdd(WindowT *window, int16_t x, int16_t y, WidgetT *widget);
|
||||
void windowWidgetRemove(WindowT *window, WidgetT *widget);
|
||||
|
||||
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
#include "gui/wmwindow.h"
|
||||
#include "gui/widgets/label.h"
|
||||
#include "gui/widgets/picture.h"
|
||||
#include "gui/widgets/button.h"
|
||||
|
||||
|
||||
void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, void *data) {
|
||||
void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) {
|
||||
(void)widget;
|
||||
logWrite("%dx%d %s\n", x, y, data);
|
||||
logWrite("%d %dx%d %s\n", event, x, y, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +40,7 @@ int main(int argc, char *argv[]) {
|
|||
char title[256];
|
||||
uint16_t i;
|
||||
LabelT *l = NULL;
|
||||
ButtonT *b = NULL;
|
||||
WindowT *w = NULL;
|
||||
|
||||
(void)argc;
|
||||
|
@ -48,18 +50,17 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if (guiStartup(800, 600, 16) == SUCCESS) {
|
||||
|
||||
// Register all desired widgets with Roo/E.
|
||||
guiRegister(labelRegister);
|
||||
guiRegister(pictureRegister);
|
||||
|
||||
for (i=1; i<4; i++) {
|
||||
sprintf(title, "Testing %d", i);
|
||||
w = windowCreate(i * 50, i * 50, 300, 200, title, WIN_STANDARD, 640, 480);
|
||||
|
||||
l = labelCreate(150, 10, LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label Test");
|
||||
l = labelCreate(LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label");
|
||||
labelColorSet(l, __guiBaseColors[i], GUI_BLACK);
|
||||
labelClickSet(l, clickHandler, title);
|
||||
windowWidgetAdd(w, W(l));
|
||||
windowWidgetAdd(w, 20, 10, W(l));
|
||||
|
||||
b = buttonCreate("Button", clickHandler, NULL);
|
||||
windowWidgetAdd(w, 20, 40, W(b));
|
||||
}
|
||||
guiRun();
|
||||
guiShutdown();
|
||||
|
|
Loading…
Add table
Reference in a new issue