diff --git a/oui.h b/oui.h index ec0a12a..36019db 100644 --- a/oui.h +++ b/oui.h @@ -287,6 +287,9 @@ typedef enum UIevent { // usually menuitems for a context menu. // the respective container can be queried using uiGetExtendItem() UI_EXTEND = 0x1000, + // item has received a scrollwheel event + // the accumulated wheel offset can be queried with uiGetScroll() + UI_SCROLL = 0x2000, } UIevent; // handler callback; event is one of UI_EVENT_* @@ -369,6 +372,13 @@ OUI_EXPORT void uiSetKey(unsigned int key, unsigned int mod, int enabled); // all char events are being buffered until the next call to uiProcess() OUI_EXPORT void uiSetChar(unsigned int value); +// accumulates scroll wheel offsets for the current frame +// all offsets are being accumulated until the next call to uiProcess() +OUI_EXPORT void uiSetScroll(int x, int y); + +// returns the currently accumulated scroll wheel offsets for this frame +OUI_EXPORT UIvec2 uiGetScroll(); + // Stages // ------ @@ -712,6 +722,8 @@ struct UIcontext { UIvec2 last_cursor; // where the cursor is currently UIvec2 cursor; + // accumulated scroll wheel offsets + UIvec2 scroll; UIhandle hot_handle; UIhandle active_handle; @@ -856,6 +868,8 @@ static void uiAddInputEvent(UIinputEvent event) { static void uiClearInputEvents() { assert(ui_context); ui_context->eventcount = 0; + ui_context->scroll.x = 0; + ui_context->scroll.y = 0; } void uiSetKey(unsigned int key, unsigned int mod, int enabled) { @@ -870,6 +884,17 @@ void uiSetChar(unsigned int value) { uiAddInputEvent(event); } +void uiSetScroll(int x, int y) { + assert(ui_context); + ui_context->scroll.x += x; + ui_context->scroll.y += y; +} + +UIvec2 uiGetScroll() { + assert(ui_context); + return ui_context->scroll; +} + int uiGetLastButton(int button) { assert(ui_context); return (ui_context->last_buttons & (1ull<frozen) return -1; UIrect rect = pitem->rect; @@ -1396,21 +1423,28 @@ int uiFindItem(int item, int x, int y, int ox, int oy) { && (y= 0) { - int best_hit = uiFindItem(kid,x,y,ox,oy); + int best_hit = uiFindItemForEvent(kid, + event,hot_rect,x,y,ox,oy); if (best_hit >= 0) return best_hit; kid = uiPrevSibling(kid); } - // click-through if the item has no handler for input events - if (pitem->event_flags & UI_ANY_INPUT) { + // click-through if the item has no handler for this event + if (pitem->event_flags & event) { rect.x = ox; rect.y = oy; - ui_context->hot_rect = rect; + if (hot_rect) + *hot_rect = rect; return item; } } return -1; } +int uiFindItem(int item, int x, int y, int ox, int oy) { + return uiFindItemForEvent(item, (UIevent)UI_ANY_INPUT, + &ui_context->hot_rect, x, y, ox, oy); +} + void uiLayout() { assert(ui_context); if (!ui_context->count) return; @@ -1434,9 +1468,8 @@ void uiLayout() { void uiUpdateHotItem() { assert(ui_context); if (!ui_context->count) return; - int hot = uiFindItem(0, + ui_context->hot_item = uiFindItem(0, ui_context->cursor.x, ui_context->cursor.y, 0, 0); - ui_context->hot_item = hot; } void uiProcess() { @@ -1461,6 +1494,14 @@ void uiProcess() { } else { ui_context->focus_handle = 0; } + if (ui_context->scroll.x || ui_context->scroll.y) { + int scroll_item = uiFindItemForEvent(0, UI_SCROLL, NULL, + ui_context->cursor.x, ui_context->cursor.y, 0, 0); + if (scroll_item >= 0) { + uiNotifyItem(scroll_item, UI_SCROLL); + } + } + uiClearInputEvents(); int hot = ui_context->hot_item;