diff --git a/src/ugui_impl.c3 b/src/ugui_core.c3 similarity index 53% rename from src/ugui_impl.c3 rename to src/ugui_core.c3 index 5503e34..793885a 100644 --- a/src/ugui_impl.c3 +++ b/src/ugui_core.c3 @@ -1,6 +1,177 @@ module ugui; +import vtree; +import cache; +import fifo; + import std::io; +import std::core::string; + +struct Rect { + short x, y, w, h; +} + +struct Point { + short x, y; +} + +struct Color{ + char r, g, b, a; +} + +// element ids are just long ints +def Id = usz; + +enum ElemType { + ETYPE_NONE, + ETYPE_DIV, + ETYPE_BUTTON, + ETYPE_SLIDER, + ETYPE_TEXT, +} + +bitstruct ElemFlags : uint { + bool updated : 0; + bool has_focus : 1; + bool is_new : 2; +} + +bitstruct ElemEvents : uint { + bool key_press : 0; + bool key_release : 1; + bool key_hold : 2; + bool mouse_hover : 3; + bool mouse_press : 4; + bool mouse_release : 5; + bool mouse_hold : 6; + bool update : 7; +} + +struct ElemText { + char* str; +} + +// element structure +struct Elem { + Id id; + ElemFlags flags; + ElemEvents events; + Rect bounds; + ElemType type; + union { + ElemDiv div; + ElemButton button; + ElemSlider slider; + ElemText text; + } +} + + +// relationships between elements are stored in a tree, it stores just the ids +def IdTree = vtree::VTree() @private; + +// elements themselves are kept in a cache +const uint MAX_ELEMENTS = 1024; +def ElemCache = cache::Cache() @private; + +def CmdQueue = fifo::Fifo(); + +fault UgError { + INVALID_SIZE, + EVENT_UNSUPPORTED, + UNEXPECTED_ELEMENT, + WRONG_ELEMENT_TYPE, +} + +macro Color uint_to_rgba(uint $u) { + return Color{ + .r = (char)(($u >> 24) & 0xff), + .g = (char)(($u >> 16) & 0xff), + .b = (char)(($u >> 8) & 0xff), + .a = (char)(($u >> 0) & 0xff) + }; +} + +const Rect DIV_FILL = { .x = 0, .y = 0, .w = 0, .h = 0 }; + +const uint STACK_STEP = 10; +const uint MAX_ELEMS = 128; +const uint MAX_CMDS = 256; +const uint ROOT_ID = 1; + +enum Layout { + ROW, + COLUMN, + FLOATING +} + +// global style, similar to the css box model +struct Style { // css box model + Rect padding; + Rect border; + Rect margin; + Color bgcolor; // background color + Color fgcolor; // foreground color + Color brcolor; // border color + ushort radius; +} + + +struct Ctx { + Layout layout; + IdTree tree; + ElemCache cache; + CmdQueue cmd_queue; + // total size in pixels of the context + ushort width, height; + Style style; + Font font; + + bool has_focus; + struct input { + InputEvents events; + struct mouse { + Point pos, delta; + // mouse_down: bitmap of mouse buttons that are held + // mouse_updated: bitmap of mouse buttons that have been updated + // mouse_released = mouse_updated & ~mouse_down + // mouse_pressed = mouse_updated & mouse_down + MouseButtons down; + MouseButtons updated; + } + } + + isz active_div; // tree node indicating the current active div +} + +macro point_in_rect(Point p, Rect r) +{ + return (p.x >= r.x && p.x <= r.x + r.w) && (p.y >= r.y && p.y <= r.y + r.h); +} + +// return true if rect a contains b +macro bool Rect.contains(Rect a, Rect b) +{ + return (a.x <= b.x && a.y <= b.y && a.x+a.w >= b.x+b.w && a.y+a.h >= b.y+b.h); +} + +macro Rect Rect.intersection(Rect a, Rect b) +{ + return Rect{ + .x = (short)max(a.x, b.x), + .y = (short)max(a.y, b.y), + .w = (short)min(a.x+a.w, b.x+b.w) - (short)max(a.x, b.x), + .h = (short)min(a.y+a.h, b.y+b.h) - (short)max(a.y, b.y), + }; +} + +// rect intersection not null +macro bool Rect.collides(Rect a, Rect b) +{ + return !(a.x > b.x+b.w || a.x+a.w < b.x || a.y > b.y+b.h || a.y+a.h < b.y); +} + +macro bool Rect.is_null(r) => r.x == 0 && r.y == 0 && r.x == 0 && r.w == 0; // return a pointer to the parent of the current active div fn Elem*! Ctx.get_parent(&ctx) diff --git a/src/ugui_data.c3 b/src/ugui_data.c3 deleted file mode 100644 index a10b1f3..0000000 --- a/src/ugui_data.c3 +++ /dev/null @@ -1,174 +0,0 @@ -module ugui; - -import std::core::string; - -import vtree; -import cache; -import fifo; - - -struct Rect { - short x, y, w, h; -} - -struct Point { - short x, y; -} - -struct Color{ - char r, g, b, a; -} - -// element ids are just long ints -def Id = usz; - -enum ElemType { - ETYPE_NONE, - ETYPE_DIV, - ETYPE_BUTTON, - ETYPE_SLIDER, - ETYPE_TEXT, -} - -bitstruct ElemFlags : uint { - bool updated : 0; - bool has_focus : 1; - bool is_new : 2; -} - -bitstruct ElemEvents : uint { - bool key_press : 0; - bool key_release : 1; - bool key_hold : 2; - bool mouse_hover : 3; - bool mouse_press : 4; - bool mouse_release : 5; - bool mouse_hold : 6; - bool update : 7; -} - -struct ElemText { - char* str; -} - -// element structure -struct Elem { - Id id; - ElemFlags flags; - ElemEvents events; - Rect bounds; - ElemType type; - union { - ElemDiv div; - ElemButton button; - ElemSlider slider; - ElemText text; - } -} - - -// relationships between elements are stored in a tree, it stores just the ids -def IdTree = vtree::VTree() @private; - -// elements themselves are kept in a cache -const uint MAX_ELEMENTS = 1024; -def ElemCache = cache::Cache() @private; - -def CmdQueue = fifo::Fifo(); - -fault UgError { - INVALID_SIZE, - EVENT_UNSUPPORTED, - UNEXPECTED_ELEMENT, - WRONG_ELEMENT_TYPE, -} - -macro Color uint_to_rgba(uint $u) { - return Color{ - .r = (char)(($u >> 24) & 0xff), - .g = (char)(($u >> 16) & 0xff), - .b = (char)(($u >> 8) & 0xff), - .a = (char)(($u >> 0) & 0xff) - }; -} - -const Rect DIV_FILL = { .x = 0, .y = 0, .w = 0, .h = 0 }; - -const uint STACK_STEP = 10; -const uint MAX_ELEMS = 128; -const uint MAX_CMDS = 256; -const uint ROOT_ID = 1; - -enum Layout { - ROW, - COLUMN, - FLOATING -} - -// global style, similar to the css box model -struct Style { // css box model - Rect padding; - Rect border; - Rect margin; - Color bgcolor; // background color - Color fgcolor; // foreground color - Color brcolor; // border color - ushort radius; -} - - -struct Ctx { - Layout layout; - IdTree tree; - ElemCache cache; - CmdQueue cmd_queue; - // total size in pixels of the context - ushort width, height; - Style style; - Font font; - - bool has_focus; - struct input { - InputEvents events; - struct mouse { - Point pos, delta; - // mouse_down: bitmap of mouse buttons that are held - // mouse_updated: bitmap of mouse buttons that have been updated - // mouse_released = mouse_updated & ~mouse_down - // mouse_pressed = mouse_updated & mouse_down - MouseButtons down; - MouseButtons updated; - } - } - - isz active_div; // tree node indicating the current active div -} - -macro point_in_rect(Point p, Rect r) -{ - return (p.x >= r.x && p.x <= r.x + r.w) && (p.y >= r.y && p.y <= r.y + r.h); -} - -// return true if rect a contains b -macro bool Rect.contains(Rect a, Rect b) -{ - return (a.x <= b.x && a.y <= b.y && a.x+a.w >= b.x+b.w && a.y+a.h >= b.y+b.h); -} - -macro Rect Rect.intersection(Rect a, Rect b) -{ - return Rect{ - .x = (short)max(a.x, b.x), - .y = (short)max(a.y, b.y), - .w = (short)min(a.x+a.w, b.x+b.w) - (short)max(a.x, b.x), - .h = (short)min(a.y+a.h, b.y+b.h) - (short)max(a.y, b.y), - }; -} - -// rect intersection not null -macro bool Rect.collides(Rect a, Rect b) -{ - return !(a.x > b.x+b.w || a.x+a.w < b.x || a.y > b.y+b.h || a.y+a.h < b.y); -} - -macro bool Rect.is_null(r) => r.x == 0 && r.y == 0 && r.x == 0 && r.w == 0;