You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
ugui/src/ugui_data.c3

194 lines
3.2 KiB

module ugui;
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,
}
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;
}
enum DivLayout {
LAYOUT_ROW,
LAYOUT_COLUMN,
LAYOUT_FLOATING,
}
// div element
struct Div {
DivLayout layout;
Point origin_r, origin_c;
Color color_bg;
}
// slider element
struct Slider {
float value;
Rect handle;
}
// element structure
struct Elem {
Id id;
ElemFlags flags;
ElemEvents events;
Rect rect;
ElemType type;
union {
Div div;
Slider slider;
}
}
// relationships between elements are stored in a tree, it stores just the ids
def IdTree = vtree::VTree(<Id>) @private;
// elements themselves are kept in a cache
const uint MAX_ELEMENTS = 2048;
def ElemCache = cache::Cache(<Id, Elem, MAX_ELEMENTS>) @private;
def CmdQueue = fifo::Fifo(<Cmd>);
fault UgError {
INVALID_SIZE,
EVENT_UNSUPPORTED,
UNEXPECTED_ELEMENT,
}
fn Id fnv1a(String str)
{
const ulong FNV_OFF = 0xcbf29ce484222325;
const ulong FNV_PRIME = 0x100000001b3;
ulong hash = FNV_OFF;
foreach (c : str) {
hash ^= c;
hash *= FNV_PRIME;
}
return hash;
}
macro hash(String str) { return fnv1a(str); }
macro 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 };
macro abs(a) { return a < 0 ? -a : a; }
macro clamp(x, min, max) { return x < min ? min : (x > max ? max : x); }
const uint STACK_STEP = 10;
const uint MAX_ELEMS = 128;
const uint MAX_CMDS = 256;
const uint ROOT_ID = 1;
// command type
enum CmdType {
CMD_RECT,
}
// command to draw a rect
struct CmdRect {
Rect rect;
Color color;
}
// command structure
struct Cmd {
CmdType type;
union {
CmdRect rect;
}
}
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 bcolor; // border color
}
struct Ctx {
Layout layout;
IdTree tree;
ElemCache cache;
CmdQueue cmd_queue;
// total size in pixels of the context
ushort width, height;
Style style;
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);
}