refactor(icon): Modularizar en carpeta (805→515 LOC hub, -36%)

This commit is contained in:
reugenio 2025-12-29 11:41:24 +01:00
parent 50a6d3ca60
commit 1ae07812bd
7 changed files with 758 additions and 809 deletions

View file

@ -9,7 +9,7 @@ const Command = @import("../core/command.zig");
const Layout = @import("../core/layout.zig"); const Layout = @import("../core/layout.zig");
const Style = @import("../core/style.zig"); const Style = @import("../core/style.zig");
const Input = @import("../core/input.zig"); const Input = @import("../core/input.zig");
const icon_module = @import("icon.zig"); const icon_module = @import("icon/icon.zig");
const iconbutton = @import("iconbutton.zig"); const iconbutton = @import("iconbutton.zig");
/// AppBar position /// AppBar position

View file

@ -0,0 +1,93 @@
//! Icon - Helpers de dibujo
//!
//! Funciones para dibujar líneas y círculos con grosor.
const Context = @import("../../core/context.zig").Context;
const Command = @import("../../core/command.zig");
const Style = @import("../../core/style.zig");
// =============================================================================
// Drawing Helpers
// =============================================================================
/// Draw a line with thickness
pub fn drawLine(ctx: *Context, x1: i32, y1: i32, x2: i32, y2: i32, thickness: u32, color: Style.Color) void {
if (thickness <= 1) {
ctx.pushCommand(Command.line(x1, y1, x2, y2, color));
} else {
const dx = x2 - x1;
const dy = y2 - y1;
const len = @sqrt(@as(f32, @floatFromInt(dx * dx + dy * dy)));
if (len < 1) {
ctx.pushCommand(Command.rect(x1, y1, thickness, thickness, color));
return;
}
const nx = -@as(f32, @floatFromInt(dy)) / len;
const ny = @as(f32, @floatFromInt(dx)) / len;
const half = @as(f32, @floatFromInt(thickness)) / 2.0;
var offset: f32 = -half;
while (offset < half) : (offset += 1.0) {
const ox = @as(i32, @intFromFloat(nx * offset));
const oy = @as(i32, @intFromFloat(ny * offset));
ctx.pushCommand(Command.line(x1 + ox, y1 + oy, x2 + ox, y2 + oy, color));
}
}
}
/// Fill a circle
pub fn fillCircle(ctx: *Context, cx: i32, cy: i32, radius: u32, color: Style.Color) void {
if (radius == 0) {
ctx.pushCommand(Command.rect(cx, cy, 1, 1, color));
return;
}
const r = @as(i32, @intCast(radius));
var dy: i32 = -r;
while (dy <= r) : (dy += 1) {
const dy_f = @as(f32, @floatFromInt(dy));
const r_f = @as(f32, @floatFromInt(r));
const dx = @as(i32, @intFromFloat(@sqrt(r_f * r_f - dy_f * dy_f)));
ctx.pushCommand(Command.rect(cx - dx, cy + dy, @intCast(dx * 2 + 1), 1, color));
}
}
/// Stroke a circle
pub fn strokeCircle(ctx: *Context, cx: i32, cy: i32, radius: u32, thickness: u32, color: Style.Color) void {
if (radius == 0) return;
const r = @as(i32, @intCast(radius));
var px: i32 = 0;
var py: i32 = r;
var d: i32 = 3 - 2 * r;
while (px <= py) {
setPixelThick(ctx, cx + px, cy + py, thickness, color);
setPixelThick(ctx, cx - px, cy + py, thickness, color);
setPixelThick(ctx, cx + px, cy - py, thickness, color);
setPixelThick(ctx, cx - px, cy - py, thickness, color);
setPixelThick(ctx, cx + py, cy + px, thickness, color);
setPixelThick(ctx, cx - py, cy + px, thickness, color);
setPixelThick(ctx, cx + py, cy - px, thickness, color);
setPixelThick(ctx, cx - py, cy - px, thickness, color);
if (d < 0) {
d = d + 4 * px + 6;
} else {
d = d + 4 * (px - py) + 10;
py -= 1;
}
px += 1;
}
}
fn setPixelThick(ctx: *Context, pixel_x: i32, pixel_y: i32, thickness: u32, color: Style.Color) void {
if (thickness <= 1) {
ctx.pushCommand(Command.rect(pixel_x, pixel_y, 1, 1, color));
} else {
const half = @as(i32, @intCast(thickness / 2));
ctx.pushCommand(Command.rect(pixel_x - half, pixel_y - half, thickness, thickness, color));
}
}

File diff suppressed because it is too large Load diff

146
src/widgets/icon/types.zig Normal file
View file

@ -0,0 +1,146 @@
//! Icon - Tipos y configuración
//!
//! Size, IconType, Config, Colors.
const Style = @import("../../core/style.zig");
// =============================================================================
// Size
// =============================================================================
/// Icon size presets
pub const Size = enum {
small, // 12x12
medium, // 16x16
large, // 24x24
xlarge, // 32x32
pub fn pixels(self: Size) u32 {
return switch (self) {
.small => 12,
.medium => 16,
.large => 24,
.xlarge => 32,
};
}
};
// =============================================================================
// IconType
// =============================================================================
/// Built-in icon types
pub const IconType = enum {
// Navigation
arrow_up,
arrow_down,
arrow_left,
arrow_right,
chevron_up,
chevron_down,
chevron_left,
chevron_right,
home,
menu,
more_horizontal,
more_vertical,
// Actions
check,
close,
plus,
minus,
edit,
delete,
refresh,
search,
settings,
filter,
sort,
copy,
paste,
cut,
undo,
redo,
// Files
file,
folder,
folder_open,
document,
image_file,
download,
upload,
save,
// Status
info,
warning,
error_icon,
success,
question,
star,
star_filled,
heart,
heart_filled,
// UI elements
eye,
eye_off,
lock,
unlock,
user,
users,
calendar,
clock,
bell,
mail,
// Media
play,
pause,
stop,
volume,
volume_off,
// Misc
grip,
drag,
expand,
collapse,
maximize,
minimize,
external_link,
};
// =============================================================================
// Config
// =============================================================================
/// Icon configuration
pub const Config = struct {
/// Icon size
size: Size = .medium,
/// Custom size (overrides size preset)
custom_size: ?u32 = null,
/// Stroke width
stroke_width: u32 = 2,
/// Fill icon
filled: bool = false,
};
// =============================================================================
// Colors
// =============================================================================
/// Icon colors
pub const Colors = struct {
foreground: Style.Color = Style.Color.rgba(220, 220, 220, 255),
background: ?Style.Color = null,
pub fn fromTheme(theme: Style.Theme) Colors {
return .{
.foreground = theme.foreground,
};
}
};

View file

@ -9,7 +9,7 @@ const Command = @import("../core/command.zig");
const Layout = @import("../core/layout.zig"); const Layout = @import("../core/layout.zig");
const Style = @import("../core/style.zig"); const Style = @import("../core/style.zig");
const Input = @import("../core/input.zig"); const Input = @import("../core/input.zig");
const icon_module = @import("icon.zig"); const icon_module = @import("icon/icon.zig");
/// IconButton style variants /// IconButton style variants
pub const ButtonStyle = enum { pub const ButtonStyle = enum {

View file

@ -9,7 +9,7 @@ const Command = @import("../core/command.zig");
const Layout = @import("../core/layout.zig"); const Layout = @import("../core/layout.zig");
const Style = @import("../core/style.zig"); const Style = @import("../core/style.zig");
const Input = @import("../core/input.zig"); const Input = @import("../core/input.zig");
const icon_module = @import("icon.zig"); const icon_module = @import("icon/icon.zig");
/// Navigation item /// Navigation item
pub const NavItem = struct { pub const NavItem = struct {

View file

@ -39,7 +39,7 @@ pub const richtext = @import("richtext.zig");
pub const breadcrumb = @import("breadcrumb.zig"); pub const breadcrumb = @import("breadcrumb.zig");
pub const canvas = @import("canvas.zig"); pub const canvas = @import("canvas.zig");
pub const chart = @import("chart.zig"); pub const chart = @import("chart.zig");
pub const icon = @import("icon.zig"); pub const icon = @import("icon/icon.zig");
pub const virtual_scroll = @import("virtual_scroll.zig"); pub const virtual_scroll = @import("virtual_scroll.zig");
pub const virtual_advanced_table = @import("virtual_advanced_table/virtual_advanced_table.zig"); pub const virtual_advanced_table = @import("virtual_advanced_table/virtual_advanced_table.zig");