mirror of
https://github.com/nicbarker/clay.git
synced 2026-02-06 12:48:49 +00:00
feat(ncurses): Add interaction callbacks and improve input handling
Introduces Input Processing and Interaction helpers for the Ncurses renderer, ensuring robust mouse support and simplified event handling. **Renderer (`renderers/ncurses`):** - **`Clay_Ncurses_ProcessInput`**: Added a dedicated input processing function that handles both keyboard and mouse events. - Implemented persistent `_isMouseDown` state tracking to fix missed "fast clicks" and preserve button state during drag operations. - Adjusted `mousemask` to `BUTTON1_PRESSED | BUTTON1_RELEASED | REPORT_MOUSE_POSITION` to bypass Ncurses' internal click resolution delay. - **`Clay_Ncurses_OnClick`**: Added a helper function to easily attach click listeners. - Registers the user's callback directly via `Clay_OnHover` (avoiding allocation/proxies). - Matches the standard Clay callback signature pattern. **Example (`examples/ncurses-example`):** - **Input Loop**: Migrated main loop to use `Clay_Ncurses_ProcessInput`. - **Interactions**: - Added a "Toggle Help" button to the sidebar. - Implemented `HandleHelpToggleClick` callback, which explicitly checks for `CLAY_POINTER_DATA_RELEASED_THIS_FRAME` to validate clicks. - Added visual hover effects to sidebar items. **Documentation (`renderers/ncurses/README.md`):** - Updated "Usage" section to demonstrate `Clay_Ncurses_ProcessInput`. - Added "Input & Interaction" section documenting the new helpers.
This commit is contained in:
parent
bc742a190a
commit
c700104760
3 changed files with 203 additions and 17 deletions
|
|
@ -425,7 +425,10 @@ void Clay_Ncurses_Initialize() {
|
|||
keypad(stdscr, TRUE);
|
||||
curs_set(0);
|
||||
|
||||
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
|
||||
// We only ask for PRESS and RELEASE events.
|
||||
// If we ask for CLICK events, ncurses waits to see if a release happens quickly,
|
||||
// which delays the report of the PRESS event or swallows it, causing Clay to miss the "Down" state.
|
||||
mousemask(BUTTON1_PRESSED | BUTTON1_RELEASED | REPORT_MOUSE_POSITION, NULL);
|
||||
|
||||
start_color();
|
||||
use_default_colors();
|
||||
|
|
@ -613,3 +616,58 @@ static int Clay_Ncurses_MeasureStringWidth(Clay_StringSlice text) {
|
|||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles Ncurses input and updates Clay's internal pointer state.
|
||||
* Use this instead of standard getch() in your main loop to enable mouse interaction.
|
||||
*
|
||||
* @param window The Ncurses window to read input from (e.g. stdscr).
|
||||
* @return The key code pressed, or ERR if no input.
|
||||
*/
|
||||
static bool _pointerReleasedThisFrame = false;
|
||||
|
||||
int Clay_Ncurses_ProcessInput(WINDOW *window) {
|
||||
int key = wgetch(window);
|
||||
_pointerReleasedThisFrame = false;
|
||||
|
||||
// Handle Mouse
|
||||
if (key == KEY_MOUSE) {
|
||||
MEVENT event;
|
||||
if (getmouse(&event) == OK) {
|
||||
// Convert Cell Coordinates -> Clay Logical Coordinates
|
||||
Clay_Vector2 mousePos = {
|
||||
(float)event.x * CLAY_NCURSES_CELL_WIDTH,
|
||||
(float)event.y * CLAY_NCURSES_CELL_HEIGHT
|
||||
};
|
||||
|
||||
// Persistent state to handle drag/move events where button state might be absent in the event mask
|
||||
static bool _isMouseDown = false;
|
||||
|
||||
if (event.bstate & (BUTTON1_PRESSED | BUTTON1_DOUBLE_CLICKED | BUTTON1_TRIPLE_CLICKED)) {
|
||||
_isMouseDown = true;
|
||||
}
|
||||
|
||||
if (event.bstate & BUTTON1_RELEASED) {
|
||||
_isMouseDown = false;
|
||||
}
|
||||
|
||||
// Update Clay State
|
||||
Clay_SetPointerState(mousePos, _isMouseDown);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper to attach an OnClick listener to the current element.
|
||||
* Registers a hover callback. The user's function must check `pointerData.state == CLAY_POINTER_DATA_RELEASED_THIS_FRAME`.
|
||||
*
|
||||
* @param onClickFunc Function pointer to call.
|
||||
* @param userData User data passed to the callback.
|
||||
*/
|
||||
void Clay_Ncurses_OnClick(void (*onClickFunc)(Clay_ElementId elementId, Clay_PointerData pointerData, void *userData), void *userData) {
|
||||
if (onClickFunc) {
|
||||
Clay_OnHover(onClickFunc, userData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue