diff --git a/ports/headless.c b/ports/headless.c index 9cf02c0..519cf5a 100644 --- a/ports/headless.c +++ b/ports/headless.c @@ -929,7 +929,6 @@ bool iui_headless_save_screenshot(iui_port_ctx *ctx, const char *path) /* Adler-32 checksum */ uint32_t adler = adler32(raw_data, raw_size); write_be32(zlib_data + zlib_pos, adler); - zlib_pos += 4; free(raw_data); diff --git a/src/container.c b/src/container.c index 58c38f6..2afd368 100644 --- a/src/container.c +++ b/src/container.c @@ -688,10 +688,10 @@ void iui_tooltip(iui_context *ctx, const char *text) x = win.x + win.width - width; /* Smart vertical positioning: check available space above and below */ - float space_below = - (win.y + win.height) - (ctx->layout.y + ctx->row_height); - float space_above = ctx->layout.y - win.y; if (y + height > win.y + win.height) { + float space_below = + (win.y + win.height) - (ctx->layout.y + ctx->row_height); + float space_above = ctx->layout.y - win.y; /* Would overflow bottom - try flipping above if more space there */ if (space_above > space_below && space_above >= height) y = ctx->layout.y - height - IUI_TOOLTIP_OFFSET; @@ -759,10 +759,10 @@ bool iui_tooltip_rich(iui_context *ctx, x = win.x + win.width - width; /* Smart vertical positioning: check available space above and below */ - float space_below = - (win.y + win.height) - (ctx->layout.y + ctx->row_height); - float space_above = ctx->layout.y - win.y; if (y + height > win.y + win.height) { + float space_below = + (win.y + win.height) - (ctx->layout.y + ctx->row_height); + float space_above = ctx->layout.y - win.y; /* Would overflow bottom - try flipping above if more space there */ if (space_above > space_below && space_above >= height) y = ctx->layout.y - height - IUI_TOOLTIP_OFFSET; diff --git a/src/core.c b/src/core.c index 91b9092..c23c1b9 100644 --- a/src/core.c +++ b/src/core.c @@ -874,7 +874,7 @@ bool iui_has_focus(const iui_context *ctx, const char *id) } /* Internal: Check if widget with given ID is focused */ -bool iui_widget_is_focused(iui_context *ctx, uint32_t id) +bool iui_widget_is_focused(const iui_context *ctx, uint32_t id) { return ctx->focused_widget_id == id && id != 0; } @@ -1340,6 +1340,7 @@ const char *iui_a11y_state_description(uint32_t state) APPEND_STATE(IUI_A11Y_STATE_HASPOPUP, "has popup") #undef APPEND_STATE + (void) count; /* suppress unused-after-final-increment warning */ return buf; } diff --git a/src/dialog.c b/src/dialog.c index 6e070fa..52c4ba9 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -228,14 +228,13 @@ int iui_dialog(iui_context *ctx, iui_state_t state = iui_get_component_state(ctx, btn_rect, false); /* Draw button based on position (rightmost:filled, others:text) */ - uint32_t bg_color = 0; uint32_t text_color = ctx->colors.primary; /* MD3 button corner radius (full rounded) */ float btn_corner = IUI_SHAPE_FULL; if (i == btn_count - 1) { /* Primary button (rightmost) - filled style */ - bg_color = ctx->colors.primary; + uint32_t bg_color = ctx->colors.primary; text_color = ctx->colors.on_primary; ctx->renderer.draw_box(btn_rect, btn_corner, bg_color, ctx->renderer.user); @@ -376,9 +375,9 @@ bool iui_fullscreen_dialog_begin(iui_context *ctx, } /* Draw title after close icon */ - float title_x = padding + touch_target + padding * 0.5f; - float title_y = (header_h - ctx->font_height) * 0.5f; if (dialog->title) { + float title_x = padding + touch_target + padding * 0.5f; + float title_y = (header_h - ctx->font_height) * 0.5f; iui_internal_draw_text(ctx, title_x, title_y, dialog->title, ctx->colors.on_surface); } diff --git a/src/draw.c b/src/draw.c index bea40bf..de74cb5 100644 --- a/src/draw.c +++ b/src/draw.c @@ -287,10 +287,11 @@ static void iui_divider_internal(iui_context *ctx, float left_inset) ctx->layout.y += 8.f; /* MD3: 1dp height, outline_variant color */ - float x = ctx->layout.x + left_inset, w = ctx->layout.width - left_inset; + float w = ctx->layout.width - left_inset; /* Guard against negative width in narrow containers */ if (w > 0.f) { + float x = ctx->layout.x + left_inset; ctx->renderer.draw_box((iui_rect_t) {x, ctx->layout.y, w, 1.f}, 0.f, ctx->colors.outline_variant, ctx->renderer.user); } @@ -537,10 +538,9 @@ iui_state_t iui_get_component_state(iui_context *ctx, if (ctx->mouse_pressed & IUI_MOUSE_LEFT) return IUI_STATE_PRESSED; - } - if (hovered) return IUI_STATE_HOVERED; + } return IUI_STATE_DEFAULT; } diff --git a/src/fab.c b/src/fab.c index e4cfd36..4facb30 100644 --- a/src/fab.c +++ b/src/fab.c @@ -58,12 +58,11 @@ static bool iui_fab_internal(iui_context *ctx, iui_draw_state_layer(ctx, fab_rect, corner_radius, content_color, state); /* Calculate content position */ - float content_x = x; float center_y = y + fab_h * 0.5f; if (label) { /* Extended FAB: icon (optional) + label */ - content_x = x + IUI_FAB_EXTENDED_PADDING; + float content_x = x + IUI_FAB_EXTENDED_PADDING; if (icon) { float icon_cx = content_x + icon_size * 0.5f; diff --git a/src/icons.c b/src/icons.c index 5cad08b..a0b9fbd 100644 --- a/src/icons.c +++ b/src/icons.c @@ -331,11 +331,8 @@ void iui_draw_fab_icon(iui_context *ctx, cx + half * 0.3f, cy, stroke, color); iui_draw_line_soft(ctx, cx + half * 0.3f, cy, cx - half * 0.2f, cy + half * 0.4f, stroke, color); - } else if (!strcmp(icon_name, "dot")) { - /* Filled dot */ - iui_draw_circle_soft(ctx, cx, cy, size * 0.15f, color, 0, 0); } else { - /* Default: draw a simple dot/circle for unknown icons */ + /* Default / "dot": draw a simple filled circle */ iui_draw_circle_soft(ctx, cx, cy, size * 0.15f, color, 0, 0); } } diff --git a/src/input.c b/src/input.c index 30f7a37..c055ccd 100644 --- a/src/input.c +++ b/src/input.c @@ -751,17 +751,16 @@ bool iui_edit_with_selection(iui_context *ctx, state->is_dragging = false; } - /* Handle keyboard input when focused */ + /* Handle keyboard input when focused and auto-scroll to keep cursor visible + */ if (has_focus) { modified = iui_process_text_input_selection(ctx, buffer, buffer_size, state); /* Reset cursor blink on any key activity */ if (ctx->key_pressed != IUI_KEY_NONE || ctx->char_input != 0) ctx->cursor_blink = 0.f; - } - /* Auto-scroll to keep cursor visible */ - if (has_focus) { + /* Auto-scroll to keep cursor visible */ float cursor_x_in_text = textfield_get_width_to_pos(ctx, buffer, state->cursor, false); if (cursor_x_in_text < state->scroll_offset) @@ -990,7 +989,8 @@ iui_textfield_result iui_textfield_with_selection( has_focus = false; state->is_dragging = false; } - } else if (opts.disabled && has_focus) { + } else if (has_focus) { + /* Widget is disabled but still has focus - clear it */ ctx->focused_edit = NULL; has_focus = false; } @@ -1217,15 +1217,11 @@ bool iui_switch(iui_context *ctx, } } - /* Apply focus state layer */ + /* Apply focus state layer and draw focus ring when focused */ if (is_focused) { uint32_t focus_layer = iui_state_layer(ctx->colors.primary, IUI_STATE_FOCUS_ALPHA); track_color = iui_blend_color(track_color, focus_layer); - } - - /* Draw focus ring when focused */ - if (is_focused) { iui_draw_focus_ring(ctx, track_rect, corner); } @@ -1525,16 +1521,14 @@ bool iui_dropdown(iui_context *ctx, const iui_dropdown_options *options) } /* Draw floating label */ - float label_y; - uint32_t label_color = - options->disabled - ? iui_state_layer(ctx->colors.on_surface_variant, - IUI_STATE_DISABLE_ALPHA) - : (is_open ? ctx->colors.primary : ctx->colors.on_surface_variant); - if (options->label) { + uint32_t label_color = + options->disabled ? iui_state_layer(ctx->colors.on_surface_variant, + IUI_STATE_DISABLE_ALPHA) + : (is_open ? ctx->colors.primary + : ctx->colors.on_surface_variant); /* Label floats above when there's a selection */ - label_y = field_rect.y + 8.f; + float label_y = field_rect.y + 8.f; iui_internal_draw_text(ctx, field_rect.x + padding, label_y, options->label, label_color); } diff --git a/src/internal.h b/src/internal.h index e87a2d2..bf85c1a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -988,7 +988,7 @@ void iui_draw_fab_icon(iui_context *ctx, float cx, float cy, float size, - const char *icon, + const char *icon_name, uint32_t color); /* Vector font rendering (implemented in core.c) */ @@ -1079,7 +1079,7 @@ bool iui_register_focusable(iui_context *ctx, iui_rect_t bounds, float corner); void iui_process_focus_navigation(iui_context *ctx); -bool iui_widget_is_focused(iui_context *ctx, uint32_t id); +bool iui_widget_is_focused(const iui_context *ctx, uint32_t id); /* Layout internal functions (iui_layout.c) */ diff --git a/src/layout.c b/src/layout.c index 993e5af..4e88062 100644 --- a/src/layout.c +++ b/src/layout.c @@ -95,10 +95,8 @@ void iui_row(iui_context *ctx, int items, const float *widths, float height) return; /* End previous row if any */ - if (ctx->in_row) { + if (ctx->in_row) ctx->layout.y = ctx->row.next_row_y; - ctx->in_row = false; - } ctx->in_row = true; ctx->row.item_count = items; diff --git a/src/searchbar.c b/src/searchbar.c index 7540763..a4d9869 100644 --- a/src/searchbar.c +++ b/src/searchbar.c @@ -444,10 +444,10 @@ bool iui_search_view_suggestion(iui_context *ctx, /* Draw icon if provided */ float content_x = padding; - float icon_cy = item_y + item_h * 0.5f; if (icon) { float icon_cx = padding + icon_size * 0.5f; + float icon_cy = item_y + item_h * 0.5f; iui_draw_fab_icon(ctx, icon_cx, icon_cy, icon_size, icon, ctx->colors.on_surface_variant); content_x += icon_size + padding; diff --git a/src/tabs.c b/src/tabs.c index da8da6b..f5ee10b 100644 --- a/src/tabs.c +++ b/src/tabs.c @@ -98,7 +98,6 @@ static int iui_tabs_internal(iui_context *ctx, is_selected ? ctx->colors.primary : ctx->colors.on_surface_variant; /* Calculate content position (centered) */ - float content_y = tabs_y + tab_height * 0.5f; float text_width = iui_get_text_width(ctx, labels[i]); if (icons && icons[i]) { @@ -122,6 +121,7 @@ static int iui_tabs_internal(iui_context *ctx, content_color); } else { /* Label only (centered vertically) */ + float content_y = tabs_y + tab_height * 0.5f; float label_x = tab_x + (tab_width - text_width) * 0.5f, label_y = content_y - ctx->font_height * 0.5f; iui_internal_draw_text(ctx, label_x, label_y, labels[i], diff --git a/tests/test-overflow.c b/tests/test-overflow.c index 9c26b23..d3fbc02 100644 --- a/tests/test-overflow.c +++ b/tests/test-overflow.c @@ -129,9 +129,9 @@ static void test_large_coord_clip(void) bool success = iui_push_clip(ctx, large_clip); ASSERT_TRUE(success); - /* Verify coordinates were clamped to uint16 range */ - ASSERT_TRUE(g_last_clip_max_x <= UINT16_MAX); - ASSERT_TRUE(g_last_clip_max_y <= UINT16_MAX); + /* Verify coordinates were clamped to uint16 max (150000 -> 65535) */ + ASSERT_EQ(g_last_clip_max_x, UINT16_MAX); + ASSERT_EQ(g_last_clip_max_y, UINT16_MAX); iui_pop_clip(ctx); @@ -249,10 +249,10 @@ static void test_slider_tracking_overflow(void) float values[IUI_MAX_TRACKED_SLIDERS + 10]; for (int i = 0; i < IUI_MAX_TRACKED_SLIDERS + 10; i++) { - values[i] = 50.f; - values[i] = iui_slider_ex(ctx, values[i], 0.f, 100.f, 1.f, NULL); + values[i] = iui_slider_ex(ctx, 50.f, 0.f, 100.f, 1.f, NULL); iui_newline(ctx); } + (void) values; /* suppress unused warning - test only checks for crashes */ /* Should not crash - overflow handled gracefully */