initial refactor
This commit is contained in:
parent
39e78ea078
commit
f48151b38e
82
src/main.c3
82
src/main.c3
@ -15,18 +15,15 @@ fn int main(String[] args)
|
|||||||
rl::init_window(width, height, "Ugui Test");
|
rl::init_window(width, height, "Ugui Test");
|
||||||
ctx.input_window_size(width, height)!!;
|
ctx.input_window_size(width, height)!!;
|
||||||
|
|
||||||
double[10][4] median_times;
|
|
||||||
isz frame;
|
isz frame;
|
||||||
double median_input, median_layout, median_draw, median_tot;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!rl::window_should_close()) {
|
while (!rl::window_should_close()) {
|
||||||
const int PARTIAL_INPUT = 0;
|
const int PARTIAL_INPUT = 0;
|
||||||
const int PARTIAL_LAYOUT = 1;
|
const int PARTIAL_LAYOUT = 1;
|
||||||
const int PARTIAL_DRAW = 2;
|
const int PARTIAL_DRAW = 2;
|
||||||
//timer_start();
|
|
||||||
|
|
||||||
/*** Start Input Handling ***/
|
/* Start Input Handling */
|
||||||
if (rl::is_window_resized()) {
|
if (rl::is_window_resized()) {
|
||||||
width = (short)rl::get_screen_width();
|
width = (short)rl::get_screen_width();
|
||||||
height = (short)rl::get_screen_height();
|
height = (short)rl::get_screen_height();
|
||||||
@ -48,47 +45,40 @@ fn int main(String[] args)
|
|||||||
buttons.btn_right = rl::is_mouse_button_down(rl::MOUSE_BUTTON_RIGHT);
|
buttons.btn_right = rl::is_mouse_button_down(rl::MOUSE_BUTTON_RIGHT);
|
||||||
buttons.btn_middle = rl::is_mouse_button_down(rl::MOUSE_BUTTON_MIDDLE);
|
buttons.btn_middle = rl::is_mouse_button_down(rl::MOUSE_BUTTON_MIDDLE);
|
||||||
ctx.input_mouse_button(buttons);
|
ctx.input_mouse_button(buttons);
|
||||||
|
/* End Input Handling */
|
||||||
|
|
||||||
//timer_partial(PARTIAL_INPUT);
|
/* Start UI Handling */
|
||||||
/*** End Input Handling ***/
|
|
||||||
|
|
||||||
/*** Start UI Handling ***/
|
|
||||||
ctx.frame_begin()!!;
|
ctx.frame_begin()!!;
|
||||||
|
|
||||||
// main div, fill the whole window
|
// main div, fill the whole window
|
||||||
ctx.div_begin("main", ugui::DIV_FILL)!!;
|
ctx.div_begin("main", ugui::DIV_FILL)!!;
|
||||||
{|
|
{|
|
||||||
ctx.layout_set_column()!!;
|
ctx.layout_set_column()!!;
|
||||||
if (ctx.button("button0", ugui::Rect{.y = 100, .x = 100, .w = 30, .h = 30})!!.mouse_hold) {
|
if (ctx.button("button0", ugui::Rect{100,100,30,30})!!.mouse_press) {
|
||||||
io::printn("HOLDING button0");
|
io::printn("press button0");
|
||||||
}
|
}
|
||||||
ctx.layout_next_column()!!;
|
ctx.layout_next_column()!!;
|
||||||
ctx.button("button1", ugui::Rect{.w = 30, .h = 30})!!;
|
if (ctx.button("button1", ugui::Rect{0,0,30,30})!!.mouse_press) {
|
||||||
|
io::printn("press button1");
|
||||||
|
}
|
||||||
ctx.layout_next_column()!!;
|
ctx.layout_next_column()!!;
|
||||||
ctx.button("button2", ugui::Rect{.w = 30, .h = 30})!!;
|
if (ctx.button("button2", ugui::Rect{0,0,30,30})!!.mouse_release) {
|
||||||
|
io::printn("release button2");
|
||||||
|
}
|
||||||
|};
|
|};
|
||||||
ctx.div_end()!!;
|
ctx.div_end()!!;
|
||||||
|
|
||||||
ctx.frame_end()!!;
|
ctx.frame_end()!!;
|
||||||
//timer_partial(PARTIAL_LAYOUT);
|
/* End UI Handling */
|
||||||
/*** End UI Handling ***/
|
|
||||||
|
|
||||||
/*** Start UI Drawing ***/
|
/* Start UI Drawing */
|
||||||
rl::begin_drawing();
|
rl::begin_drawing();
|
||||||
// ClearBackground(BLACK);
|
// ClearBackground(BLACK);
|
||||||
|
|
||||||
io::printn("----- Draw Begin -----");
|
|
||||||
rl::Color c;
|
rl::Color c;
|
||||||
for (Cmd* cmd; (cmd = ctx.cmd_queue.dequeue() ?? null) != null;) {
|
for (Cmd* cmd; (cmd = ctx.cmd_queue.dequeue() ?? null) != null;) {
|
||||||
switch (cmd.type) {
|
switch (cmd.type) {
|
||||||
case ugui::CmdType.CMD_RECT:
|
case ugui::CmdType.CMD_RECT:
|
||||||
io::printfn(
|
|
||||||
"draw rect x=%d y=%d w=%d h=%d",
|
|
||||||
cmd.rect.rect.x,
|
|
||||||
cmd.rect.rect.y,
|
|
||||||
cmd.rect.rect.w,
|
|
||||||
cmd.rect.rect.h
|
|
||||||
);
|
|
||||||
c = rl::Color{
|
c = rl::Color{
|
||||||
.r = cmd.rect.color.r,
|
.r = cmd.rect.color.r,
|
||||||
.g = cmd.rect.color.g,
|
.g = cmd.rect.color.g,
|
||||||
@ -106,52 +96,10 @@ fn int main(String[] args)
|
|||||||
io::printfn("Unknown cmd type: %d", cmd.type);
|
io::printfn("Unknown cmd type: %d", cmd.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io::printf("----- Draw End -----\n\n");
|
|
||||||
|
|
||||||
rl::end_drawing();
|
rl::end_drawing();
|
||||||
//timer_partial(PARTIAL_DRAW);
|
|
||||||
//timer_stop();
|
|
||||||
/*** End UI Drawing ***/
|
|
||||||
/*
|
|
||||||
median_times[frame][PARTIAL_INPUT] =
|
|
||||||
1e3 * timer_get_sec(PARTIAL_INPUT);
|
|
||||||
median_times[frame][PARTIAL_LAYOUT] =
|
|
||||||
1e3 * timer_get_sec(PARTIAL_LAYOUT);
|
|
||||||
median_times[frame][PARTIAL_DRAW] =
|
|
||||||
1e3 * timer_get_sec(PARTIAL_DRAW);
|
|
||||||
median_times[frame][3] = 1e3 * timer_get_sec(-1);
|
|
||||||
*/
|
|
||||||
frame += 1;
|
|
||||||
frame %= 10;
|
|
||||||
/*
|
|
||||||
if (frame == 0) {
|
|
||||||
median_input = 0;
|
|
||||||
median_layout = 0;
|
|
||||||
median_draw = 0;
|
|
||||||
median_tot = 0;
|
|
||||||
for (size_t i = 0; i < 10; i++) {
|
|
||||||
median_input += median_times[i][PARTIAL_INPUT];
|
|
||||||
median_layout += median_times[i][PARTIAL_LAYOUT];
|
|
||||||
median_draw += median_times[i][PARTIAL_DRAW];
|
|
||||||
median_tot += median_times[i][3];
|
|
||||||
}
|
|
||||||
median_input /= 10;
|
|
||||||
median_layout /= 10;
|
|
||||||
median_draw /= 10;
|
|
||||||
median_tot /= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("input time: %lfms\n", median_input);
|
// TODO: throttle FPS
|
||||||
printf("layout time: %lfms\n", median_layout);
|
|
||||||
printf("draw time: %lfms\n", median_draw);
|
|
||||||
printf("total time: %lfms\n", median_tot);
|
|
||||||
|
|
||||||
// Throttle Frames
|
|
||||||
// TODO: add an fps limit, time frame generation and log it
|
|
||||||
const float TARGET_FPS = 100;
|
|
||||||
float wait_time = MAX((1.0 / TARGET_FPS) - timer_get_sec(-1), 0);
|
|
||||||
WaitTime(wait_time);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rl::close_window();
|
rl::close_window();
|
||||||
@ -160,6 +108,7 @@ fn int main(String[] args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn void! test_vtree() @test
|
fn void! test_vtree() @test
|
||||||
{
|
{
|
||||||
vtree::VTree(<String>) vt;
|
vtree::VTree(<String>) vt;
|
||||||
@ -194,3 +143,4 @@ fn void! test_cache() @test
|
|||||||
r = cc.get_or_insert(&&"Ciao Mamma", 1)!;
|
r = cc.get_or_insert(&&"Ciao Mamma", 1)!;
|
||||||
assert(*r!! == "Ciao Mamma", "incorrect string");
|
assert(*r!! == "Ciao Mamma", "incorrect string");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
48
src/ugui_button.c3
Normal file
48
src/ugui_button.c3
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
module ugui;
|
||||||
|
|
||||||
|
// draw a button, return the events on that button
|
||||||
|
fn ElemEvents! Ctx.button(&ctx, String label, Rect size)
|
||||||
|
{
|
||||||
|
Id id = hash(label);
|
||||||
|
|
||||||
|
Elem *parent = ctx.get_parent()!;
|
||||||
|
Elem *c_elem = ctx.get_elem(id)!;
|
||||||
|
// add it to the tree
|
||||||
|
ctx.tree.add(id, ctx.active_div)!;
|
||||||
|
|
||||||
|
// 1. Fill the element fields
|
||||||
|
// this resets the flags
|
||||||
|
c_elem.type = ETYPE_BUTTON;
|
||||||
|
Color bg_color = uint_to_rgba(0x0000ffff);
|
||||||
|
|
||||||
|
// if the element is new or the parent was updated then redo layout
|
||||||
|
if (c_elem.flags.is_new || parent.flags.updated) {
|
||||||
|
// 2. Layout
|
||||||
|
c_elem.rect = ctx.position_element(parent, size, true);
|
||||||
|
|
||||||
|
// TODO: 3. Fill the button specific fields
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check for interactions
|
||||||
|
// FIXME: this is not how normal buttons work, usually focus follows both
|
||||||
|
// mouse hover and mouse down
|
||||||
|
c_elem.events = ctx.get_elem_events(c_elem);
|
||||||
|
if (parent.flags.has_focus) {
|
||||||
|
if (c_elem.events.mouse_hover) {
|
||||||
|
c_elem.flags.has_focus = true;
|
||||||
|
bg_color = uint_to_rgba(0x00ff00ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the button
|
||||||
|
Cmd cmd = {
|
||||||
|
.type = CMD_RECT,
|
||||||
|
.rect = {
|
||||||
|
.rect = c_elem.rect,
|
||||||
|
.color = bg_color,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ctx.cmd_queue.enqueue(&cmd)!;
|
||||||
|
|
||||||
|
return c_elem.events;
|
||||||
|
}
|
@ -28,6 +28,7 @@ enum ElemType {
|
|||||||
bitstruct ElemFlags : uint {
|
bitstruct ElemFlags : uint {
|
||||||
bool updated : 0;
|
bool updated : 0;
|
||||||
bool has_focus : 1;
|
bool has_focus : 1;
|
||||||
|
bool is_new : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitstruct ElemEvents : uint {
|
bitstruct ElemEvents : uint {
|
||||||
|
147
src/ugui_impl.c3
147
src/ugui_impl.c3
@ -11,6 +11,19 @@ fn Elem*! Ctx.get_parent(&ctx)
|
|||||||
return ctx.cache.search(parent_id);
|
return ctx.cache.search(parent_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get or push an element from the cache, return a pointer to it
|
||||||
|
// resets all flags except is_new which is set accordingly
|
||||||
|
macro Ctx.get_elem(&ctx, Id id)
|
||||||
|
{
|
||||||
|
Elem empty_elem;
|
||||||
|
bool is_new;
|
||||||
|
Elem* c_elem;
|
||||||
|
c_elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!;
|
||||||
|
c_elem.flags = (ElemFlags)0;
|
||||||
|
c_elem.flags.is_new = is_new;
|
||||||
|
return c_elem;
|
||||||
|
}
|
||||||
|
|
||||||
fn void! Ctx.init(&ctx)
|
fn void! Ctx.init(&ctx)
|
||||||
{
|
{
|
||||||
ctx.tree.init(MAX_ELEMENTS)!;
|
ctx.tree.init(MAX_ELEMENTS)!;
|
||||||
@ -39,56 +52,40 @@ fn void Ctx.free(&ctx)
|
|||||||
|
|
||||||
fn void! Ctx.frame_begin(&ctx)
|
fn void! Ctx.frame_begin(&ctx)
|
||||||
{
|
{
|
||||||
// 1. Create the root div element
|
|
||||||
// NOTE: in c3 everythong is zero initialized by default
|
|
||||||
Rect space = {
|
|
||||||
.w = ctx.width,
|
|
||||||
.h = ctx.height,
|
|
||||||
};
|
|
||||||
|
|
||||||
Elem root = {
|
|
||||||
.id = ROOT_ID,
|
|
||||||
.type = ETYPE_DIV,
|
|
||||||
.rect = space,
|
|
||||||
.div = {
|
|
||||||
.layout = LAYOUT_ROW,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// 2. Get the root element from the cache and update it
|
||||||
|
Elem* c_elem = ctx.get_elem(ROOT_ID)!;
|
||||||
// The root should have the updated flag only if the size of the window
|
// The root should have the updated flag only if the size of the window
|
||||||
// was changed between frames, this propagates an element size recalculation
|
// was changed between frames, this propagates an element size recalculation
|
||||||
// down the element tree
|
// down the element tree
|
||||||
if (ctx.input.events.resize) {
|
c_elem.flags.updated = ctx.input.events.resize;
|
||||||
root.flags.updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the window has focus then the root element also has focus, no other
|
// if the window has focus then the root element also has focus, no other
|
||||||
// computation needed, child elements need to check the mouse positon and
|
// computation needed, child elements need to check the mouse positon and
|
||||||
// other stuff
|
// other stuff
|
||||||
if (ctx.has_focus) {
|
c_elem.flags.has_focus = ctx.has_focus;
|
||||||
root.flags.has_focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: check errors
|
if (c_elem.flags.is_new || c_elem.flags.updated) {
|
||||||
// 2. Get the root element from the cache and update it
|
Elem def_root = {
|
||||||
bool is_new;
|
.id = ROOT_ID,
|
||||||
Elem empty_elem;
|
.type = ETYPE_DIV,
|
||||||
Elem* c_elem = ctx.cache.get_or_insert(&empty_elem, root.id, &is_new)!;
|
.rect = {
|
||||||
// flags always need to be set to the new flags
|
.w = ctx.width,
|
||||||
c_elem.flags = root.flags;
|
.h = ctx.height,
|
||||||
if (is_new || root.flags.updated) {
|
},
|
||||||
*c_elem = root;
|
.div = {
|
||||||
|
.layout = LAYOUT_ROW,
|
||||||
|
},
|
||||||
|
.flags = c_elem.flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
*c_elem = def_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Push the root element into the element tree
|
// 3. Push the root element into the element tree
|
||||||
ctx.active_div = ctx.tree.add(root.id, 0)!;
|
ctx.active_div = ctx.tree.add(ROOT_ID, 0)!;
|
||||||
|
|
||||||
// print_tree(ctx);
|
|
||||||
|
|
||||||
// The root element does not push anything to the stack
|
// The root element does not push anything to the stack
|
||||||
// TODO: add a background color taken from a theme or config
|
// TODO: add a background color taken from a theme or config
|
||||||
|
|
||||||
io::printn("##### Frame Begin #####");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Ctx.frame_end(&ctx)
|
fn void! Ctx.frame_end(&ctx)
|
||||||
@ -113,36 +110,22 @@ $if 1:
|
|||||||
};
|
};
|
||||||
ctx.cmd_queue.enqueue(&cmd)!;
|
ctx.cmd_queue.enqueue(&cmd)!;
|
||||||
$endif
|
$endif
|
||||||
|
|
||||||
io::printn("##### Frame End #####");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void! Ctx.div_begin(&ctx, String label, Rect size)
|
fn void! Ctx.div_begin(&ctx, String label, Rect size)
|
||||||
{
|
{
|
||||||
Id id = hash(label);
|
Id id = hash(label);
|
||||||
|
|
||||||
bool is_new;
|
|
||||||
Elem empty_elem;
|
|
||||||
Elem* c_elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!;
|
|
||||||
|
|
||||||
// FIXME: why save the id in the tree and not something more direct like
|
|
||||||
// the element pointer or the index into the cache vector?
|
|
||||||
isz div_node = ctx.tree.add(id, ctx.active_div)!;
|
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem *parent = ctx.get_parent()!;
|
||||||
|
Elem* c_elem = ctx.get_elem(id)!;
|
||||||
ctx.tree.print();
|
isz div_node = ctx.tree.add(id, ctx.active_div)!;
|
||||||
|
|
||||||
// Use the current div
|
|
||||||
ctx.active_div = div_node;
|
ctx.active_div = div_node;
|
||||||
|
|
||||||
// 1. Fill the element fields
|
// 1. Fill the element fields
|
||||||
// this resets the flags
|
|
||||||
c_elem.type = ETYPE_DIV;
|
c_elem.type = ETYPE_DIV;
|
||||||
c_elem.flags = (ElemFlags)0;
|
|
||||||
|
|
||||||
// do layout and update flags only if the element was updated
|
// do layout and update flags only if the element was updated
|
||||||
if (is_new || parent.flags.updated) {
|
if (c_elem.flags.is_new || parent.flags.updated) {
|
||||||
// 2. layout the element
|
// 2. layout the element
|
||||||
c_elem.rect = ctx.position_element(parent, size);
|
c_elem.rect = ctx.position_element(parent, size);
|
||||||
|
|
||||||
@ -183,62 +166,10 @@ fn void! Ctx.div_end(&ctx)
|
|||||||
ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
|
ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ensure elem != null
|
/**
|
||||||
|
* @ensure elem != null
|
||||||
|
**/
|
||||||
fn bool Ctx.is_hovered(&ctx, Elem *elem)
|
fn bool Ctx.is_hovered(&ctx, Elem *elem)
|
||||||
{
|
{
|
||||||
return point_in_rect(ctx.input.mouse.pos, elem.rect);
|
return point_in_rect(ctx.input.mouse.pos, elem.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ElemEvents! Ctx.button(&ctx, String label, Rect size)
|
|
||||||
{
|
|
||||||
Id id = hash(label);
|
|
||||||
|
|
||||||
// TODO: do layouting if the element is new or the parent has updated
|
|
||||||
bool is_new;
|
|
||||||
Elem empty_elem;
|
|
||||||
Elem *c_elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!;
|
|
||||||
|
|
||||||
// add it to the tree
|
|
||||||
ctx.tree.add(id, ctx.active_div)!;
|
|
||||||
ctx.tree.print();
|
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
|
||||||
|
|
||||||
// 1. Fill the element fields
|
|
||||||
// this resets the flags
|
|
||||||
c_elem.type = ETYPE_BUTTON;
|
|
||||||
c_elem.flags = (ElemFlags)0;
|
|
||||||
Color bg_color = uint_to_rgba(0x0000ffff);
|
|
||||||
|
|
||||||
// if the element is new or the parent was updated then redo layout
|
|
||||||
if (is_new || parent.flags.updated) {
|
|
||||||
// 2. Layout
|
|
||||||
c_elem.rect = ctx.position_element(parent, size, true);
|
|
||||||
|
|
||||||
// TODO: 3. Fill the button specific fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Check for interactions
|
|
||||||
if (parent.flags.has_focus) {
|
|
||||||
if (ctx.is_hovered(c_elem)) {
|
|
||||||
c_elem.flags.has_focus = true;
|
|
||||||
c_elem.events.mouse_hover = true;
|
|
||||||
bg_color = uint_to_rgba(0x00ff00ff);
|
|
||||||
c_elem.events.mouse_hold = ctx.input.mouse.down.btn_left;
|
|
||||||
} else {
|
|
||||||
c_elem.events.mouse_hover = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the button
|
|
||||||
Cmd cmd = {
|
|
||||||
.type = CMD_RECT,
|
|
||||||
.rect = {
|
|
||||||
.rect = c_elem.rect,
|
|
||||||
.color = bg_color,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
ctx.cmd_queue.enqueue(&cmd)!;
|
|
||||||
|
|
||||||
return c_elem.events;
|
|
||||||
}
|
|
||||||
|
@ -40,21 +40,64 @@ bitstruct MouseButtons : uint {
|
|||||||
bool btn_5 : 4;
|
bool btn_5 : 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro Ctx.mouse_pressed(&ctx)
|
||||||
|
{
|
||||||
|
return ctx.input.mouse.updated & ctx.input.mouse.down;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro Ctx.mouse_released(&ctx)
|
||||||
|
{
|
||||||
|
return ctx.input.mouse.updated & ~ctx.input.mouse.down;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro Ctx.mouse_down(&ctx)
|
||||||
|
{
|
||||||
|
return ctx.input.mouse.down;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MouseButtons BTN_NONE = (MouseButtons)0u;
|
||||||
|
const MouseButtons BTN_ANY = (MouseButtons)(uint.max);
|
||||||
|
const MouseButtons BTN_LEFT = {.btn_left = true};
|
||||||
|
const MouseButtons BTN_MIDDLE = {.btn_middle = true};
|
||||||
|
const MouseButtons BTN_RIGHT = {.btn_right = true};
|
||||||
|
const MouseButtons BTN_4 = {.btn_4 = true};
|
||||||
|
const MouseButtons BTN_5 = {.btn_5 = true};
|
||||||
|
|
||||||
|
// FIXME: hthis compairson could be done with a cast using MouseButtons.inner
|
||||||
|
// property but I could not figure out how
|
||||||
|
macro Ctx.is_mouse_pressed(&ctx, MouseButtons btn)
|
||||||
|
{
|
||||||
|
return (ctx.mouse_pressed() & btn) != BTN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro Ctx.is_mouse_released(&ctx, MouseButtons btn)
|
||||||
|
{
|
||||||
|
return (ctx.mouse_released() & btn) != BTN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro Ctx.is_mouse_down(&ctx, MouseButtons btn)
|
||||||
|
{
|
||||||
|
return (ctx.mouse_down() & btn) != BTN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro ElemEvents Ctx.get_elem_events(&ctx, Elem *elem)
|
||||||
|
{
|
||||||
|
// TODO: add the other events
|
||||||
|
ElemEvents ev = {
|
||||||
|
.mouse_hover = ctx.is_hovered(elem),
|
||||||
|
.mouse_press = ctx.is_mouse_pressed(BTN_ANY),
|
||||||
|
.mouse_release = ctx.is_mouse_released(BTN_ANY),
|
||||||
|
.mouse_hold = ctx.is_mouse_down(BTN_ANY),
|
||||||
|
};
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
// Mouse Button moved
|
// Mouse Button moved
|
||||||
fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons)
|
fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons)
|
||||||
{
|
{
|
||||||
ctx.input.mouse.updated = ctx.input.mouse.down ^ buttons;
|
ctx.input.mouse.updated = ctx.input.mouse.down ^ buttons;
|
||||||
ctx.input.mouse.down = buttons;
|
ctx.input.mouse.down = buttons;
|
||||||
ctx.input.events.mouse_btn = true;
|
ctx.input.events.mouse_btn = true;
|
||||||
|
|
||||||
io::printfn(
|
|
||||||
"Mouse Down: %s%s%s%s%s",
|
|
||||||
buttons.btn_left ? "BTN_LEFT " : "",
|
|
||||||
buttons.btn_right ? "BTN_RIGHT " : "",
|
|
||||||
buttons.btn_middle ? "BTN_MIDDLE " : "",
|
|
||||||
buttons.btn_4 ? "BTN_4 " : "",
|
|
||||||
buttons.btn_5 ? "BTN_5 " : ""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mouse was moved, report absolute position
|
// Mouse was moved, report absolute position
|
||||||
|
Loading…
Reference in New Issue
Block a user