Function names are now methodItemVerb

This commit is contained in:
Scott Duensing 2021-11-07 18:45:50 -06:00
parent 22954a848a
commit cf12d340bd
32 changed files with 892 additions and 872 deletions

View file

@ -51,22 +51,22 @@ static int16_t _key = 0;
static int16_t _meta = 0;
uint8_t keyAlt(void) {
uint8_t keyAltGet(void) {
return 0 != (_meta & (1 << META_ALT)) + (_meta & (1 << META_ALT_LEFT)) + (_meta & (1 << META_ALT_RIGHT));
}
uint8_t keyASCII(void) {
uint8_t keyASCIIGet(void) {
return LOW_BYTE(_key);
}
uint8_t keyControl(void) {
uint8_t keyControlGet(void) {
return 0 != (_meta & (1 << META_CONTROL)) + (_meta & (1 << META_CONTROL_LEFT)) + (_meta & (1 << META_CONTROL_RIGHT));
}
uint8_t keyExtended(void) {
uint8_t keyExtendedGet(void) {
return _extended;
}
@ -101,12 +101,12 @@ uint8_t keyHit(void) {
}
uint8_t keyScanCode(void) {
uint8_t keyScanCodeGet(void) {
return HIGH_BYTE(_key);
}
uint8_t keyShift(void) {
uint8_t keyShiftGet(void) {
return 0 != (_meta & (1 << META_SHIFT_LEFT)) + (_meta & (1 << META_SHIFT_RIGHT));
}

View file

@ -21,6 +21,7 @@
#include "os.h"
#include "vesa.h"
#include "surface.h"
// http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
@ -134,20 +135,18 @@ typedef struct VBESurfaceS {
static void vbeCreatePalette(void);
static VBEInfoT *vbeGetInfo(void);
static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber);
static VBEModeInfoT *vbeGetModeInfoPtr(void);
//static VBEModeInfoT *vbeGetModeInfoPtr(void);
static void *vbeGetPmodeInterface(void);
static VBESurfaceT *vbeGetVBESurfacePtr(void);
//static VBESurfaceT *vbeGetVBESurfacePtr(void);
static uint8_t vbeIsDesiredMode(void);
static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp);
//static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp);
static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp);
static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline);
//static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline);
static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber);
static uint16_t vbeSetScanlineLength(uint16_t pixelLength);
static void (*pmVBESetDisplayStart)(void);
void (*surfacePutPixel)(uint16_t x, uint16_t y, ColorT color);
static VBESurfaceT _vbeSurface;
static VBEInfoT _vbeInfo;
@ -306,9 +305,11 @@ static VBEModeInfoT *vbeGetModeInfo(uint16_t vbeModeNumber) {
}
/*
static VBEModeInfoT *vbeGetModeInfoPtr(void) {
return(&_vbeModeInfo);
}
*/
static void *vbeGetPmodeInterface(void) {
@ -361,9 +362,11 @@ static void *vbeGetPmodeInterface(void) {
}
/*
static VBESurfaceT *vbeGetVBESurfacePtr(void) {
return(&_vbeSurface);
}
*/
static uint8_t vbeIsDesiredMode(void) {
@ -397,6 +400,7 @@ ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) {
}
/*
static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
uint16_t vbeModeNumber;
__dpmi_meminfo m;
@ -419,10 +423,12 @@ static VBESurfaceT *vbeModeInit(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
return(&_vbeSurface);
}
*/
void vbePresent(void) {
_movedatal(_my_ds(), (int32_t)surfaceOffscreenGet()->buffer.bits32, _vbeSurface.lfbSelector, 0x0, _vbeSurface.screenDWords);
SurfaceT *o = surfaceOffScreenGet();
_movedatal(_my_ds(), (int32_t)o->buffer.bits32, _vbeSurface.lfbSelector, 0x0, _vbeSurface.screenDWords);
}
@ -444,6 +450,7 @@ static uint16_t vbeSelectModeNumber(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
}
/*
static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline) {
__dpmi_regs r;
int32_t address;
@ -477,6 +484,7 @@ static void vbeSetDisplayStart(uint32_t pixel, uint32_t scanline) {
r.x.dx = scanline;
__dpmi_int(0x10, &r);
}
*/
static VBESurfaceT *vbeSetMode(uint16_t vbeModeNumber) {

View file

@ -26,6 +26,11 @@ static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_
static void buttonPaint(WidgetT *widget, RectT pos);
void buttonClickHandlerSet(ButtonT *button, widgetCallback callback) {
button->clicked = callback;
}
static void buttonDel(WidgetT **widget) {
ButtonT *b = (ButtonT *)*widget;
@ -43,10 +48,10 @@ WidgetT *buttonInit(WidgetT *button, char *title, widgetCallback callback) {
b->base.mouseEventMethod = buttonMouseEvent;
b->title = NULL;
buttonSetClickHandler(b, callback);
buttonClickHandlerSet(b, callback);
// Width is set in buttonSetTitle
buttonSetTitle(b, title);
buttonTitleSet(b, title);
return button;
}
@ -115,11 +120,11 @@ static void buttonPaint(WidgetT *widget, RectT pos) {
// Draw bezel.
for (i=0; i<_guiMetric[METRIC_BUTTON_BEZEL_SIZE]; i++) {
surfaceDrawHighlightFrame(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, highlight, shadow);
surfaceHighlightFrameDraw(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, highlight, shadow);
}
// Draw background (depends on x from above).
surfaceDrawRectangleFilled(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, _guiColor[COLOR_BUTTON_BACKGROUND]);
surfaceRectangleFilledDraw(pos.x + i, pos.y + i, pos.x + pos.w - i, pos.y + pos.h - i, _guiColor[COLOR_BUTTON_BACKGROUND]);
// Draw title (depends on x from above).
fontRender(_guiFont, b->title, _guiColor[COLOR_BUTTON_TEXT], _guiColor[COLOR_BUTTON_BACKGROUND], pos.x + i + _guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] + active, pos.y + i + _guiMetric[METRIC_BUTTON_VERTICAL_PADDING] + active);
@ -129,12 +134,7 @@ static void buttonPaint(WidgetT *widget, RectT pos) {
}
void buttonSetClickHandler(ButtonT *button, widgetCallback callback) {
button->clicked = callback;
}
void buttonSetTitle(ButtonT *button, char *title) {
void buttonTitleSet(ButtonT *button, char *title) {
if (button->title) free(button->title);
button->title = strdup(title);
button->base.pos.w = (strlen(title) * fontWidthGet(_guiFont)) + (_guiMetric[METRIC_BUTTON_HORIZONTAL_PADDING] * 2) + (_guiMetric[METRIC_BUTTON_BEZEL_SIZE] * 2);

View file

@ -33,10 +33,10 @@ typedef struct ButtonS {
} ButtonT;
void buttonClickHandlerSet(ButtonT *button, widgetCallback callback);
WidgetT *buttonInit(WidgetT *button, char *title, widgetCallback callback);
ButtonT *buttonNew(uint16_t x, uint16_t y, char *title, widgetCallback callback);
void buttonSetClickHandler(ButtonT *button, widgetCallback callback);
void buttonSetTitle(ButtonT *button, char *title);
void buttonTitleSet(ButtonT *button, char *title);
#endif // BUTTON_H

View file

@ -26,6 +26,11 @@ static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint1
static void checkboxPaint(WidgetT *widget, RectT pos);
void checkboxClickHandlerSet(CheckboxT *checkbox, widgetCallback callback) {
checkbox->clicked = callback;
}
static void checkboxDel(WidgetT **widget) {
CheckboxT *c = (CheckboxT *)*widget;
@ -35,11 +40,6 @@ static void checkboxDel(WidgetT **widget) {
}
uint8_t checkboxGetValue(CheckboxT *checkbox) {
return GUI_GET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
}
WidgetT *checkboxInit(WidgetT *widget, char *title) {
CheckboxT *c = (CheckboxT *)widget;
@ -49,7 +49,7 @@ WidgetT *checkboxInit(WidgetT *widget, char *title) {
c->title = NULL;
c->clicked = NULL;
checkboxSetTitle(c, title);
checkboxTitleSet(c, title);
return widget;
}
@ -64,7 +64,7 @@ static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint1
if (event == MOUSE_EVENT_LEFT_UP) {
// Toggle value.
checkboxSetValue(c, !checkboxGetValue(c));
checkboxValueSet(c, !checkboxValueGet(c));
// Fire callback on mouse up.
if (c->clicked) c->clicked(widget);
}
@ -100,7 +100,7 @@ static void checkboxPaint(WidgetT *widget, RectT pos) {
ColorT fill;
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
active = checkboxGetValue(c);
active = checkboxValueGet(c);
highlight = active ? _guiColor[COLOR_CHECKBOX_SHADOW] : _guiColor[COLOR_CHECKBOX_HIGHLIGHT];
shadow = active ? _guiColor[COLOR_CHECKBOX_HIGHLIGHT] : _guiColor[COLOR_CHECKBOX_SHADOW];
fill = active ? _guiColor[COLOR_CHECKBOX_ACTIVE] : _guiColor[COLOR_CHECKBOX_INACTIVE];
@ -109,10 +109,10 @@ static void checkboxPaint(WidgetT *widget, RectT pos) {
o = (_guiFont->height - 10) * 0.5;
// Draw outline of checkbox.
surfaceDrawHighlightFrame(pos.x, pos.y + o, pos.x + 10, pos.y + 10 + o, highlight, shadow);
surfaceHighlightFrameDraw(pos.x, pos.y + o, pos.x + 10, pos.y + 10 + o, highlight, shadow);
// Draw background.
surfaceDrawRectangleFilled(pos.x + 1, pos.y + o + 1, pos.x + 9, pos.y + + o + 9, fill);
surfaceRectangleFilledDraw(pos.x + 1, pos.y + o + 1, pos.x + 9, pos.y + + o + 9, fill);
// Draw title.
fontRender(_guiFont, c->title, _guiColor[COLOR_CHECKBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x + 10 + _guiMetric[METRIC_CHECKBOX_PADDING], pos.y);
@ -122,12 +122,7 @@ static void checkboxPaint(WidgetT *widget, RectT pos) {
}
void checkboxSetClickHandler(CheckboxT *checkbox, widgetCallback callback) {
checkbox->clicked = callback;
}
void checkboxSetTitle(CheckboxT *checkbox, char *title) {
void checkboxTitleSet(CheckboxT *checkbox, char *title) {
if (checkbox->title) free(checkbox->title);
checkbox->title = strdup(title);
checkbox->base.pos.w = (strlen(title) * fontWidthGet(_guiFont)) + 10 + _guiMetric[METRIC_CHECKBOX_PADDING];
@ -135,14 +130,19 @@ void checkboxSetTitle(CheckboxT *checkbox, char *title) {
}
void checkboxSetValue(CheckboxT *checkbox, uint8_t selected) {
uint8_t checkboxValueGet(CheckboxT *checkbox) {
return GUI_GET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
}
void checkboxValueSet(CheckboxT *checkbox, uint8_t selected) {
if (selected) {
if (!checkboxGetValue(checkbox)) {
if (!checkboxValueGet(checkbox)) {
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY);
}
} else {
if (checkboxGetValue(checkbox)) {
if (checkboxValueGet(checkbox)) {
GUI_CLEAR_FLAG((WidgetT *)checkbox, WIDGET_FLAG_ACTIVE);
GUI_SET_FLAG((WidgetT *)checkbox, WIDGET_FLAG_DIRTY);
}

View file

@ -33,12 +33,12 @@ typedef struct CheckboxS {
} CheckboxT;
uint8_t checkboxGetValue(CheckboxT *checkbox);
void checkboxClickHandlerSet(CheckboxT *checkbox, widgetCallback callback);
WidgetT *checkboxInit(WidgetT *widget, char *title);
CheckboxT *checkboxNew(uint16_t x, uint16_t y, char *title);
void checkboxSetClickHandler(CheckboxT *checkbox, widgetCallback callback);
void checkboxSetTitle(CheckboxT *checkbox, char *title);
void checkboxSetValue(CheckboxT *checkbox, uint8_t selected);
void checkboxTitleSet(CheckboxT *checkbox, char *title);
uint8_t checkboxValueGet(CheckboxT *checkbox);
void checkboxValueSet(CheckboxT *checkbox, uint8_t selected);
#endif // CHECKBOX_H

View file

@ -41,7 +41,7 @@ WidgetT *frameInit(WidgetT *widget, char *title) {
f->base.paintMethod = framePaint;
f->title = NULL;
frameSetTitle(f, title);
frameTitleSet(f, title);
return widget;
}
@ -70,7 +70,7 @@ static void framePaint(WidgetT *widget, RectT pos) {
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
// Draw frame.
surfaceDrawHighlightFrame(pos.x, pos.y + (fontHeightGet(_guiFont) * 0.5), pos.x + pos.w, pos.y + pos.h, _guiColor[COLOR_FRAME_SHADOW], _guiColor[COLOR_FRAME_HIGHLIGHT]);
surfaceHighlightFrameDraw(pos.x, pos.y + (fontHeightGet(_guiFont) * 0.5), pos.x + pos.w, pos.y + pos.h, _guiColor[COLOR_FRAME_SHADOW], _guiColor[COLOR_FRAME_HIGHLIGHT]);
// Draw title.
fontRender(_guiFont, f->title, _guiColor[COLOR_FRAME_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x + 10, pos.y);
@ -80,7 +80,7 @@ static void framePaint(WidgetT *widget, RectT pos) {
}
void frameSetTitle(FrameT *frame, char *title) {
void frameTitleSet(FrameT *frame, char *title) {
if (frame->title) free(frame->title);
frame->title = (char *)malloc(strlen(title) + 3);
frame->title[0] = ' ';

View file

@ -34,7 +34,7 @@ typedef struct FrameS {
WidgetT *frameInit(WidgetT *widget, char *title);
FrameT *frameNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
void frameSetTitle(FrameT *frame, char *title);
void frameTitleSet(FrameT *frame, char *title);
#endif // FRAME_H

View file

@ -56,13 +56,16 @@ static char *_magicDebugNames[MAGIC_COUNT] = {
"RadioButton",
"Picture",
"Frame",
"Textbox"
"Textbox",
"Updown",
"Listbox",
"Terminal"
};
static void guiPaintBoundsGet(WidgetT *widget, RectT *pos);
static void guiProcessKeyboardChildren(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
static uint8_t guiProcessMouseChildren(WidgetT *widget, MouseT *mouse);
static void guiKeyboardChildrenProcess(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse);
void guiAttach(WidgetT *parent, WidgetT *child) {
@ -110,7 +113,7 @@ void guiAttach(WidgetT *parent, WidgetT *child) {
// New windows should be active.
if (child->magic == MAGIC_WINDOW) {
windowSetActive((WindowT *)child);
windowActiveSet((WindowT *)child);
}
}
@ -192,6 +195,38 @@ void guiFocusSet(WidgetT *widget) {
}
static void guiKeyboardChildrenProcess(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
size_t len;
size_t x;
// Process children of this widget.
len = arrlenu(widget->children);
for (x=0; x<len; x++) {
guiKeyboardChildrenProcess(widget->children[x], ascii, extended, scancode, shift, control, alt);
}
// Does this widget want events? Check for global keyboard so it doesn't get double events.
if (widget) {
if (widget->keyboardEventMethod && GUI_GET_FLAG(widget, WIDGET_FLAG_ALWAYS_RECEIVE_KEYBOARD_EVENTS)) {
widget->keyboardEventMethod(widget, ascii, extended, scancode, shift, control, alt);
}
}
}
void guiKeyboardProcess(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
// Does the focused widget want events? Check for global keyboard so it doesn't get double events.
if (_guiFocused) {
if (_guiFocused->keyboardEventMethod && !GUI_GET_FLAG(_guiFocused, WIDGET_FLAG_ALWAYS_RECEIVE_KEYBOARD_EVENTS)) {
_guiFocused->keyboardEventMethod(_guiFocused, ascii, extended, scancode, shift, control, alt);
}
}
// Check everyone for global keyboard handling.
guiKeyboardChildrenProcess((WidgetT *)_guiDesktop, ascii, extended, scancode, shift, control, alt);
}
void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y) {
RectT r;
guiWidgetPositionOnScreenGet(widget, &r);
@ -200,47 +235,7 @@ void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, ui
}
void guiPaint(WidgetT *widget) {
size_t len = arrlenu(widget->children);
size_t x;
RectT pos;
// Paint us. Widget handles dirty flag so they can animate if needed.
if (widget->paintMethod) {
surfaceSet(widget->surface);
guiPaintBoundsGet(widget, &pos);
widget->paintMethod(widget, pos);
}
// Paint all children.
if (len > 0) {
for (x=0; x<len; x++) {
guiPaint(widget->children[x]);
}
}
}
static void guiPaintBoundsGet(WidgetT *widget, RectT *pos) {
if (widget->magic == MAGIC_DESKTOP || widget->magic == MAGIC_WINDOW) {
pos->x = 0;
pos->y = 0;
} else {
*pos = widget->parent->clip;
pos->x += widget->pos.x;
pos->y += widget->pos.y;
}
pos->w = widget->pos.w;
pos->h = widget->pos.h;
}
void guiProcessMouse(MouseT *mouse) {
guiProcessMouseChildren(W(_guiDesktop), mouse);
}
static uint8_t guiProcessMouseChildren(WidgetT *widget, MouseT *mouse) {
static uint8_t guiMouseChildrenProcess(WidgetT *widget, MouseT *mouse) {
size_t len;
int16_t x;
RectT r;
@ -254,11 +249,12 @@ static uint8_t guiProcessMouseChildren(WidgetT *widget, MouseT *mouse) {
// Search children backwards for active widget before checking this widget.
len = arrlenu(widget->children);
for (x=len-1; x>=0; --x) {
if (guiProcessMouseChildren(widget->children[x], mouse)) {
if (guiMouseChildrenProcess(widget->children[x], mouse)) {
return 1;
}
}
// Get widget and screen coordinates of pointer.
guiWidgetPositionOnScreenGet(widget, &r);
sx = r.x;
sy = r.y;
@ -327,59 +323,51 @@ static uint8_t guiProcessMouseChildren(WidgetT *widget, MouseT *mouse) {
}
void guiProcessKeyboard(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
// Does the focused widget want events? Check for global keyboard so it doesn't get double events.
if (_guiFocused) {
if (_guiFocused->keyboardEventMethod && !GUI_GET_FLAG(_guiFocused, WIDGET_FLAG_ALWAYS_RECEIVE_KEYBOARD_EVENTS)) {
_guiFocused->keyboardEventMethod(_guiFocused, ascii, extended, scancode, shift, control, alt);
}
}
// Check everyone for global keyboard handling.
guiProcessKeyboardChildren((WidgetT *)_guiDesktop, ascii, extended, scancode, shift, control, alt);
void guiMouseProcess(MouseT *mouse) {
guiMouseChildrenProcess(W(_guiDesktop), mouse);
}
static void guiProcessKeyboardChildren(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
size_t len;
void guiPaint(WidgetT *widget) {
size_t len = arrlenu(widget->children);
size_t x;
RectT pos;
// Process children of this widget.
len = arrlenu(widget->children);
for (x=0; x<len; x++) {
guiProcessKeyboardChildren(widget->children[x], ascii, extended, scancode, shift, control, alt);
// Paint us. Widget handles dirty flag so they can animate if needed.
if (widget->paintMethod) {
surfaceSet(widget->surface);
guiPaintBoundsGet(widget, &pos);
widget->paintMethod(widget, pos);
}
// Does this widget want events? Check for global keyboard so it doesn't get double events.
if (widget) {
if (widget->keyboardEventMethod && GUI_GET_FLAG(widget, WIDGET_FLAG_ALWAYS_RECEIVE_KEYBOARD_EVENTS)) {
widget->keyboardEventMethod(widget, ascii, extended, scancode, shift, control, alt);
// Paint all children.
if (len > 0) {
for (x=0; x<len; x++) {
guiPaint(widget->children[x]);
}
}
}
static void guiPaintBoundsGet(WidgetT *widget, RectT *pos) {
if (widget->magic == MAGIC_DESKTOP || widget->magic == MAGIC_WINDOW) {
pos->x = 0;
pos->y = 0;
} else {
*pos = widget->parent->clip;
pos->x += widget->pos.x;
pos->y += widget->pos.y;
}
pos->w = widget->pos.w;
pos->h = widget->pos.h;
}
WidgetT *guiRootGet(void) {
return (WidgetT *)_guiDesktop;
}
void guiSetWidgetAndChildrenDirty(WidgetT *widget) {
size_t len = arrlenu(widget->children);
size_t x;
// Mark us dirty.
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
// Mark all children.
if (len > 0) {
for (x=0; x<len; x++) {
guiSetWidgetAndChildrenDirty(widget->children[x]);
}
}
}
DesktopT *guiStartup(void) {
_guiMetric[METRIC_BUTTON_BEZEL_SIZE] = 2;
@ -491,6 +479,22 @@ void guiUserDataSet(WidgetT *widget, void *userData) {
}
void guiWidgetAndChildrenDirtySet(WidgetT *widget) {
size_t len = arrlenu(widget->children);
size_t x;
// Mark us dirty.
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
// Mark all children.
if (len > 0) {
for (x=0; x<len; x++) {
guiWidgetAndChildrenDirtySet(widget->children[x]);
}
}
}
void guiWidgetBoundsDrawableOnScreenGet(WidgetT *widget, RectT *bounds) {
guiPaintBoundsGet(widget, bounds);
if (GUI_GET_FLAG(widget, WIDGET_FLAG_OWNS_SURFACE)) {

View file

@ -164,16 +164,16 @@ void guiComposite(void);
void guiDelete(WidgetT **widget);
WidgetT *guiFocusGet(void);
void guiFocusSet(WidgetT *widget);
void guiKeyboardProcess(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y);
void guiMouseProcess(MouseT *mouse);
void guiPaint(WidgetT *widget);
void guiProcessMouse(MouseT *mouse);
void guiProcessKeyboard(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
WidgetT *guiRootGet(void);
void guiSetWidgetAndChildrenDirty(WidgetT *widget);
DesktopT *guiStartup(void);
void guiShutdown(void);
void *guiUserDataGet(WidgetT *widget);
void guiUserDataSet(WidgetT *widget, void *userData);
void guiWidgetAndChildrenDirtySet(WidgetT *widget);
void guiWidgetBoundsDrawableOnScreenGet(WidgetT *widget, RectT *bounds);
void guiWidgetPositionOnScreenGet(WidgetT *widget, RectT *pos);
void guiWidgetTreeDump(WidgetT *widget, uint16_t depth);

View file

@ -26,6 +26,29 @@ static void labelMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t
static void labelPaint(WidgetT *widget, RectT pos);
void labelClickHandlerSet(LabelT *label, widgetCallback callback) {
label->clicked = callback;
}
void labelColorActiveSet(LabelT *label, ColorT color) {
label->active = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
void labelColorBackgroundSet(LabelT *label, ColorT color) {
label->background = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
void labelColorForegroundSet(LabelT *label, ColorT color) {
label->foreground = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
static void labelDel(WidgetT **widget) {
LabelT *l = (LabelT *)*widget;
@ -46,7 +69,7 @@ WidgetT *labelInit(WidgetT *widget, char *title) {
l->foreground = _guiColor[COLOR_LABEL_TEXT_INACTIVE];
l->clicked = NULL;
labelSetTitle(l, title);
labelTitleSet(l, title);
return widget;
}
@ -112,30 +135,7 @@ static void labelPaint(WidgetT *widget, RectT pos) {
}
void labelSetActiveColor(LabelT *label, ColorT color) {
label->active = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
void labelSetBackgroundColor(LabelT *label, ColorT color) {
label->background = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
void labelSetClickHandler(LabelT *label, widgetCallback callback) {
label->clicked = callback;
}
void labelSetForegroundColor(LabelT *label, ColorT color) {
label->foreground = color;
GUI_SET_FLAG((WidgetT *)label, WIDGET_FLAG_DIRTY);
}
void labelSetTitle(LabelT *label, char *title) {
void labelTitleSet(LabelT *label, char *title) {
if (label->title) free(label->title);
label->title = strdup(title);
label->base.pos.w = (strlen(title) * fontWidthGet(_guiFont));

View file

@ -36,13 +36,13 @@ typedef struct LabelS {
} LabelT;
void labelClickHandlerSet(LabelT *label, widgetCallback callback);
void labelColorActiveSet(LabelT *label, ColorT color);
void labelColorBackgroundSet(LabelT *label, ColorT color);
void labelColorForegroundSet(LabelT *label, ColorT color);
WidgetT *labelInit(WidgetT *widget, char *title);
LabelT *labelNew(uint16_t x, uint16_t y, char *title);
void labelSetActiveColor(LabelT *label, ColorT color);
void labelSetBackgroundColor(LabelT *label, ColorT color);
void labelSetClickHandler(LabelT *label, widgetCallback callback);
void labelSetForegroundColor(LabelT *label, ColorT color);
void labelSetTitle(LabelT *label, char *title);
void labelTitleSet(LabelT *label, char *title);
#endif // LABEL_H

View file

@ -36,17 +36,11 @@ static void listboxDel(WidgetT **widget);
static void listboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
static void listboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
static void listboxPaint(WidgetT *widget, RectT pos);
static void listboxScrollUp(ListboxT *listbox);
static void listboxScrollDown(ListboxT *listbox);
static void listboxScrollUp(ListboxT *listbox);
static void listboxSizesRecalculate(ListboxT *listbox);
void listboxAddItem(ListboxT *listbox, char *item) {
arrput(listbox->values, strdup(item));
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
static void listboxDel(WidgetT **widget) {
ListboxT *l = (ListboxT *)*widget;
size_t len = arrlenu(l->values);
@ -64,13 +58,16 @@ static void listboxDel(WidgetT **widget) {
}
uint16_t listboxGetIndex(ListboxT *listbox) {
uint16_t listboxIndexGet(ListboxT *listbox) {
return listbox->selected;
}
char *listboxGetValue(ListboxT *listbox) {
return listbox->values[listbox->selected];
void listboxIndexSet(ListboxT *listbox, uint16_t index) {
if (index < arrlenu(listbox->values)) {
listbox->selected = index;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
}
@ -88,12 +85,35 @@ WidgetT *listboxInit(WidgetT *widget, char *title) {
l->offset = 0;
// Visibles are set in listboxSetTitle
listboxSetTitle(l, title);
listboxTitleSet(l, title);
return widget;
}
void listboxItemAdd(ListboxT *listbox, char *item) {
arrput(listbox->values, strdup(item));
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
void listboxItemRemove(ListboxT *listbox, char *item) {
size_t len = arrlenu(listbox->values);
size_t x;
if (len > 0) {
for (x=0; x<len; x++) {
if (strcmp(item, listbox->values[x]) == 0) {
arrdel(listbox->values, x);
if (listbox->selected > len || listbox->selected > 0) listbox->selected--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
break;
}
}
}
}
static void listboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
ListboxT *l = (ListboxT *)widget;
@ -238,16 +258,16 @@ static void listboxPaint(WidgetT *widget, RectT pos) {
fontRender(_guiFont, l->title, _guiColor[COLOR_LISTBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y);
// Draw outline of listbox.
surfaceDrawHighlightFrame(pos.x, _valueTop, pos.x + _valueWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
surfaceHighlightFrameDraw(pos.x, _valueTop, pos.x + _valueWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
// Draw background of listbox.
surfaceDrawRectangleFilled(pos.x + 1, _valueTop + 1, pos.x + _valueWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_BACKGROUND]);
surfaceRectangleFilledDraw(pos.x + 1, _valueTop + 1, pos.x + _valueWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_BACKGROUND]);
// Draw listbox contents.
o = _valueTop + 1 + _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING];
for (i=0; i<items; i++) {
if (i == l->selected) {
surfaceDrawRectangleFilled(pos.x + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(_guiFont) - 1, _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]);
surfaceRectangleFilledDraw(pos.x + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(_guiFont) - 1, _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]);
fontRender(_guiFont, l->values[l->offset + i], _guiColor[COLOR_LISTBOX_SELECTED_TEXT], _guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND], pos.x + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
} else {
fontRender(_guiFont, l->values[l->offset + i], _guiColor[COLOR_LISTBOX_TEXT], _guiColor[COLOR_LISTBOX_BACKGROUND], pos.x + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
@ -256,69 +276,37 @@ static void listboxPaint(WidgetT *widget, RectT pos) {
}
// Draw outline of arrows.
surfaceDrawHighlightFrame(_arrowStart, _valueTop, _arrowStart + _arrowWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
surfaceHighlightFrameDraw(_arrowStart, _valueTop, _arrowStart + _arrowWidth, _valueBottom, _guiColor[COLOR_LISTBOX_SHADOW], _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
// Draw background of arrows.
surfaceDrawRectangleFilled(_arrowStart + 1, _valueTop + 1, _arrowStart + _arrowWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND]);
surfaceRectangleFilledDraw(_arrowStart + 1, _valueTop + 1, _arrowStart + _arrowWidth - 1, _valueBottom - 1, _guiColor[COLOR_LISTBOX_ARROWS_BACKGROUND]);
// Draw up arrow
_arrowStart += _halfFont + 1 + _guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING]; // Center of up arrow
o = _valueTop + 1 + _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING]; // Top of up arrow
color = l->offset + l->selected > 0 ? _guiColor[COLOR_LISTBOX_ARROWS_ACTIVE] : _guiColor[COLOR_LISTBOX_ARROWS_INACTIVE];
for (i=0; i<=fontHeightGet(_guiFont); i++) {
surfaceDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color);
surfaceLineDraw(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color);
}
surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]);
surfaceDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]);
surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]);
surfaceLineDraw(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_SHADOW]);
surfaceLineDraw(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_LISTBOX_HIGHLIGHT]);
// Draw down arrow
o = _valueBottom - 1 - _guiMetric[METRIC_LISTBOX_VERTICAL_PADDING]; // Bottom of down arrow
color = l->offset + l->selected < len - 1 ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE];
for (i=0; i<=fontHeightGet(_guiFont); i++) {
surfaceDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color);
surfaceLineDraw(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color);
}
surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceLineDraw(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
}
}
void listboxRemoveItem(ListboxT *listbox, char *item) {
size_t len = arrlenu(listbox->values);
size_t x;
if (len > 0) {
for (x=0; x<len; x++) {
if (strcmp(item, listbox->values[x]) == 0) {
arrdel(listbox->values, x);
if (listbox->selected > len || listbox->selected > 0) listbox->selected--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
break;
}
}
}
}
static void listboxScrollUp(ListboxT *listbox) {
// Can we decrement?
if (listbox->selected > 0) {
listbox->selected--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
} else {
// Can we scroll the list up?
if (listbox->offset > 0) {
listbox->offset--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
}
}
static void listboxScrollDown(ListboxT *listbox) {
int16_t len = arrlenu(listbox->values);
@ -339,38 +327,16 @@ static void listboxScrollDown(ListboxT *listbox) {
}
void listboxSetIndex(ListboxT *listbox, uint16_t index) {
if (index < arrlenu(listbox->values)) {
listbox->selected = index;
static void listboxScrollUp(ListboxT *listbox) {
// Can we decrement?
if (listbox->selected > 0) {
listbox->selected--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
}
void listboxSetStep(ListboxT *listbox, int32_t step) {
listbox->step = step;
}
void listboxSetTitle(ListboxT *listbox, char *title) {
if (listbox->title) free(listbox->title);
listbox->title = strdup(title);
listboxSizesRecalculate(listbox);
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
void listboxSetValue(ListboxT *listbox, char *value) {
size_t len = arrlenu(listbox->values);
size_t x;
if (len > 0) {
for (x=0; x<len; x++) {
if (strcmp(value, listbox->values[x]) == 0) {
listbox->selected = x;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
break;
}
} else {
// Can we scroll the list up?
if (listbox->offset > 0) {
listbox->offset--;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
}
}
@ -400,3 +366,37 @@ static void listboxSizesRecalculate(ListboxT *listbox) {
_visibleY = (_valueHeight - 2 + (_guiMetric[METRIC_LISTBOX_VERTICAL_PADDING] * 2)) / fontHeightGet(_guiFont);
}
void listboxStepSet(ListboxT *listbox, int32_t step) {
listbox->step = step;
}
void listboxTitleSet(ListboxT *listbox, char *title) {
if (listbox->title) free(listbox->title);
listbox->title = strdup(title);
listboxSizesRecalculate(listbox);
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
}
char *listboxValueGet(ListboxT *listbox) {
return listbox->values[listbox->selected];
}
void listboxValueSet(ListboxT *listbox, char *value) {
size_t len = arrlenu(listbox->values);
size_t x;
if (len > 0) {
for (x=0; x<len; x++) {
if (strcmp(value, listbox->values[x]) == 0) {
listbox->selected = x;
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
break;
}
}
}
}

View file

@ -36,16 +36,16 @@ typedef struct ListboxS {
} ListboxT;
void listboxAddItem(ListboxT *listbox, char *item);
uint16_t listboxGetIndex(ListboxT *listbox);
char *listboxGetValue(ListboxT *listbox);
uint16_t listboxIndexGet(ListboxT *listbox);
void listboxIndexSet(ListboxT *listbox, uint16_t index);
WidgetT *listboxInit(WidgetT *widget, char *title);
void listboxItemAdd(ListboxT *listbox, char *item);
void listboxItemRemove(ListboxT *listbox, char *item);
ListboxT *listboxNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
void listboxRemoveItem(ListboxT *listbox, char *item);
void listboxSetIndex(ListboxT *listbox, uint16_t index);
void listboxSetStep(ListboxT *listbox, int32_t step);
void listboxSetTitle(ListboxT *listbox, char *title);
void listboxSetValue(ListboxT *listbox, char *value);
void listboxStepSet(ListboxT *listbox, int32_t step);
void listboxTitleSet(ListboxT *listbox, char *title);
char *listboxValueGet(ListboxT *listbox);
void listboxValueSet(ListboxT *listbox, char *value);
#endif // LISTBOX_H

View file

@ -26,6 +26,11 @@ static void pictureMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16
static void picturePaint(WidgetT *widget, RectT pos);
void pictureClickHandlerSet(PictureT *picture, widgetCallback callback) {
picture->clicked = callback;
}
static void pictureDel(WidgetT **widget) {
PictureT *p = (PictureT *)*widget;
@ -107,8 +112,3 @@ static void picturePaint(WidgetT *widget, RectT pos) {
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
}
}
void pictureSetClickHandler(PictureT *picture, widgetCallback callback) {
picture->clicked = callback;
}

View file

@ -35,9 +35,9 @@ typedef struct PictureS {
} PictureT;
void pictureClickHandlerSet(PictureT *picture, widgetCallback callback);
WidgetT *pictureInit(WidgetT *widget, char *filename);
PictureT *pictureNew(uint16_t x, uint16_t y, char *filename);
void pictureSetClickHandler(PictureT *picture, widgetCallback callback);
#endif // PICTURE_H

View file

@ -21,34 +21,15 @@
#include "radio.h"
static void radioClearSelectedInGroup(WidgetT *widget, uint32_t group);
static void radioDel(WidgetT **widget);
static RadioT *radioFindSelectedInGroup(WidgetT *widget, uint32_t group);
static void radioMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
static void radioPaint(WidgetT *widget, RectT pos);
static void radioSelectedInGroupClear(WidgetT *widget, uint32_t group);
static RadioT *radioSelectedInGroupFind(WidgetT *widget, uint32_t group);
static void radioClearSelectedInGroup(WidgetT *widget, uint32_t group) {
size_t len = arrlenu(widget->children);
size_t x;
// Is this a Radio Button?
if (widget->magic == MAGIC_RADIOBUTTON) {
// Is this in our group and active?
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
// Deactivate it, mark it dirty, and stop searching.
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_ACTIVE);
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
return;
}
}
// Process any children.
if (len > 0) {
for (x=0; x<len; x++) {
radioClearSelectedInGroup(widget->children[x], group);
}
}
void radioClickHandlerSet(RadioT *radio, widgetCallback callback) {
radio->clicked = callback;
}
@ -61,37 +42,6 @@ static void radioDel(WidgetT **widget) {
}
static RadioT *radioFindSelectedInGroup(WidgetT *widget, uint32_t group) {
size_t len = arrlenu(widget->children);
size_t x;
RadioT *result = NULL;
// Is this a Radio Button?
if (widget->magic == MAGIC_RADIOBUTTON) {
// Is this in our group and active?
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
// Found! Stop searching.
return (RadioT *)widget;
}
}
// Process any children.
if (len > 0) {
for (x=0; x<len; x++) {
result = radioFindSelectedInGroup(widget->children[x], group);
if (result) break;
}
}
return result;
}
RadioT *radioGetSelected(RadioT *radio) {
return radioFindSelectedInGroup(guiRootGet(), radio->group);
}
WidgetT *radioInit(WidgetT *widget, char *title, uint16_t group) {
RadioT *r = (RadioT *)widget;
@ -102,7 +52,7 @@ WidgetT *radioInit(WidgetT *widget, char *title, uint16_t group) {
r->clicked = NULL;
r->group = group;
radioSetTitle(r, title);
radioTitleSet(r, title);
// Width is set in radioSetTitle
r->base.pos.h = fontHeightGet(_guiFont);
@ -120,7 +70,7 @@ static void radioMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t
if (event == MOUSE_EVENT_LEFT_UP) {
// Select us.
radioSetSelected(r);
radioSelectedSet(r);
// Fire callback on mouse up.
if (r->clicked) r->clicked(widget);
}
@ -156,7 +106,7 @@ static void radioPaint(WidgetT *widget, RectT pos) {
ColorT fill;
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
active = (radioGetSelected(r) == r);
active = (radioSelectedGet(r) == r);
highlight = active ? _guiColor[COLOR_RADIOBUTTON_SHADOW] : _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT];
shadow = active ? _guiColor[COLOR_RADIOBUTTON_HIGHLIGHT] : _guiColor[COLOR_RADIOBUTTON_SHADOW];
fill = active ? _guiColor[COLOR_RADIOBUTTON_ACTIVE] : _guiColor[COLOR_RADIOBUTTON_INACTIVE];
@ -165,15 +115,15 @@ static void radioPaint(WidgetT *widget, RectT pos) {
o = (_guiFont->height - 10) * 0.5;
// Draw outline of radio button.
surfaceDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o, highlight);
surfaceDrawLine(pos.x + 5, pos.y + o, pos.x + 10, pos.y + o + 5, highlight);
surfaceDrawLine(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o + 10, shadow);
surfaceDrawLine(pos.x + 5, pos.y + o + 10, pos.x + 10, pos.y + o + 5, shadow);
surfaceLineDraw(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o, highlight);
surfaceLineDraw(pos.x + 5, pos.y + o, pos.x + 10, pos.y + o + 5, highlight);
surfaceLineDraw(pos.x, pos.y + o + 5, pos.x + 5, pos.y + o + 10, shadow);
surfaceLineDraw(pos.x + 5, pos.y + o + 10, pos.x + 10, pos.y + o + 5, shadow);
// Fill radio button.
for (i=0; i<4; i++) {
surfaceDrawLine(pos.x + 5 - i, pos.y + o + i + 1, pos.x + 5 + i, pos.y + o + i + 1, fill);
surfaceDrawLine(pos.x + 5 - i, pos.y + o - i + 8, pos.x + 5 + i, pos.y + o - i + 8, fill);
surfaceLineDraw(pos.x + 5 - i, pos.y + o + i + 1, pos.x + 5 + i, pos.y + o + i + 1, fill);
surfaceLineDraw(pos.x + 5 - i, pos.y + o - i + 8, pos.x + 5 + i, pos.y + o - i + 8, fill);
}
// Draw title.
@ -184,16 +134,66 @@ static void radioPaint(WidgetT *widget, RectT pos) {
}
void radioSetClickHandler(RadioT *radio, widgetCallback callback) {
radio->clicked = callback;
static void radioSelectedInGroupClear(WidgetT *widget, uint32_t group) {
size_t len = arrlenu(widget->children);
size_t x;
// Is this a Radio Button?
if (widget->magic == MAGIC_RADIOBUTTON) {
// Is this in our group and active?
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
// Deactivate it, mark it dirty, and stop searching.
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_ACTIVE);
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
return;
}
}
// Process any children.
if (len > 0) {
for (x=0; x<len; x++) {
radioSelectedInGroupClear(widget->children[x], group);
}
}
}
void radioSetSelected(RadioT *radio) {
static RadioT *radioSelectedInGroupFind(WidgetT *widget, uint32_t group) {
size_t len = arrlenu(widget->children);
size_t x;
RadioT *result = NULL;
// Is this a Radio Button?
if (widget->magic == MAGIC_RADIOBUTTON) {
// Is this in our group and active?
if (((RadioT *)widget)->group == group && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
// Found! Stop searching.
return (RadioT *)widget;
}
}
// Process any children.
if (len > 0) {
for (x=0; x<len; x++) {
result = radioSelectedInGroupFind(widget->children[x], group);
if (result) break;
}
}
return result;
}
RadioT *radioSelectedGet(RadioT *radio) {
return radioSelectedInGroupFind(guiRootGet(), radio->group);
}
void radioSelectedSet(RadioT *radio) {
// Are we already selected?
if (!GUI_GET_FLAG((WidgetT *)radio, WIDGET_FLAG_ACTIVE)) {
// Clear whoever is selected.
radioClearSelectedInGroup(guiRootGet(), radio->group);
radioSelectedInGroupClear(guiRootGet(), radio->group);
// Select us.
GUI_SET_FLAG((WidgetT *)radio, WIDGET_FLAG_ACTIVE);
GUI_SET_FLAG((WidgetT *)radio, WIDGET_FLAG_DIRTY);
@ -201,7 +201,7 @@ void radioSetSelected(RadioT *radio) {
}
void radioSetTitle(RadioT *radio, char *title) {
void radioTitleSet(RadioT *radio, char *title) {
if (radio->title) free(radio->title);
radio->title = strdup(title);
radio->base.pos.w = (strlen(title) * fontWidthGet(_guiFont)) + 10 + _guiMetric[METRIC_RADIOBUTTON_PADDING];

View file

@ -34,12 +34,12 @@ typedef struct RadioS {
} RadioT;
RadioT *radioGetSelected(RadioT *radio);
void radioClickHandlerSet(RadioT *radio, widgetCallback callback);
WidgetT *radioInit(WidgetT *widget, char *title, uint16_t group);
RadioT *radioNew(uint16_t x, uint16_t y, char *title, uint16_t group);
void radioSetClickHandler(RadioT *radio, widgetCallback callback);
void radioSetSelected(RadioT *radio);
void radioSetTitle(RadioT *radio, char *title);
RadioT *radioSelectedGet(RadioT *radio);
void radioSelectedSet(RadioT *radio);
void radioTitleSet(RadioT *radio, char *title);
#endif // RADIO_H

View file

@ -34,9 +34,9 @@
#define TERMINAL_CELL_CLEAR_FLAG(t,x,y,f) ((t)->cells[(x)][(y)].flags &= (~(1 << (f))))
static int16_t terminalConvertToInt(char *number, int16_t defaultValue);
static void terminalDel(WidgetT **widget);
static void terminalFocusEvent(WidgetT *widget, uint8_t focused);
static int16_t terminalIntConvert(char *number, int16_t defaultValue);
static void terminalMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
static void terminalKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
static void terminalPaint(WidgetT *widget, RectT pos);
@ -48,244 +48,7 @@ void terminalBackgroundSet(TerminalT *terminal, uint8_t color) {
}
static int16_t terminalConvertToInt(char *number, int16_t defaultValue) {
char *end = NULL;
int16_t result = (int16_t)strtol(number, &end, 10);
if (end == NULL || number[0] == 0) result = defaultValue;
return result;
}
void terminalCursorMove(TerminalT *terminal, uint16_t col, uint16_t row) {
// Clamp X.
if (col < 1) {
terminal->cursorX = 1;
} else {
if (col > terminal->cols) {
terminal->cursorX = terminal->cols;
} else {
terminal->cursorX = col;
}
}
// Clamp Y.
if (row < 1) {
terminal->cursorY = 1;
} else {
if (row > terminal->rows) {
terminal->cursorY = terminal->rows;
} else {
terminal->cursorY = row;
}
}
}
static void terminalDel(WidgetT **widget) {
TerminalT *t = (TerminalT *)*widget;
uint16_t x;
terminalSequenceReset(t);
for (x=0; x<t->cols; x++) {
free(t->cells[x]);
}
free(t->cells);
free(t);
t = NULL;
}
static void terminalFocusEvent(WidgetT *widget, uint8_t focused) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
(void)focused;
// When focus changes, we need to mark ALL the cells dirty so they get redrawn when the window is redrawn.
for (y=0; y<t->rows; y++) {
for (x=0; x<t->cols; x++) {
TERMINAL_CELL_SET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
}
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
}
void terminalForegroundSet(TerminalT *terminal, uint8_t color) {
terminal->foreground = color;
terminal->bold = (color > 7);
}
WidgetT *terminalInit(WidgetT *widget, uint16_t cols, uint16_t rows) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
t->base.delMethod = terminalDel;
t->base.focusMethod = terminalFocusEvent;
t->base.paintMethod = terminalPaint;
t->base.keyboardEventMethod = terminalKeyboardEvent;
t->base.mouseEventMethod = terminalMouseEvent;
t->font = _guiFont; // Default font. Also see terminalNew.
t->cols = cols;
t->rows = rows;
t->cursorX = 1;
t->cursorY = 1;
t->saveX = 1;
t->saveY = 1;
t->bold = 0;
t->blink = 0;
t->reverse = 0;
t->background = TERMINAL_COLOR_BLACK;
t->foreground = TERMINAL_COLOR_LIGHT_GRAY;
t->escFound = 0;
t->inEscape = 0;
t->numberIndex = 0;
t->number[0] = 0;
t->parameters = NULL;
// Allocate space for column data.
t->cells = (CellT **)malloc(sizeof(CellT *) * cols);
if (!t->cells) return NULL;
// Allocate space for row data.
for (x=0; x<cols; x++) {
t->cells[x] = (CellT *)malloc(sizeof(CellT) * rows);
if (!t->cells[x]) {
for (y=0; y<x; y++) {
free(t->cells[y]);
}
free(t->cells);
return NULL;
}
}
// Set up default palette.
t->palette[TERMINAL_COLOR_BLACK] = vbeColorMake( 0, 0, 0);
t->palette[TERMINAL_COLOR_BLUE] = vbeColorMake(170, 0, 0);
t->palette[TERMINAL_COLOR_GREEN] = vbeColorMake( 0, 170, 0);
t->palette[TERMINAL_COLOR_CYAN] = vbeColorMake(170, 85, 0);
t->palette[TERMINAL_COLOR_RED] = vbeColorMake( 0, 0, 170);
t->palette[TERMINAL_COLOR_MAGENTA] = vbeColorMake(170, 0, 170);
t->palette[TERMINAL_COLOR_BROWN] = vbeColorMake( 0, 170, 170);
t->palette[TERMINAL_COLOR_LIGHT_GRAY] = vbeColorMake(170, 170, 170);
t->palette[TERMINAL_COLOR_DARK_GRAY] = vbeColorMake( 85, 85, 85);
t->palette[TERMINAL_COLOR_BRIGHT_BLUE] = vbeColorMake(255, 85, 85);
t->palette[TERMINAL_COLOR_BRIGHT_GREEN] = vbeColorMake( 85, 255, 85);
t->palette[TERMINAL_COLOR_BRIGHT_CYAN] = vbeColorMake(255, 255, 85);
t->palette[TERMINAL_COLOR_BRIGHT_RED] = vbeColorMake( 85, 85, 255);
t->palette[TERMINAL_COLOR_BRIGHT_MAGENTA] = vbeColorMake(255, 85, 255);
t->palette[TERMINAL_COLOR_YELLOW] = vbeColorMake( 85, 255, 255);
t->palette[TERMINAL_COLOR_WHITE] = vbeColorMake(255, 255, 255);
// Default attributes is gray on black, no bold, no blink, and dirty.
for (y=0; y<rows; y++) {
for (x=0; x<cols; x++) {
t->cells[x][y].character = ' ';
t->cells[x][y].background = TERMINAL_COLOR_BLACK;
t->cells[x][y].foreground = TERMINAL_COLOR_LIGHT_GRAY;
t->cells[x][y].flags = 0;
TERMINAL_CELL_SET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
}
return widget;
}
static void terminalKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
}
static void terminalMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
TerminalT *t = (TerminalT *)widget;
(void)mouse;
// Fire callback on mouse up.
if (event == MOUSE_EVENT_LEFT_UP) {
}
}
TerminalT *terminalNew(uint16_t x, uint16_t y, uint16_t cols, uint16_t rows) {
TerminalT *terminal = (TerminalT *)malloc(sizeof(TerminalT));
WidgetT *widget = NULL;
uint16_t w;
uint16_t h;
if (!terminal) return NULL;
// Default font. Also see terminalInit.
w = fontWidthGet(_guiFont) * cols;
h = fontHeightGet(_guiFont) * rows;
widget = widgetInit(W(terminal), MAGIC_TERMINAL, x, y, w, h, 0, 0, 0, 0);
if (!widget) {
free(terminal);
return NULL;
}
terminal = (TerminalT *)terminalInit((WidgetT *)terminal, cols, rows);
if (!terminal) {
free(terminal);
return NULL;
}
return terminal;
}
static void terminalPaint(WidgetT *widget, RectT pos) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
uint16_t xp;
uint16_t yp;
char c[2];
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
c[1] = 0;
yp = pos.y;
for (y=0; y<t->rows; y++) {
xp = pos.x;
for (x=0; x<t->cols; x++) {
if (TERMINAL_CELL_GET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY)) {
c[0] = t->cells[x][y].character;
fontRender(t->font, c, t->palette[t->cells[x][y].foreground], t->palette[t->cells[x][y].background], xp, yp);
TERMINAL_CELL_CLEAR_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
xp += fontWidthGet(t->font);
}
yp += fontHeightGet(t->font);
}
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
}
}
void terminalPrint(TerminalT *terminal, char *string) {
uint16_t i;
for (i=0; i<strlen(string); i++) {
terminalPrintChar(terminal, string[i]);
}
}
void terminalPrintChar(TerminalT *terminal, uint8_t c) {
void terminalCharPrint(TerminalT *terminal, uint8_t c) {
int16_t x;
int16_t y;
uint16_t p;
@ -328,7 +91,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor up.
case 'A':
y = terminalConvertToInt(terminal->number, 1);
y = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor up %d\n", y);
terminalCursorMove(terminal, terminal->cursorX, terminal->cursorY - y);
terminalSequenceReset(terminal);
@ -336,7 +99,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor down.
case 'B':
y = terminalConvertToInt(terminal->number, 1);
y = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor down %d\n", y);
terminalCursorMove(terminal, terminal->cursorX, terminal->cursorY + y);
terminalSequenceReset(terminal);
@ -344,7 +107,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor forward.
case 'C':
x = terminalConvertToInt(terminal->number, 1);
x = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor forward %d\n", x);
terminalCursorMove(terminal, terminal->cursorX + x, terminal->cursorY);
terminalSequenceReset(terminal);
@ -352,7 +115,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor backward.
case 'D':
x = terminalConvertToInt(terminal->number, 1);
x = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor backward %d\n", x);
terminalCursorMove(terminal, terminal->cursorX - x, terminal->cursorY);
terminalSequenceReset(terminal);
@ -360,7 +123,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor line down.
case 'E':
y = terminalConvertToInt(terminal->number, 1);
y = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor down %d lines\n", y);
terminalCursorMove(terminal, 1, terminal->cursorY + y);
//***TODO*** This should allow scrolling.
@ -369,7 +132,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor line up.
case 'F':
y = terminalConvertToInt(terminal->number, 1);
y = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor up %d lines\n", y);
terminalCursorMove(terminal, 1, terminal->cursorY - y);
//***TODO*** This should allow scrolling.
@ -378,7 +141,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Cursor horizontal absolute.
case 'G':
x = terminalConvertToInt(terminal->number, 1);
x = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor horizontal absolute %d\n", x);
terminalCursorMove(terminal, x, terminal->cursorY);
terminalSequenceReset(terminal);
@ -390,15 +153,15 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
switch (arrlen(terminal->parameters)) {
// Cursor vertical absolute. Kinda. Moves X to 1.
case 0:
y = terminalConvertToInt(terminal->number, 1);
y = terminalIntConvert(terminal->number, 1);
termWrite("Moving cursor kinda vertictal absolute %d\n", y);
terminalCursorMove(terminal, 1, y);
break;
// Absolute position.
case 1:
x = terminalConvertToInt(terminal->number, 1);
y = terminalConvertToInt(terminal->parameters[0], 1);
x = terminalIntConvert(terminal->number, 1);
y = terminalIntConvert(terminal->parameters[0], 1);
termWrite("Moving cursor absolute %d %d\n", x, y);
terminalCursorMove(terminal, x, y);
break;
@ -413,7 +176,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Clear display.
case 'J':
if (arrlen(terminal->parameters) == 0 && terminalConvertToInt(terminal->number, 1) == 2) {
if (arrlen(terminal->parameters) == 0 && terminalIntConvert(terminal->number, 1) == 2) {
termWrite("Clear display\n");
terminalScreenClear(terminal);
terminalCursorMove(terminal, 1, 1);
@ -426,7 +189,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
// Clear from cursor to end of line.
case 'K':
x = terminalConvertToInt(terminal->number, 0);
x = terminalIntConvert(terminal->number, 0);
if (x == 0) {
termWrite("Clear to end of line\n");
for (y=terminal->cursorX-1; y<terminal->cols; y++) {
@ -498,7 +261,7 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
case 'm':
arrput(terminal->parameters, strdup(terminal->number));
for (p=0; p<arrlen(terminal->parameters); p++) {
x = terminalConvertToInt(terminal->parameters[p], 0);
x = terminalIntConvert(terminal->parameters[p], 0);
switch (x) {
// Reset.
case 0:
@ -703,6 +466,234 @@ void terminalPrintChar(TerminalT *terminal, uint8_t c) {
}
void terminalCursorMove(TerminalT *terminal, uint16_t col, uint16_t row) {
// Clamp X.
if (col < 1) {
terminal->cursorX = 1;
} else {
if (col > terminal->cols) {
terminal->cursorX = terminal->cols;
} else {
terminal->cursorX = col;
}
}
// Clamp Y.
if (row < 1) {
terminal->cursorY = 1;
} else {
if (row > terminal->rows) {
terminal->cursorY = terminal->rows;
} else {
terminal->cursorY = row;
}
}
}
static void terminalDel(WidgetT **widget) {
TerminalT *t = (TerminalT *)*widget;
uint16_t x;
terminalSequenceReset(t);
for (x=0; x<t->cols; x++) {
free(t->cells[x]);
}
free(t->cells);
free(t);
t = NULL;
}
static void terminalFocusEvent(WidgetT *widget, uint8_t focused) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
(void)focused;
// When focus changes, we need to mark ALL the cells dirty so they get redrawn when the window is redrawn.
for (y=0; y<t->rows; y++) {
for (x=0; x<t->cols; x++) {
TERMINAL_CELL_SET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
}
GUI_SET_FLAG(widget, WIDGET_FLAG_DIRTY);
}
void terminalForegroundSet(TerminalT *terminal, uint8_t color) {
terminal->foreground = color;
terminal->bold = (color > 7);
}
WidgetT *terminalInit(WidgetT *widget, uint16_t cols, uint16_t rows) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
t->base.delMethod = terminalDel;
t->base.focusMethod = terminalFocusEvent;
t->base.paintMethod = terminalPaint;
t->base.keyboardEventMethod = terminalKeyboardEvent;
t->base.mouseEventMethod = terminalMouseEvent;
t->font = _guiFont; // Default font. Also see terminalNew.
t->cols = cols;
t->rows = rows;
t->cursorX = 1;
t->cursorY = 1;
t->saveX = 1;
t->saveY = 1;
t->bold = 0;
t->blink = 0;
t->reverse = 0;
t->background = TERMINAL_COLOR_BLACK;
t->foreground = TERMINAL_COLOR_LIGHT_GRAY;
t->escFound = 0;
t->inEscape = 0;
t->numberIndex = 0;
t->number[0] = 0;
t->parameters = NULL;
// Allocate space for column data.
t->cells = (CellT **)malloc(sizeof(CellT *) * cols);
if (!t->cells) return NULL;
// Allocate space for row data.
for (x=0; x<cols; x++) {
t->cells[x] = (CellT *)malloc(sizeof(CellT) * rows);
if (!t->cells[x]) {
for (y=0; y<x; y++) {
free(t->cells[y]);
}
free(t->cells);
return NULL;
}
}
// Set up default palette.
t->palette[TERMINAL_COLOR_BLACK] = vbeColorMake( 0, 0, 0);
t->palette[TERMINAL_COLOR_BLUE] = vbeColorMake(170, 0, 0);
t->palette[TERMINAL_COLOR_GREEN] = vbeColorMake( 0, 170, 0);
t->palette[TERMINAL_COLOR_CYAN] = vbeColorMake(170, 85, 0);
t->palette[TERMINAL_COLOR_RED] = vbeColorMake( 0, 0, 170);
t->palette[TERMINAL_COLOR_MAGENTA] = vbeColorMake(170, 0, 170);
t->palette[TERMINAL_COLOR_BROWN] = vbeColorMake( 0, 170, 170);
t->palette[TERMINAL_COLOR_LIGHT_GRAY] = vbeColorMake(170, 170, 170);
t->palette[TERMINAL_COLOR_DARK_GRAY] = vbeColorMake( 85, 85, 85);
t->palette[TERMINAL_COLOR_BRIGHT_BLUE] = vbeColorMake(255, 85, 85);
t->palette[TERMINAL_COLOR_BRIGHT_GREEN] = vbeColorMake( 85, 255, 85);
t->palette[TERMINAL_COLOR_BRIGHT_CYAN] = vbeColorMake(255, 255, 85);
t->palette[TERMINAL_COLOR_BRIGHT_RED] = vbeColorMake( 85, 85, 255);
t->palette[TERMINAL_COLOR_BRIGHT_MAGENTA] = vbeColorMake(255, 85, 255);
t->palette[TERMINAL_COLOR_YELLOW] = vbeColorMake( 85, 255, 255);
t->palette[TERMINAL_COLOR_WHITE] = vbeColorMake(255, 255, 255);
// Default attributes is gray on black, no bold, no blink, and dirty.
for (y=0; y<rows; y++) {
for (x=0; x<cols; x++) {
t->cells[x][y].character = ' ';
t->cells[x][y].background = TERMINAL_COLOR_BLACK;
t->cells[x][y].foreground = TERMINAL_COLOR_LIGHT_GRAY;
t->cells[x][y].flags = 0;
TERMINAL_CELL_SET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
}
return widget;
}
static int16_t terminalIntConvert(char *number, int16_t defaultValue) {
char *end = NULL;
int16_t result = (int16_t)strtol(number, &end, 10);
if (end == NULL || number[0] == 0) result = defaultValue;
return result;
}
static void terminalKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
}
static void terminalMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
TerminalT *t = (TerminalT *)widget;
(void)mouse;
// Fire callback on mouse up.
if (event == MOUSE_EVENT_LEFT_UP) {
}
}
TerminalT *terminalNew(uint16_t x, uint16_t y, uint16_t cols, uint16_t rows) {
TerminalT *terminal = (TerminalT *)malloc(sizeof(TerminalT));
WidgetT *widget = NULL;
uint16_t w;
uint16_t h;
if (!terminal) return NULL;
// Default font. Also see terminalInit.
w = fontWidthGet(_guiFont) * cols;
h = fontHeightGet(_guiFont) * rows;
widget = widgetInit(W(terminal), MAGIC_TERMINAL, x, y, w, h, 0, 0, 0, 0);
if (!widget) {
free(terminal);
return NULL;
}
terminal = (TerminalT *)terminalInit((WidgetT *)terminal, cols, rows);
if (!terminal) {
free(terminal);
return NULL;
}
return terminal;
}
static void terminalPaint(WidgetT *widget, RectT pos) {
TerminalT *t = (TerminalT *)widget;
uint16_t x;
uint16_t y;
uint16_t xp;
uint16_t yp;
char c[2];
if (GUI_GET_FLAG(widget, WIDGET_FLAG_DIRTY)) {
c[1] = 0;
yp = pos.y;
for (y=0; y<t->rows; y++) {
xp = pos.x;
for (x=0; x<t->cols; x++) {
if (TERMINAL_CELL_GET_FLAG(t, x, y, TERMINAL_FLAG_DIRTY)) {
c[0] = t->cells[x][y].character;
fontRender(t->font, c, t->palette[t->cells[x][y].foreground], t->palette[t->cells[x][y].background], xp, yp);
TERMINAL_CELL_CLEAR_FLAG(t, x, y, TERMINAL_FLAG_DIRTY);
}
xp += fontWidthGet(t->font);
}
yp += fontHeightGet(t->font);
}
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_DIRTY);
}
}
void terminalScreenClear(TerminalT *terminal) {
uint16_t x;
uint16_t y;
@ -735,3 +726,14 @@ static void terminalSequenceReset(TerminalT *terminal) {
terminal->parameters = NULL;
}
}
void terminalStringPrint(TerminalT *terminal, char *string) {
uint16_t i;
for (i=0; i<strlen(string); i++) {
terminalCharPrint(terminal, string[i]);
}
}

View file

@ -85,13 +85,13 @@ typedef struct TerminalS {
void terminalBackgroundSet(TerminalT *terminal, uint8_t color);
void terminalCharPrint(TerminalT *terminal, uint8_t c);
void terminalCursorMove(TerminalT *terminal, uint16_t col, uint16_t row);
void terminalForegroundSet(TerminalT *terminal, uint8_t color);
WidgetT *terminalInit(WidgetT *widget, uint16_t cols, uint16_t rows);
TerminalT *terminalNew(uint16_t x, uint16_t y, uint16_t cols, uint16_t rows);
void terminalPrint(TerminalT *terminal, char *string);
void terminalPrintChar(TerminalT *terminal, uint8_t c);
void terminalScreenClear(TerminalT *terminal);
void terminalStringPrint(TerminalT *terminal, char *string);
#endif // TERMINAL_H

View file

@ -47,11 +47,6 @@ static void textboxFocusEvent(WidgetT *widget, uint8_t focused) {
}
char *textboxGetValue(TextboxT *textbox) {
return textbox->value;
}
WidgetT *textboxInit(WidgetT *widget, char *title) {
TextboxT *t = (TextboxT *)widget;
@ -70,7 +65,7 @@ WidgetT *textboxInit(WidgetT *widget, char *title) {
t->value[0] = 0;
// Visible is set in textboxSetTitle
textboxSetTitle(t, title);
textboxTitleSet(t, title);
return widget;
}
@ -98,7 +93,7 @@ static void textboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extende
case 79: // END
// We cheat and just reset the value. That moves the offset and cursor.
temp = strdup(t->value);
textboxSetValue(t, temp);
textboxValueSet(t, temp);
free(temp);
break;
@ -201,6 +196,17 @@ static void textboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extende
}
void textboxLengthMaxSet(TextboxT *textbox, uint16_t length) {
char *temp = strdup(textbox->value);
free(textbox->value);
textbox->maxLength = length + 1;
textbox->value = (char *)malloc(textbox->maxLength);
textboxValueSet(textbox, temp);
free(temp);
}
static void textboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
TextboxT *t = (TextboxT *)widget;
RectT textArea;
@ -268,11 +274,11 @@ static void textboxPaint(WidgetT *widget, RectT pos) {
fontRender(_guiFont, t->title, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y + 2 + _guiMetric[METRIC_TEXTBOX_VERTICAL_PADDING]);
// Draw outline of textbox.
surfaceDrawHighlightFrame( pos.x + labelWidth, pos.y, pos.x + labelWidth + valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_TEXTBOX_SHADOW], _guiColor[COLOR_TEXTBOX_HIGHLIGHT]);
surfaceDrawRectangle( pos.x + labelWidth + 1, pos.y + 1, pos.x + labelWidth + valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]);
surfaceHighlightFrameDraw( pos.x + labelWidth, pos.y, pos.x + labelWidth + valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_TEXTBOX_SHADOW], _guiColor[COLOR_TEXTBOX_HIGHLIGHT]);
surfaceRectangleDraw( pos.x + labelWidth + 1, pos.y + 1, pos.x + labelWidth + valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]);
// Draw background.
surfaceDrawRectangleFilled(pos.x + labelWidth + 2, pos.y + 2, pos.x + labelWidth + valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_TEXTBOX_BACKGROUND]);
surfaceRectangleFilledDraw(pos.x + labelWidth + 2, pos.y + 2, pos.x + labelWidth + valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_TEXTBOX_BACKGROUND]);
// Where's the text display start?
textX = pos.x + labelWidth + 2 + _guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING];
@ -295,7 +301,23 @@ static void textboxPaint(WidgetT *widget, RectT pos) {
}
void textboxSetValue(TextboxT *textbox, char *value) {
void textboxTitleSet(TextboxT *textbox, char *title) {
if (textbox->title) free(textbox->title);
textbox->title = strdup(title);
// Figure out how many characters we have room to display.
textbox->visible = (textbox->base.pos.w - ((strlen(title) * fontWidthGet(_guiFont)) + _guiMetric[METRIC_TEXTBOX_PADDING] + 4 + (_guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING] * 2))) / fontWidthGet(_guiFont);
GUI_SET_FLAG((WidgetT *)textbox, WIDGET_FLAG_DIRTY);
}
char *textboxValueGet(TextboxT *textbox) {
return textbox->value;
}
void textboxValueSet(TextboxT *textbox, char *value) {
// Copy it & truncate if needed.
strncpy(textbox->value, value, textbox->maxLength - 1);
@ -309,25 +331,3 @@ void textboxSetValue(TextboxT *textbox, char *value) {
GUI_SET_FLAG((WidgetT *)textbox, WIDGET_FLAG_DIRTY);
}
void textboxSetMaxLength(TextboxT *textbox, uint16_t length) {
char *temp = strdup(textbox->value);
free(textbox->value);
textbox->maxLength = length + 1;
textbox->value = (char *)malloc(textbox->maxLength);
textboxSetValue(textbox, temp);
free(temp);
}
void textboxSetTitle(TextboxT *textbox, char *title) {
if (textbox->title) free(textbox->title);
textbox->title = strdup(title);
// Figure out how many characters we have room to display.
textbox->visible = (textbox->base.pos.w - ((strlen(title) * fontWidthGet(_guiFont)) + _guiMetric[METRIC_TEXTBOX_PADDING] + 4 + (_guiMetric[METRIC_TEXTBOX_HORIZONTAL_PADDING] * 2))) / fontWidthGet(_guiFont);
GUI_SET_FLAG((WidgetT *)textbox, WIDGET_FLAG_DIRTY);
}

View file

@ -37,12 +37,12 @@ typedef struct TextboxS {
} TextboxT;
char *textboxGetValue(TextboxT *textbox);
WidgetT *textboxInit(WidgetT *widget, char *title);
void textboxLengthMaxSet(TextboxT *textbox, uint16_t length);
TextboxT *textboxNew(uint16_t x, uint16_t y, uint16_t w, char *title);
void textboxSetValue(TextboxT *textbox, char *value);
void textboxSetMaxLength(TextboxT *textbox, uint16_t length);
void textboxSetTitle(TextboxT *textbox, char *title);
void textboxTitleSet(TextboxT *textbox, char *title);
char *textboxValueGet(TextboxT *textbox);
void textboxValueSet(TextboxT *textbox, char *value);
#endif // TEXTBOX_H

View file

@ -40,8 +40,8 @@ static void updownFocusEvent(WidgetT *widget, uint8_t focused);
static void updownMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
static void updownKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
static void updownPaint(WidgetT *widget, RectT pos);
static void updownSetVisible(UpdownT *updown);
static void updownSizesRecalculate(UpdownT *updown);
static void updownVisibleSet(UpdownT *updown);
static void updownDel(WidgetT **widget) {
@ -61,11 +61,6 @@ static void updownFocusEvent(WidgetT *widget, uint8_t focused) {
}
int32_t updownGetValue(UpdownT *updown) {
return updown->value;
}
WidgetT *updownInit(WidgetT *widget, int32_t min, int32_t max, int32_t step, char *title) {
UpdownT *u = (UpdownT *)widget;
@ -79,10 +74,10 @@ WidgetT *updownInit(WidgetT *widget, int32_t min, int32_t max, int32_t step, cha
u->title = NULL;
u->value = 0;
updownSetTitle(u, title); // Needs to be set first so updownSizesRecalculate works.
updownSetMinimum(u, min);
updownSetMaximum(u, max);
updownSetStep(u, step);
updownTitleSet(u, title); // Needs to be set first so updownSizesRecalculate works.
updownMinimumSet(u, min);
updownMaximumSet(u, max);
updownStepSet(u, step);
return widget;
}
@ -168,6 +163,22 @@ static void updownKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended
}
void updownMaximumSet(UpdownT *updown, int32_t maximum) {
if (maximum > updown->minimum) {
updown->maximum = maximum;
updownVisibleSet(updown);
}
}
void updownMinimumSet(UpdownT *updown, int32_t minimum) {
if (minimum < updown->maximum) {
updown->minimum = minimum;
updownVisibleSet(updown);
}
}
static void updownMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event) {
UpdownT *u = (UpdownT *)widget;
uint16_t o;
@ -254,39 +265,39 @@ static void updownPaint(WidgetT *widget, RectT pos) {
fontRender(_guiFont, u->title, _guiColor[COLOR_UPDOWN_TEXT], _guiColor[COLOR_WINDOW_BACKGROUND], pos.x, pos.y + 2 + _guiMetric[METRIC_UPDOWN_VERTICAL_PADDING]);
// Draw outline of text.
surfaceDrawHighlightFrame( pos.x + _labelWidth, pos.y, pos.x + _labelWidth + _valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceDrawRectangle( pos.x + _labelWidth + 1, pos.y + 1, pos.x + _labelWidth + _valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]);
surfaceHighlightFrameDraw( pos.x + _labelWidth, pos.y, pos.x + _labelWidth + _valueWidth + 2, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceRectangleDraw( pos.x + _labelWidth + 1, pos.y + 1, pos.x + _labelWidth + _valueWidth + 1, pos.y + pos.h - 1, _guiColor[COLOR_WINDOW_BACKGROUND]);
// Draw text background.
surfaceDrawRectangleFilled(pos.x + _labelWidth + 2, pos.y + 2, pos.x + _labelWidth + _valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_UPDOWN_BACKGROUND]);
surfaceRectangleFilledDraw(pos.x + _labelWidth + 2, pos.y + 2, pos.x + _labelWidth + _valueWidth, pos.y + pos.h - 2, _guiColor[COLOR_UPDOWN_BACKGROUND]);
// Draw arrows outline
surfaceDrawHighlightFrame(_arrowStart, pos.y, _arrowStart + _arrowWidth + 1, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceHighlightFrameDraw(_arrowStart, pos.y, _arrowStart + _arrowWidth + 1, pos.y + pos.h, _guiColor[COLOR_UPDOWN_SHADOW], _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
// Draw arrows background
surfaceDrawRectangleFilled(_arrowStart + 1, pos.y + 1, _arrowStart + _arrowWidth, pos.y + pos.h - 1, _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND]);
surfaceRectangleFilledDraw(_arrowStart + 1, pos.y + 1, _arrowStart + _arrowWidth, pos.y + pos.h - 1, _guiColor[COLOR_UPDOWN_ARROWS_BACKGROUND]);
// Draw up arrow
_arrowStart += _halfFont + 1 + _guiMetric[METRIC_UPDOWN_HORIZONTAL_PADDING]; // Center of up arrow
o = pos.y + 1 + _guiMetric[METRIC_UPDOWN_VERTICAL_PADDING]; // Top of up arrow
color = u->value < u->maximum ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE];
for (i=0; i<=fontHeightGet(_guiFont); i++) {
surfaceDrawLine(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color);
surfaceLineDraw(_arrowStart - i * 0.5, o + i, _arrowStart + i * 0.5, o + i, color);
}
surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceDrawLine(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceLineDraw(_arrowStart - _halfFont, o + fontHeightGet(_guiFont), _arrowStart + _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceLineDraw(_arrowStart, o, _arrowStart - _halfFont, o + fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
// Draw down arrow
_arrowStart += fontHeightGet(_guiFont) + 1; // Center of down arrow
o += fontHeightGet(_guiFont); // Bottom of down arrow
color = u->value > u->minimum ? _guiColor[COLOR_UPDOWN_ARROWS_ACTIVE] : _guiColor[COLOR_UPDOWN_ARROWS_INACTIVE];
for (i=0; i<=fontHeightGet(_guiFont); i++) {
surfaceDrawLine(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color);
surfaceLineDraw(_arrowStart - i * 0.5, o - i, _arrowStart + i * 0.5, o - i, color);
}
surfaceDrawLine(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceDrawLine(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceDrawLine(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_SHADOW]);
surfaceLineDraw(_arrowStart - _halfFont, o - fontHeightGet(_guiFont), _arrowStart + _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
surfaceLineDraw(_arrowStart, o, _arrowStart - _halfFont, o - fontHeightGet(_guiFont), _guiColor[COLOR_UPDOWN_HIGHLIGHT]);
// Where's the text display start?
textX = pos.x + _labelWidth + 2 + _guiMetric[METRIC_UPDOWN_HORIZONTAL_PADDING];
@ -308,60 +319,6 @@ static void updownPaint(WidgetT *widget, RectT pos) {
}
void updownSetMaximum(UpdownT *updown, int32_t maximum) {
if (maximum > updown->minimum) {
updown->maximum = maximum;
updownSetVisible(updown);
}
}
void updownSetMinimum(UpdownT *updown, int32_t minimum) {
if (minimum < updown->maximum) {
updown->minimum = minimum;
updownSetVisible(updown);
}
}
void updownSetStep(UpdownT *updown, int32_t step) {
updown->step = step;
}
void updownSetTitle(UpdownT *updown, char *title) {
if (updown->title) free(updown->title);
updown->title = strdup(title);
updownSetVisible(updown);
GUI_SET_FLAG((WidgetT *)updown, WIDGET_FLAG_DIRTY);
}
void updownSetValue(UpdownT *updown, int32_t value) {
if (value >= updown->minimum && value <= updown->maximum) {
updown->value = value;
GUI_SET_FLAG((WidgetT *)updown, WIDGET_FLAG_DIRTY);
}
}
static void updownSetVisible(UpdownT *updown) {
char digits[UPDOWN_MAX_DIGITS + 1];
int8_t maxWidth;
int8_t minWidth;
// Calculate how many characters we need to be able to display.
maxWidth = snprintf(digits, UPDOWN_MAX_DIGITS, "%ld", (long)updown->maximum); // Weird typecasting prevents warnings in both DOS and Linux (32 and 64 bit)
minWidth = snprintf(digits, UPDOWN_MAX_DIGITS, "%ld", (long)updown->minimum); // Weird typecasting prevents warnings in both DOS and Linux (32 and 64 bit)
updown->visible = maxWidth > minWidth ? maxWidth : minWidth;
// Calculate width of the widget.
updownSizesRecalculate(updown);
updown->base.pos.w = _arrowStart + _arrowWidth + 1;
}
static void updownSizesRecalculate(UpdownT *updown) {
// Label [ 0] ^v
@ -377,3 +334,46 @@ static void updownSizesRecalculate(UpdownT *updown) {
_arrowWidth = (fontHeightGet(_guiFont) * 2) + 1 + 2 + (_guiMetric[METRIC_UPDOWN_HORIZONTAL_PADDING] * 2); // Arrow width = font height
_arrowStart = _labelWidth + _valueWidth + 2 + _guiMetric[METRIC_UPDOWN_ARROW_PADDING];
}
void updownStepSet(UpdownT *updown, int32_t step) {
updown->step = step;
}
void updownTitleSet(UpdownT *updown, char *title) {
if (updown->title) free(updown->title);
updown->title = strdup(title);
updownVisibleSet(updown);
GUI_SET_FLAG((WidgetT *)updown, WIDGET_FLAG_DIRTY);
}
int32_t updownValueGet(UpdownT *updown) {
return updown->value;
}
void updownValueSet(UpdownT *updown, int32_t value) {
if (value >= updown->minimum && value <= updown->maximum) {
updown->value = value;
GUI_SET_FLAG((WidgetT *)updown, WIDGET_FLAG_DIRTY);
}
}
static void updownVisibleSet(UpdownT *updown) {
char digits[UPDOWN_MAX_DIGITS + 1];
int8_t maxWidth;
int8_t minWidth;
// Calculate how many characters we need to be able to display.
maxWidth = snprintf(digits, UPDOWN_MAX_DIGITS, "%ld", (long)updown->maximum); // Weird typecasting prevents warnings in both DOS and Linux (32 and 64 bit)
minWidth = snprintf(digits, UPDOWN_MAX_DIGITS, "%ld", (long)updown->minimum); // Weird typecasting prevents warnings in both DOS and Linux (32 and 64 bit)
updown->visible = maxWidth > minWidth ? maxWidth : minWidth;
// Calculate width of the widget.
updownSizesRecalculate(updown);
updown->base.pos.w = _arrowStart + _arrowWidth + 1;
}

View file

@ -37,14 +37,14 @@ typedef struct UpdownS {
} UpdownT;
int32_t updownGetValue(UpdownT *updown);
WidgetT *updownInit(WidgetT *widget, int32_t min, int32_t max, int32_t step, char *title);
void updownMaximumSet(UpdownT *updown, int32_t maximum);
void updownMinimumSet(UpdownT *updown, int32_t minimum);
UpdownT *updownNew(uint16_t x, uint16_t y, int32_t min, int32_t max, int32_t step, char *title);
void updownSetValue(UpdownT *updown, int32_t value);
void updownSetMaximum(UpdownT *updown, int32_t maximum);
void updownSetMinimum(UpdownT *updown, int32_t minimum);
void updownSetStep(UpdownT *updown, int32_t step);
void updownSetTitle(UpdownT *updown, char *title);
void updownStepSet(UpdownT *updown, int32_t step);
void updownTitleSet(UpdownT *updown, char *title);
int32_t updownValueGet(UpdownT *updown);
void updownValueSet(UpdownT *updown, int32_t value);
#endif // UPDOWN_H

View file

@ -21,13 +21,42 @@
#include "window.h"
static void windowDeactivateAll(WidgetT *widget);
static void windowAllDeactivate(WidgetT *widget);
static void windowDel(WidgetT **widget);
static void windowMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t y, uint8_t event);
static void windowPaint(WidgetT *widget, RectT pos);
static void windowDeactivateAll(WidgetT *widget) {
void windowActiveSet(WindowT *window) {
size_t len;
int16_t i;
WidgetT *parent = W(window)->parent;
WidgetT *child;
// Deactivate all windows.
windowAllDeactivate(guiRootGet());
// Activate us.
GUI_SET_FLAG(W(window), WIDGET_FLAG_ACTIVE);
// Find our window in the widget list.
len = arrlenu(parent->children);
for (i=len-1; i>=0; i--) {
child = parent->children[i];
if (child == W(window)) {
// Move to the top of the widget list.
arrdel(parent->children, i);
arrput(parent->children, child);
break;
}
}
// Tell the GUI.
_guiActiveWindow = window;
}
static void windowAllDeactivate(WidgetT *widget) {
size_t len = arrlenu(widget->children);
size_t x;
@ -35,13 +64,13 @@ static void windowDeactivateAll(WidgetT *widget) {
if (widget->magic == MAGIC_WINDOW) {
// Deactivate it.
GUI_CLEAR_FLAG(widget, WIDGET_FLAG_ACTIVE);
guiSetWidgetAndChildrenDirty(widget);
guiWidgetAndChildrenDirtySet(widget);
}
// Process any children.
if (len > 0) {
for (x=0; x<len; x++) {
windowDeactivateAll(widget->children[x]);
windowAllDeactivate(widget->children[x]);
}
}
}
@ -66,7 +95,7 @@ WidgetT *windowInit(WidgetT *window, char *title) {
win->flags = 0;
win->title = NULL;
windowSetTitle(win, title);
windowTitleSet(win, title);
GUI_SET_FLAG(window, WIDGET_FLAG_OWNS_SURFACE);
win->base.surface = surfaceCreate(win->base.pos.w, win->base.pos.h);
@ -87,7 +116,7 @@ static void windowMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_
(void)x;
// Raise window?
if (event == MOUSE_EVENT_LEFT_UP && !GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) windowSetActive(window);
if (event == MOUSE_EVENT_LEFT_UP && !GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) windowActiveSet(window);
// Start dragging?
if (event == MOUSE_EVENT_LEFT_DOWN && GUI_GET_FLAG(widget, WIDGET_FLAG_ACTIVE)) {
@ -158,14 +187,14 @@ static void windowPaint(WidgetT *widget, RectT pos) {
surfaceClear(_guiColor[COLOR_WINDOW_BACKGROUND]);
// Outer edge.
surfaceDrawHighlightFrame(0, 0, x2, y2, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]);
surfaceHighlightFrameDraw(0, 0, x2, y2, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]);
// Inner edge - skip METRIC_WINDOW_BORDER_WIDTH pixels. Be sure shadow and highlight are not included in the width.
surfaceDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, y2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, _guiColor[COLOR_WINDOW_SHADOW], _guiColor[COLOR_WINDOW_HIGHLIGHT]);
surfaceHighlightFrameDraw(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 2, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, y2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 2, _guiColor[COLOR_WINDOW_SHADOW], _guiColor[COLOR_WINDOW_HIGHLIGHT]);
// Title bar - METRIC_WINDOW_TITLE_HEIGHT pixels high. Be sure shadow and highlight are not included in the width.
surfaceDrawHighlightFrame(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 4, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]);
surfaceDrawRectangleFilled(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 2, background);
surfaceHighlightFrameDraw(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 3, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 3, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 4, _guiColor[COLOR_WINDOW_HIGHLIGHT], _guiColor[COLOR_WINDOW_SHADOW]);
surfaceRectangleFilledDraw(_guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 4, x2 - _guiMetric[METRIC_WINDOW_BORDER_WIDTH] - 4, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + _guiMetric[METRIC_WINDOW_TITLE_HEIGHT] + 2, background);
fontRender(_guiFont, w->title, text, background, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 16, _guiMetric[METRIC_WINDOW_BORDER_WIDTH] + 5);
@ -174,36 +203,7 @@ static void windowPaint(WidgetT *widget, RectT pos) {
}
void windowSetActive(WindowT *window) {
size_t len;
int16_t i;
WidgetT *parent = W(window)->parent;
WidgetT *child;
// Deactivate all windows.
windowDeactivateAll(guiRootGet());
// Activate us.
GUI_SET_FLAG(W(window), WIDGET_FLAG_ACTIVE);
// Find our window in the widget list.
len = arrlenu(parent->children);
for (i=len-1; i>=0; i--) {
child = parent->children[i];
if (child == W(window)) {
// Move to the top of the widget list.
arrdel(parent->children, i);
arrput(parent->children, child);
break;
}
}
// Tell the GUI.
_guiActiveWindow = window;
}
void windowSetTitle(WindowT *window, char *title) {
void windowTitleSet(WindowT *window, char *title) {
if (window->title) free(window->title);
window->title = strdup(title);
}

View file

@ -39,10 +39,10 @@ typedef struct WindowS {
} WindowT;
void windowActiveSet(WindowT *window);
WidgetT *windowInit(WidgetT *window, char *title);
WindowT *windowNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
void windowSetActive(WindowT *window);
void windowSetTitle(WindowT *window, char *title);
void windowTitleSet(WindowT *window, char *title);
#endif // WINDOW_H

View file

@ -65,22 +65,22 @@ long biostime(int cmd, long newtime) {
}
uint8_t keyAlt(void) {
uint8_t keyAltGet(void) {
return _alt;
}
uint8_t keyASCII(void) {
uint8_t keyASCIIGet(void) {
return _ASCIIKeep;
}
uint8_t keyControl(void) {
uint8_t keyControlGet(void) {
return _control;
}
uint8_t keyExtended(void) {
uint8_t keyExtendedGet(void) {
return _extended;
}
@ -115,12 +115,12 @@ uint8_t keyHit(void) {
}
uint8_t keyScanCode(void) {
uint8_t keyScanCodeGet(void) {
return _scanCode;
}
uint8_t keyShift(void) {
uint8_t keyShiftGet(void) {
return _shift;
}
@ -263,7 +263,7 @@ ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) {
void vbePresent(void) {
uint16_t x;
uint16_t y;
SurfaceT *s = surfaceOffscreenGet();
SurfaceT *s = surfaceOffScreenGet();
uint32_t p;
uint8_t r;
uint8_t g;

View file

@ -21,7 +21,6 @@
/*
* To Do:
*
* - Fix function naming to be classItemVerb (checkboxValueGet instead of checkboxGetValue)
* - Replace any direct data manipulation from outside a class with methods to handle it
* - More widget states: Ghosted, hidden
* - Methods that can change the width of a widget (such as setTitle) need to repaint the parent window as well
@ -67,35 +66,19 @@ static TerminalT *t1 = NULL;
static uint8_t lastKey = 0;
void buttonClick(WidgetT *widget) {
static void buttonClick(WidgetT *widget);
static void mainLoop(void *data);
static void terminalTest(void *data);
static void test(void *data);
static void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle);
static void buttonClick(WidgetT *widget) {
logWrite("'%s' was clicked.\n", ((ButtonT *)widget)->title);
}
void drawWidgetDebug(WidgetT *widget, uint8_t debugToggle) {
size_t len = arrlenu(widget->children);
size_t i;
RectT r;
if (debugToggle) {
// Clipping region (blue)
guiWidgetBoundsDrawableOnScreenGet(widget, &r);
surfaceDrawRectangle(r.x, r.y, r.x + r.w, r.y + r.h, vbeColorMake(0, 0, 255));
} else {
// Widget border (red)
guiWidgetPositionOnScreenGet(widget, &r);
surfaceDrawRectangle(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeColorMake(255, 0, 0));
}
if (len > 0) {
for (i=0; i<len; i++) {
drawWidgetDebug(widget->children[i], debugToggle);
}
}
}
void mainLoop(void *data) {
static void mainLoop(void *data) {
MouseT *mouse = NULL;
ImageT *pointer = NULL;
ColorT alpha;
@ -111,14 +94,14 @@ void mainLoop(void *data) {
timerUpdate();
mouse = mouseRead();
if (keyHit()) {
key = keyASCII();
key = keyASCIIGet();
lastKey = key; //***DEBUG***
guiProcessKeyboard(keyASCII(), keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
guiKeyboardProcess(keyASCIIGet(), keyExtendedGet(), keyScanCodeGet(), keyShiftGet(), keyControlGet(), keyAltGet());
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", key, keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
} else {
key = 0;
}
guiProcessMouse(mouse);
guiMouseProcess(mouse);
guiComposite();
imageRenderWithAlpha(pointer, mouse->x, mouse->y, alpha);
@ -127,7 +110,7 @@ void mainLoop(void *data) {
debugState++;
if (debugState > 2) debugState = 0;
}
if (debugState > 0) drawWidgetDebug(guiRootGet(), debugState - 1);
if (debugState > 0) widgetDebugDraw(guiRootGet(), debugState - 1);
//if (timerHalfSecondOn) guiDrawRectangle(0, 0, vbeSurfaceWidthGet() - 1, vbeSurfaceHeightGet() - 1, vbeMakeColor(255, 255, 255));
vbeVBlankWait();
@ -139,30 +122,7 @@ void mainLoop(void *data) {
}
void terminalTest(void *data) {
FILE *in = NULL;
char *buffer = NULL;
uint16_t length = 0;
(void)data;
// Load ANSI file for terminal test.
in = fopen("kanga.ans", "rt");
fseek(in, 0, SEEK_END);
length = ftell(in);
fseek(in, 0, SEEK_SET);
buffer = (char *)malloc(length + 1);
fread(buffer, 1, length, in);
fclose(in);
buffer[length] = 0;
terminalPrint(t1, buffer);
free(buffer);
}
void test(void *data) {
static void test(void *data) {
DesktopT *desktop = (DesktopT *)guiRootGet();
WindowT *w1 = NULL;
WindowT *w2 = NULL;
@ -200,17 +160,17 @@ void test(void *data) {
p1 = pictureNew(0, 0, "kanga.png");
guiAttach(W(w1), W(p1));
lb1 = listboxNew(155, 10, 120, 140, "List Box");
listboxAddItem(lb1, "One");
listboxAddItem(lb1, "Two");
listboxAddItem(lb1, "Three");
listboxAddItem(lb1, "Four");
listboxAddItem(lb1, "Five");
listboxAddItem(lb1, "Six");
listboxAddItem(lb1, "Seven");
listboxAddItem(lb1, "Eight");
listboxAddItem(lb1, "Nine");
listboxAddItem(lb1, "Ten");
listboxSetStep(lb1, 3);
listboxItemAdd(lb1, "One");
listboxItemAdd(lb1, "Two");
listboxItemAdd(lb1, "Three");
listboxItemAdd(lb1, "Four");
listboxItemAdd(lb1, "Five");
listboxItemAdd(lb1, "Six");
listboxItemAdd(lb1, "Seven");
listboxItemAdd(lb1, "Eight");
listboxItemAdd(lb1, "Nine");
listboxItemAdd(lb1, "Ten");
listboxStepSet(lb1, 3);
guiAttach(W(w1), W(lb1));
// Window 2
@ -226,13 +186,13 @@ void test(void *data) {
guiAttach(W(w2), W(r2b));
r3b = radioNew(30 + widgetWidthGet(W(r1b)) + widgetWidthGet(W(r2b)), 35, "Radio 3b", 2);
guiAttach(W(w2), W(r3b));
radioSetSelected(r1a);
radioSetSelected(r2b);
radioSelectedSet(r1a);
radioSelectedSet(r2b);
tb1 = textboxNew(10, 60, 265, "Test Textbox");
textboxSetValue(tb1, "Really long text string to edit!");
textboxValueSet(tb1, "Really long text string to edit!");
guiAttach(W(w2), W(tb1));
tb2 = textboxNew(10, 85, 265, "Test Textbox");
textboxSetValue(tb2, "Short string.");
textboxValueSet(tb2, "Short string.");
guiAttach(W(w2), W(tb2));
u1 = updownNew(10, 110, 0, 1024, 5, "UpDown");
guiAttach(W(w2), W(u1));
@ -255,6 +215,52 @@ void test(void *data) {
}
static void terminalTest(void *data) {
FILE *in = NULL;
char *buffer = NULL;
uint16_t length = 0;
(void)data;
// Load ANSI file for terminal test.
in = fopen("kanga.ans", "rt");
fseek(in, 0, SEEK_END);
length = ftell(in);
fseek(in, 0, SEEK_SET);
buffer = (char *)malloc(length + 1);
fread(buffer, 1, length, in);
fclose(in);
buffer[length] = 0;
terminalStringPrint(t1, buffer);
free(buffer);
}
static void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle) {
size_t len = arrlenu(widget->children);
size_t i;
RectT r;
if (debugToggle) {
// Clipping region (blue)
guiWidgetBoundsDrawableOnScreenGet(widget, &r);
surfaceRectangleDraw(r.x, r.y, r.x + r.w, r.y + r.h, vbeColorMake(0, 0, 255));
} else {
// Widget border (red)
guiWidgetPositionOnScreenGet(widget, &r);
surfaceRectangleDraw(r.x, r.y, r.x + widget->pos.w, r.y + widget->pos.h, vbeColorMake(255, 0, 0));
}
if (len > 0) {
for (i=0; i<len; i++) {
widgetDebugDraw(widget->children[i], debugToggle);
}
}
}
int main(int argc, char *argv[]) {
uint16_t xResolution = 0;

View file

@ -25,13 +25,13 @@
#include "os.h"
uint8_t keyAlt(void);
uint8_t keyASCII(void);
uint8_t keyControl(void);
uint8_t keyExtended(void);
uint8_t keyAltGet(void);
uint8_t keyASCIIGet(void);
uint8_t keyControlGet(void);
uint8_t keyExtendedGet(void);
uint8_t keyHit(void);
uint8_t keyScanCode(void);
uint8_t keyShift(void);
uint8_t keyScanCodeGet(void);
uint8_t keyShiftGet(void);
void keyShutdown(void);
void keyStartup(void);

View file

@ -41,9 +41,9 @@ typedef struct MouseS {
} MouseT;
MouseT *mouseRead(void);
void mouseShutdown(void);
int16_t mouseStartup(void);
MouseT *mouseRead(void);
#endif // MOUSE_H

View file

@ -114,15 +114,20 @@ void surfaceDestroy(SurfaceT **surface) {
}
void surfaceDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight) {
surfaceDrawLine(x1, y1, x2, y1, upperLeft);
surfaceDrawLine(x1, y1, x1, y2, upperLeft);
surfaceDrawLine(x1, y2, x2, y2, lowerRight);
surfaceDrawLine(x2, y1, x2, y2, lowerRight);
uint16_t surfaceHeightGet(void) {
return _activeSurface->height;
}
void surfaceDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
void surfaceHighlightFrameDraw(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight) {
surfaceLineDraw(x1, y1, x2, y1, upperLeft);
surfaceLineDraw(x1, y1, x1, y2, upperLeft);
surfaceLineDraw(x1, y2, x2, y2, lowerRight);
surfaceLineDraw(x2, y1, x2, y2, lowerRight);
}
void surfaceLineDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
int16_t x;
int16_t y;
int16_t dx;
@ -182,15 +187,20 @@ void surfaceDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT colo
}
void surfaceDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
surfaceDrawLine(x1, y1, x2, y1, color);
surfaceDrawLine(x2, y1, x2, y2, color);
surfaceDrawLine(x1, y2, x2, y2, color);
surfaceDrawLine(x1, y1, x1, y2, color);
SurfaceT *surfaceOffScreenGet(void) {
return _offScreenSurface;
}
void surfaceDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
void surfaceRectangleDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
surfaceLineDraw(x1, y1, x2, y1, color);
surfaceLineDraw(x2, y1, x2, y2, color);
surfaceLineDraw(x1, y2, x2, y2, color);
surfaceLineDraw(x1, y1, x1, y2, color);
}
void surfaceRectangleFilledDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color) {
uint16_t x;
uint16_t y;
@ -202,21 +212,6 @@ void surfaceDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2,
}
uint16_t surfaceHeightGet(void) {
return _activeSurface->height;
}
uint16_t surfaceWidthGet(void) {
return _activeSurface->width;
}
SurfaceT *surfaceOffscreenGet(void) {
return _offScreenSurface;
}
void surfaceSet(SurfaceT *surface) {
if (surface) {
_activeSurface = surface;
@ -241,3 +236,8 @@ uint8_t surfaceStartup(void) {
return (_offScreenSurface == NULL ? 1 : 0);
}
uint16_t surfaceWidthGet(void) {
return _activeSurface->width;
}

View file

@ -46,16 +46,16 @@ void surfaceBlit(SurfaceT *source, uint16_t x, uint16_t y);
void surfaceClear(ColorT color);
SurfaceT *surfaceCreate(uint16_t width, uint16_t height);
void surfaceDestroy(SurfaceT **surface);
void surfaceDrawHighlightFrame(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight);
void surfaceDrawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
void surfaceDrawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
void surfaceDrawRectangleFilled(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
uint16_t surfaceHeightGet(void);
uint16_t surfaceWidthGet(void);
SurfaceT *surfaceOffscreenGet(void);
void surfaceHighlightFrameDraw(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, ColorT upperLeft, ColorT lowerRight);
void surfaceLineDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
SurfaceT *surfaceOffScreenGet(void);
void surfaceRectangleDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
void surfaceRectangleFilledDraw(int16_t x1, int16_t y1, int16_t x2, int16_t y2, ColorT color);
void surfaceSet(SurfaceT *surface);
void surfaceShutdown(void);
uint8_t surfaceStartup(void);
uint16_t surfaceWidthGet(void);
#endif // SURFACE_H