actually correct input handling
This commit is contained in:
parent
fb3a964f7f
commit
b5ef86d092
7 changed files with 144 additions and 181 deletions
|
|
@ -90,6 +90,26 @@ alias ElemCache = cache::Cache{Id, Elem, MAX_ELEMENTS};
|
|||
|
||||
faultdef INVALID_SIZE, EVENT_UNSUPPORTED, WRONG_ELEMENT_TYPE, WRONG_ID;
|
||||
|
||||
struct InputData {
|
||||
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;
|
||||
// scroll wheel
|
||||
Point scroll;
|
||||
}
|
||||
struct keyboard {
|
||||
char[TEXT_MAX] text;
|
||||
usz text_len;
|
||||
ModKeys modkeys;
|
||||
}
|
||||
}
|
||||
|
||||
struct Ctx {
|
||||
IdTree tree;
|
||||
ElemCache cache;
|
||||
|
|
@ -101,26 +121,7 @@ struct Ctx {
|
|||
SpriteAtlas sprite_atlas;
|
||||
|
||||
bool has_focus;
|
||||
struct input {
|
||||
InputEvents events;
|
||||
int z_index; // the layer the input events need to be propageted to
|
||||
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;
|
||||
// scroll wheel
|
||||
Point scroll;
|
||||
}
|
||||
struct keyboard {
|
||||
char[TEXT_MAX] text;
|
||||
usz text_len;
|
||||
ModKeys modkeys;
|
||||
}
|
||||
}
|
||||
InputData input, current_input;
|
||||
|
||||
Id hover_id;
|
||||
Id focus_id;
|
||||
|
|
@ -249,7 +250,6 @@ fn void? Ctx.frame_begin(&ctx)
|
|||
// 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
|
||||
// other stuff
|
||||
ctx.input.z_index = 0;
|
||||
//elem.flags.has_focus = ctx.has_focus;
|
||||
|
||||
elem.bounds = {0, 0, ctx.width, ctx.height};
|
||||
|
|
@ -262,30 +262,41 @@ fn void? Ctx.frame_begin(&ctx)
|
|||
elem.layout.h = @exact(ctx.height);
|
||||
|
||||
ctx.div_scissor = elem.bounds;
|
||||
|
||||
// The root element does not push anything to the stack
|
||||
// TODO: add a background color taken from a theme or config
|
||||
}
|
||||
|
||||
fn void? Ctx.frame_end(&ctx)
|
||||
{
|
||||
// FIXME: this is not guaranteed to be root. the user might forget to close a div or some other element
|
||||
Elem* root = ctx.get_active_div()!;
|
||||
if (root.id != ROOT_ID) {
|
||||
io::printn(root.id);
|
||||
return WRONG_ID?;
|
||||
}
|
||||
|
||||
// 2. clear input fields
|
||||
ctx.input = ctx.current_input;
|
||||
ctx.current_input.events = {};
|
||||
ctx.current_input.keyboard.text_len = 0;
|
||||
|
||||
// DO THE LAYOUT
|
||||
ctx.layout_element_tree()!;
|
||||
|
||||
foreach (idx, id : ctx.tree.elem_vec) {
|
||||
if (!ctx.tree.is_used((int)idx)) continue;
|
||||
Elem* c = ctx.find_elem(id);
|
||||
// reset events
|
||||
c.events = {};
|
||||
// reset shown flag
|
||||
// TODO: use shown_last_frame to avoid this loop entirely
|
||||
c.flags.shown = false;
|
||||
}
|
||||
|
||||
// Propagate input events to the right elements
|
||||
ctx.set_elem_events(ctx.hover_id);
|
||||
ctx.set_elem_events(ctx.focus_id);
|
||||
|
||||
|
||||
// 1. clear the tree
|
||||
ctx.tree.nuke();
|
||||
|
||||
// 2. clear input fields
|
||||
ctx.input.events = (InputEvents)0;
|
||||
ctx.input.keyboard.text_len = 0;
|
||||
|
||||
// send atlas updates
|
||||
if (ctx.font.should_update) {
|
||||
ctx.push_update_atlas(&ctx.font.atlas)!;
|
||||
|
|
@ -325,27 +336,47 @@ $endif
|
|||
// }
|
||||
}
|
||||
|
||||
// TODO: add other events
|
||||
// FIXME: this does not work with touch
|
||||
// FIXME: hacked together, please do better
|
||||
/*
|
||||
fn ElemEvents Ctx.get_elem_events(&ctx, Elem *elem)
|
||||
|
||||
macro bool Ctx.is_hovered(&ctx, Elem *elem) => ctx.input.mouse.pos.in_rect(elem.bounds);
|
||||
|
||||
// Check if the element is hovered and/or focused, if it is update the context ids.
|
||||
// The order in which the elements are passed to this function is not relevant
|
||||
fn void Ctx.update_hover_and_focus(&ctx, Elem* elem)
|
||||
{
|
||||
// FIXME: gross hack to not leak events under a pop-up
|
||||
if (ctx.input.z_index != elem.z_index) return {};
|
||||
|
||||
bool hover = ctx.is_hovered(elem);
|
||||
bool focus = ctx.elem_focus(elem) || (hover && ctx.is_mouse_pressed(BTN_LEFT));
|
||||
bool focus = ctx.focus_id == elem.id || (hover && ctx.is_mouse_pressed(BTN_ANY));
|
||||
|
||||
if (ctx.is_mouse_pressed(BTN_ANY) && !hover){
|
||||
focus = false;
|
||||
if (ctx.focus_id == elem.id) ctx.focus_id = 0;
|
||||
if (hover) {
|
||||
Elem* prev_hover = ctx.find_elem(ctx.hover_id);
|
||||
bool different = prev_hover.id != elem.id;
|
||||
bool still_hovered = ctx.is_hovered(prev_hover);
|
||||
bool shown = prev_hover.flags.shown;
|
||||
bool above = prev_hover.z_index > elem.z_index;
|
||||
|
||||
hover = !(different && still_hovered && shown && above);
|
||||
}
|
||||
|
||||
if (focus) {
|
||||
Elem* prev_focus = ctx.find_elem(ctx.hover_id);
|
||||
bool different = prev_focus.id != elem.id;
|
||||
bool shown = prev_focus.flags.shown;
|
||||
bool above = prev_focus.z_index > elem.z_index;
|
||||
|
||||
focus = !(different && shown && above);
|
||||
}
|
||||
|
||||
if (hover) ctx.hover_id = elem.id;
|
||||
if (focus) ctx.focus_id = elem.id;
|
||||
}
|
||||
|
||||
if (hover) { ctx.hover_id = elem.id; }
|
||||
if (focus) { ctx.focus_id = elem.id; }
|
||||
// FIXME: this does not work with touch
|
||||
fn void Ctx.set_elem_events(&ctx, Id id)
|
||||
{
|
||||
bool hover = id == ctx.hover_id;
|
||||
bool focus = id == ctx.focus_id;
|
||||
Elem* e = ctx.find_elem(id);
|
||||
|
||||
ElemEvents ev = {
|
||||
e.events = {
|
||||
.has_focus = focus,
|
||||
.mouse_hover = hover,
|
||||
.mouse_press = hover && focus && ctx.is_mouse_pressed(BTN_ANY),
|
||||
|
|
@ -356,6 +387,4 @@ fn ElemEvents Ctx.get_elem_events(&ctx, Elem *elem)
|
|||
.key_repeat = focus && ctx.input.events.key_repeat,
|
||||
.text_input = focus && (ctx.input.keyboard.text_len || ctx.input.keyboard.modkeys & KMOD_TXT),
|
||||
};
|
||||
return ev;
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ const ModKeys KEY_ANY = (ModKeys)(ModKeys.inner.max);
|
|||
|
||||
fn bool Ctx.check_key_combo(&ctx, ModKeys mod, String ...keys)
|
||||
{
|
||||
bool is_mod = (bool)(ctx.input.keyboard.modkeys & mod);
|
||||
bool is_mod = (bool)(ctx.current_input.keyboard.modkeys & mod);
|
||||
bool is_keys = true;
|
||||
String haystack = (String)ctx.get_keys();
|
||||
foreach (needle: keys) {
|
||||
|
|
@ -86,7 +86,7 @@ fn void? Ctx.input_window_size(&ctx, short width, short height)
|
|||
if (width <= 0 || height <= 0) {
|
||||
return INVALID_SIZE?;
|
||||
}
|
||||
ctx.input.events.resize = ctx.width != width || ctx.height != height;
|
||||
ctx.current_input.events.resize = ctx.width != width || ctx.height != height;
|
||||
ctx.width = width;
|
||||
ctx.height = height;
|
||||
}
|
||||
|
|
@ -96,13 +96,13 @@ fn void Ctx.input_changefocus(&ctx, bool has_focus)
|
|||
{
|
||||
// FIXME: raylib only has an API to query the focus status so we have to
|
||||
// update the input flag only if the focus changed
|
||||
ctx.input.events.change_focus = ctx.has_focus != has_focus;
|
||||
ctx.current_input.events.change_focus = ctx.has_focus != has_focus;
|
||||
ctx.has_focus = has_focus;
|
||||
}
|
||||
|
||||
macro Ctx.mouse_pressed(&ctx) => ctx.input.mouse.updated & ctx.input.mouse.down;
|
||||
macro Ctx.mouse_released(&ctx) => ctx.input.mouse.updated & ~ctx.input.mouse.down;
|
||||
macro Ctx.mouse_down(&ctx) => ctx.input.mouse.down;
|
||||
macro Ctx.mouse_pressed(&ctx) => ctx.current_input.mouse.updated & ctx.current_input.mouse.down;
|
||||
macro Ctx.mouse_released(&ctx) => ctx.current_input.mouse.updated & ~ctx.current_input.mouse.down;
|
||||
macro Ctx.mouse_down(&ctx) => ctx.current_input.mouse.down;
|
||||
|
||||
// FIXME: hthis compairson could be done with a cast using MouseButtons.inner
|
||||
// property but I could not figure out how
|
||||
|
|
@ -113,63 +113,63 @@ macro Ctx.is_mouse_down(&ctx, MouseButtons btn) => (ctx.mouse_down() & btn) != B
|
|||
// Mouse Buttons down
|
||||
fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons)
|
||||
{
|
||||
ctx.input.mouse.updated = ctx.input.mouse.down ^ buttons;
|
||||
ctx.input.mouse.down = buttons;
|
||||
ctx.input.events.mouse_btn = (uint)ctx.input.mouse.down != 0 || (uint)ctx.input.mouse.updated != 0;
|
||||
ctx.current_input.mouse.updated = ctx.current_input.mouse.down ^ buttons;
|
||||
ctx.current_input.mouse.down = buttons;
|
||||
ctx.current_input.events.mouse_btn = (uint)ctx.current_input.mouse.down != 0 || (uint)ctx.current_input.mouse.updated != 0;
|
||||
}
|
||||
|
||||
// Mouse was moved, report absolute position
|
||||
fn void Ctx.input_mouse_abs(&ctx, short x, short y)
|
||||
{
|
||||
ctx.input.mouse.pos.x = math::clamp(x, (short)0, ctx.width);
|
||||
ctx.input.mouse.pos.y = math::clamp(y, (short)0, ctx.height);
|
||||
ctx.current_input.mouse.pos.x = math::clamp(x, (short)0, ctx.width);
|
||||
ctx.current_input.mouse.pos.y = math::clamp(y, (short)0, ctx.height);
|
||||
|
||||
short dx, dy;
|
||||
dx = x - ctx.input.mouse.pos.x;
|
||||
dy = y - ctx.input.mouse.pos.y;
|
||||
dx = x - ctx.current_input.mouse.pos.x;
|
||||
dy = y - ctx.current_input.mouse.pos.y;
|
||||
|
||||
ctx.input.mouse.delta.x = dx;
|
||||
ctx.input.mouse.delta.y = dy;
|
||||
ctx.current_input.mouse.delta.x = dx;
|
||||
ctx.current_input.mouse.delta.y = dy;
|
||||
|
||||
ctx.input.events.mouse_move = dx != 0 || dy != 0;
|
||||
ctx.current_input.events.mouse_move = dx != 0 || dy != 0;
|
||||
}
|
||||
|
||||
// Mouse was moved, report relative motion
|
||||
fn void Ctx.input_mouse_delta(&ctx, short dx, short dy)
|
||||
{
|
||||
ctx.input.mouse.delta.x = dx;
|
||||
ctx.input.mouse.delta.y = dy;
|
||||
ctx.current_input.mouse.delta.x = dx;
|
||||
ctx.current_input.mouse.delta.y = dy;
|
||||
|
||||
short mx, my;
|
||||
mx = ctx.input.mouse.pos.x + dx;
|
||||
my = ctx.input.mouse.pos.y + dy;
|
||||
mx = ctx.current_input.mouse.pos.x + dx;
|
||||
my = ctx.current_input.mouse.pos.y + dy;
|
||||
|
||||
ctx.input.mouse.pos.x = math::clamp(mx, (short)0, ctx.width);
|
||||
ctx.input.mouse.pos.y = math::clamp(my, (short)0, ctx.height);
|
||||
ctx.current_input.mouse.pos.x = math::clamp(mx, (short)0, ctx.width);
|
||||
ctx.current_input.mouse.pos.y = math::clamp(my, (short)0, ctx.height);
|
||||
|
||||
ctx.input.events.mouse_move = dx != 0 || dy != 0;
|
||||
ctx.current_input.events.mouse_move = dx != 0 || dy != 0;
|
||||
}
|
||||
|
||||
fn void Ctx.input_mouse_wheel(&ctx, short x, short y, float scale = 1.0)
|
||||
{
|
||||
ctx.input.mouse.scroll.x = (short)((float)-x*scale);
|
||||
ctx.input.mouse.scroll.y = (short)((float)-y*scale);
|
||||
ctx.input.events.mouse_scroll = x !=0 || y != 0;
|
||||
ctx.current_input.mouse.scroll.x = (short)((float)-x*scale);
|
||||
ctx.current_input.mouse.scroll.y = (short)((float)-y*scale);
|
||||
ctx.current_input.events.mouse_scroll = x !=0 || y != 0;
|
||||
}
|
||||
|
||||
fn void Ctx.input_key_press(&ctx)
|
||||
{
|
||||
ctx.input.events.key_press = true;
|
||||
ctx.current_input.events.key_press = true;
|
||||
}
|
||||
|
||||
fn void Ctx.input_key_release(&ctx)
|
||||
{
|
||||
ctx.input.events.key_release = true;
|
||||
ctx.current_input.events.key_release = true;
|
||||
}
|
||||
|
||||
fn void Ctx.input_key_repeat(&ctx)
|
||||
{
|
||||
ctx.input.events.key_repeat = true;
|
||||
ctx.current_input.events.key_repeat = true;
|
||||
}
|
||||
|
||||
// append utf-8 encoded text to the context text input
|
||||
|
|
@ -177,12 +177,12 @@ fn void Ctx.input_text_utf8(&ctx, char[] text)
|
|||
{
|
||||
if (text.len == 0) { return; }
|
||||
|
||||
usz remaining = ctx.input.keyboard.text.len - ctx.input.keyboard.text_len;
|
||||
usz remaining = ctx.current_input.keyboard.text.len - ctx.current_input.keyboard.text_len;
|
||||
usz len = text.len > remaining ? remaining : text.len;
|
||||
char[] s = ctx.input.keyboard.text[ctx.input.keyboard.text_len ..];
|
||||
char[] s = ctx.current_input.keyboard.text[ctx.current_input.keyboard.text_len ..];
|
||||
s[..len-1] = text[..len-1];
|
||||
ctx.input.keyboard.text_len += len;
|
||||
ctx.input.events.text_input = true;
|
||||
ctx.current_input.keyboard.text_len += len;
|
||||
ctx.current_input.events.text_input = true;
|
||||
}
|
||||
|
||||
fn void Ctx.input_text_unicode(&ctx, char[] text)
|
||||
|
|
@ -190,8 +190,8 @@ fn void Ctx.input_text_unicode(&ctx, char[] text)
|
|||
if (text.ptr == null || text.len == 0) { return; }
|
||||
|
||||
char[32] tmp;
|
||||
usz remaining = ctx.input.keyboard.text.len - ctx.input.keyboard.text_len;
|
||||
char[] s = ctx.input.keyboard.text[ctx.input.keyboard.text_len ..];
|
||||
usz remaining = ctx.current_input.keyboard.text.len - ctx.current_input.keyboard.text_len;
|
||||
char[] s = ctx.current_input.keyboard.text[ctx.current_input.keyboard.text_len ..];
|
||||
|
||||
usz off;
|
||||
foreach (idx, cp: text) {
|
||||
|
|
@ -200,9 +200,9 @@ fn void Ctx.input_text_unicode(&ctx, char[] text)
|
|||
s[off..off+enc] = tmp[..enc];
|
||||
off += enc;
|
||||
}
|
||||
ctx.input.keyboard.text_len += off;
|
||||
ctx.current_input.keyboard.text_len += off;
|
||||
|
||||
ctx.input.events.text_input = true;
|
||||
ctx.current_input.events.text_input = true;
|
||||
}
|
||||
|
||||
fn void Ctx.input_char(&ctx, char c)
|
||||
|
|
@ -218,6 +218,6 @@ fn ModKeys Ctx.get_mod(&ctx) => ctx.input.keyboard.modkeys;
|
|||
// TODO: make this call repetible to input modkeys one by one
|
||||
fn void Ctx.input_mod_keys(&ctx, ModKeys modkeys)
|
||||
{
|
||||
ctx.input.keyboard.modkeys = modkeys;
|
||||
ctx.input.events.mod_key = (uint)ctx.input.keyboard.modkeys != 0;
|
||||
ctx.current_input.keyboard.modkeys = modkeys;
|
||||
ctx.current_input.events.mod_key = (uint)ctx.current_input.keyboard.modkeys != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,72 +297,6 @@ fn void resolve_placement(Elem* c, Elem* p)
|
|||
}
|
||||
}
|
||||
|
||||
macro bool Ctx.is_hovered(&ctx, Elem *elem) => ctx.input.mouse.pos.in_rect(elem.bounds);
|
||||
|
||||
fn void Ctx.update_elem_events(&ctx, Elem* elem)
|
||||
{
|
||||
bool hover = ctx.is_hovered(elem);
|
||||
bool focus = ctx.focus_id == elem.id || (hover && ctx.is_mouse_pressed(BTN_ANY));
|
||||
|
||||
if (ctx.is_mouse_pressed(BTN_ANY) && !hover){
|
||||
focus = false;
|
||||
if (ctx.focus_id == elem.id) ctx.focus_id = 0;
|
||||
}
|
||||
|
||||
if (hover) {
|
||||
// TODO: this constant cache lookup could be slow
|
||||
Elem* prev_hover = ctx.find_elem(ctx.hover_id);
|
||||
if (prev_hover.id != elem.id && prev_hover.flags.shown) {
|
||||
if (prev_hover.z_index <= elem.z_index) {
|
||||
// remove hover events from prev_hover
|
||||
prev_hover.events.mouse_hover = false;
|
||||
prev_hover.events.mouse_press = false;
|
||||
prev_hover.events.mouse_release = false;
|
||||
prev_hover.events.mouse_hold = false;
|
||||
} else {
|
||||
hover = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (focus) {
|
||||
// TODO: this constant cache lookup could be slow
|
||||
Elem* prev_focus = ctx.find_elem(ctx.hover_id);
|
||||
// update the focus id and element only if the current element is at the same level
|
||||
// or above the previous element that held focus
|
||||
if (prev_focus.z_index <= elem.z_index) {
|
||||
// remove focus events from prev_focus
|
||||
prev_focus.events.has_focus = false;
|
||||
prev_focus.events.mouse_press = false;
|
||||
prev_focus.events.mouse_release = false;
|
||||
prev_focus.events.mouse_hold = false;
|
||||
prev_focus.events.key_press = false;
|
||||
prev_focus.events.key_release = false;
|
||||
prev_focus.events.key_repeat = false;
|
||||
prev_focus.events.text_input = false;
|
||||
// update the hover id
|
||||
ctx.focus_id = elem.id;
|
||||
} else if (prev_focus.flags.shown) {
|
||||
focus = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hover) ctx.hover_id = elem.id;
|
||||
|
||||
ElemEvents ev = {
|
||||
.has_focus = focus,
|
||||
.mouse_hover = hover,
|
||||
.mouse_press = hover && focus && ctx.is_mouse_pressed(BTN_ANY),
|
||||
.mouse_release = hover && focus && ctx.is_mouse_released(BTN_ANY),
|
||||
.mouse_hold = hover && focus && ctx.is_mouse_down(BTN_ANY),
|
||||
.key_press = focus && ctx.input.events.key_press,
|
||||
.key_release = focus && ctx.input.events.key_release,
|
||||
.key_repeat = focus && ctx.input.events.key_repeat,
|
||||
.text_input = focus && (ctx.input.keyboard.text_len || ctx.input.keyboard.modkeys & KMOD_TXT),
|
||||
};
|
||||
elem.events = ev;
|
||||
}
|
||||
|
||||
fn void? Ctx.layout_element_tree(&ctx)
|
||||
{
|
||||
int current;
|
||||
|
|
@ -400,11 +334,11 @@ fn void? Ctx.layout_element_tree(&ctx)
|
|||
} else {
|
||||
resolve_placement(c, p);
|
||||
update_children_bounds(c, p);
|
||||
|
||||
// reset shown flag
|
||||
}
|
||||
ctx.update_elem_events(c);
|
||||
c.flags.shown = false;
|
||||
|
||||
// FIXME: this stuff would be better elsewhere but we are already iteraring through all
|
||||
// elements so here it fits really well
|
||||
ctx.update_hover_and_focus(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,6 +199,8 @@ macro bool 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);
|
||||
}
|
||||
|
||||
macro bool Point.outside(Point p, Rect r) => !p.in_rect(r);
|
||||
|
||||
macro Point Point.add(Point a, Point b) @operator_s(+) => {.x = a.x+b.x, .y = a.y+b.y};
|
||||
macro Point Point.sub(Point a, Point b) @operator_s(-) => {.x = a.x-b.x, .y = a.y-b.y};
|
||||
macro Point Point.neg(Point p) @operator_s(-) => {-p.x, -p.y};
|
||||
|
|
@ -241,20 +243,22 @@ macro uint Color.to_uint(c) => c.r | (c.g << 8) | (c.b << 16) | (c.a << 24);
|
|||
// SIZE //
|
||||
// ---------------------------------------------------------------------------------- //
|
||||
|
||||
macro short short.add_no_of(short a, short b) => (short)max(min((int)a + (int)b, short.max), short.min) @inline;
|
||||
|
||||
struct Size {
|
||||
short min, max;
|
||||
}
|
||||
|
||||
macro Size @grow() => {.min = 0, .max = 0};
|
||||
macro Size @exact(short s) => {.min = s, .max = s};
|
||||
// PROBLEM WE ARE OVERFLOWING
|
||||
macro Size @fit(short min = 0, short max = 999) => {.min = min, .max = max};
|
||||
macro Size @fit(short min = 0, short max = short.max) => {.min = min, .max = max};
|
||||
|
||||
macro bool Size.@is_grow(s) => (s.min == 0 && s.max == 0);
|
||||
macro bool Size.@is_exact(s) => (s.min == s.max && s.min != 0);
|
||||
macro bool Size.@is_fit(s) => (s.min != s.max);
|
||||
|
||||
macro Size Size.add(a, Size b) @operator_s(+) => {.min = a.min+b.min, .max = a.max+b.max};
|
||||
macro Size Size.sub(a, Size b) @operator_s(-) => {.min = a.min-b.min, .max = a.max-b.max};
|
||||
macro Size Size.add(a, Size b) @operator_s(+) => {.min = a.min.add_no_of(b.min), .max = a.max.add_no_of(b.max)};
|
||||
macro Size Size.sub(a, Size b) @operator_s(-) => {.min = a.min.add_no_of(-b.min), .max = a.max.add_no_of(-b.max)};
|
||||
|
||||
macro Size Size.combine(a, Size b) => {.min = max(a.min, b.min), .max = min(a.max, b.max)};
|
||||
macro Size Size.comb_max(a, Size b) => {.min = max(a.min, b.min), .max = max(a.max, b.max)};
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ fn void? Ctx.div_begin_id(&ctx,
|
|||
|
||||
elem.div.scroll_x.enabled = scroll_x;
|
||||
elem.div.scroll_y.enabled = scroll_y;
|
||||
if (ctx.input.z_index < elem.z_index) ctx.input.z_index = elem.z_index;
|
||||
|
||||
// update layout with correct info
|
||||
elem.layout = {
|
||||
|
|
@ -199,7 +198,6 @@ fn bool? Ctx.popup_begin_id(&ctx,
|
|||
elem.div.scroll_x.enabled = scroll_x;
|
||||
elem.div.scroll_y.enabled = scroll_y;
|
||||
elem.z_index++;
|
||||
if (ctx.input.z_index < elem.z_index) ctx.input.z_index = elem.z_index;
|
||||
|
||||
// update layout with correct info
|
||||
elem.layout = {
|
||||
|
|
@ -222,7 +220,7 @@ fn bool? Ctx.popup_begin_id(&ctx,
|
|||
//elem.events = ctx.get_elem_events(elem);
|
||||
|
||||
// check close condition, mouse release anywhere outside the div bounds
|
||||
if ((ctx.mouse_released() & BTN_ANY) && !elem.events.mouse_hover) {
|
||||
if ((ctx.mouse_released() & BTN_ANY) && ctx.input.mouse.pos.outside(elem.bounds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue