@@ -1438,19 +1438,7 @@ bool iui_radio(iui_context *ctx,
14381438 * TextField-style component that reveals a menu of options
14391439 */
14401440
1441- /* Static state for dropdown menu (one active at a time) */
1442- /* Dropdown menu state - single instance per UI context.
1443- * Thread-safety: This static state assumes single-threaded UI rendering.
1444- * Each thread/context should have its own UI instance. If multi-context
1445- * support is needed, move this state into iui_context.
1446- */
1447- static struct {
1448- bool open ; /* menu is visible */
1449- float x , y , width ; /* menu position and width */
1450- int hovered_index ; /* currently hovered option */
1451- int frames_since_open ; /* frame counter for click protection */
1452- const int * selected ; /* pointer to track which dropdown is active */
1453- } s_dropdown = {0 };
1441+
14541442
14551443bool iui_dropdown (iui_context * ctx , const iui_dropdown_options * options )
14561444{
@@ -1481,8 +1469,8 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options)
14811469 };
14821470
14831471 /* Check if this dropdown's menu is open */
1484- bool is_open =
1485- s_dropdown . open && ( s_dropdown .selected == options -> selected_index );
1472+ bool is_open = ctx -> dropdown . open &&
1473+ ( ctx -> dropdown .selected == options -> selected_index );
14861474
14871475 /* Get field interaction state */
14881476 iui_state_t state =
@@ -1560,36 +1548,36 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options)
15601548 if (!options -> disabled && state == IUI_STATE_PRESSED ) {
15611549 if (is_open ) {
15621550 /* Close menu */
1563- s_dropdown .open = false;
1551+ ctx -> dropdown .open = false;
15641552 } else {
15651553 /* Open menu */
1566- s_dropdown .open = true;
1567- s_dropdown .x = field_rect .x ;
1568- s_dropdown .y = field_rect .y + field_h ;
1569- s_dropdown .width = field_rect .width ;
1570- s_dropdown .hovered_index = selected ;
1571- s_dropdown .frames_since_open = 0 ;
1572- s_dropdown .selected = options -> selected_index ;
1554+ ctx -> dropdown .open = true;
1555+ ctx -> dropdown .x = field_rect .x ;
1556+ ctx -> dropdown .y = field_rect .y + field_h ;
1557+ ctx -> dropdown .width = field_rect .width ;
1558+ ctx -> dropdown .hovered_index = selected ;
1559+ ctx -> dropdown .frames_since_open = 0 ;
1560+ ctx -> dropdown .selected = options -> selected_index ;
15731561 }
15741562 }
15751563
15761564 /* Draw menu if open */
15771565 if (is_open ) {
15781566 /* Capture frame count BEFORE incrementing for click protection.
1579- * This ensures the first frame after opening (frames_active == 0)
1567+ * This ensures that first frame after opening (frames_active == 0)
15801568 * blocks clicks, preventing click-through from the field that opened
1581- * this menu.
1569+ * menu.
15821570 */
1583- int frames_active = s_dropdown .frames_since_open ++ ;
1571+ int frames_active = ctx -> dropdown .frames_since_open ++ ;
15841572
15851573 /* Calculate menu height (capped at max) */
15861574 float item_h = IUI_DROPDOWN_ITEM_HEIGHT ;
15871575 float menu_h = options -> option_count * item_h ;
15881576 if (menu_h > IUI_DROPDOWN_MENU_MAX_HEIGHT )
15891577 menu_h = IUI_DROPDOWN_MENU_MAX_HEIGHT ;
15901578
1591- iui_rect_t menu_rect = {s_dropdown .x , s_dropdown . y , s_dropdown . width ,
1592- menu_h };
1579+ iui_rect_t menu_rect = {ctx -> dropdown .x , ctx -> dropdown . y ,
1580+ ctx -> dropdown . width , menu_h };
15931581
15941582 /* Begin modal for menu */
15951583 iui_begin_modal (ctx , "dropdown_menu_modal" );
@@ -1612,7 +1600,7 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options)
16121600 /* Update hovered index */
16131601 if (item_state == IUI_STATE_HOVERED ||
16141602 item_state == IUI_STATE_PRESSED ) {
1615- s_dropdown .hovered_index = i ;
1603+ ctx -> dropdown .hovered_index = i ;
16161604 }
16171605
16181606 /* Draw selection/hover background */
@@ -1640,7 +1628,7 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options)
16401628 if (frames_active >= 1 && item_state == IUI_STATE_PRESSED ) {
16411629 * options -> selected_index = i ;
16421630 selection_changed = (i != selected );
1643- s_dropdown .open = false;
1631+ ctx -> dropdown .open = false;
16441632 iui_close_modal (ctx );
16451633 }
16461634 }
@@ -1652,7 +1640,7 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options)
16521640 bool mouse_pressed = (ctx -> mouse_pressed & IUI_MOUSE_LEFT );
16531641
16541642 if (!mouse_in_menu && !mouse_in_field && mouse_pressed ) {
1655- s_dropdown .open = false;
1643+ ctx -> dropdown .open = false;
16561644 iui_close_modal (ctx );
16571645 }
16581646 }
0 commit comments