From 6bd838968d5b2786b5f7417cf7f4f98881870f1e Mon Sep 17 00:00:00 2001 From: Synthasmagoria Date: Tue, 25 Aug 2026 18:38:56 +0200 Subject: [PATCH] Moving corners like intended --- animation.odin | 48 +++++++++++++++++++++++ libraries/snths_ui/ui.odin | 1 + program.odin | 78 ++++++++++++++++++++++++++++---------- project.odin | 6 +++ 4 files changed, 114 insertions(+), 19 deletions(-) diff --git a/animation.odin b/animation.odin index 9aaad8c..0145bb9 100644 --- a/animation.odin +++ b/animation.odin @@ -11,6 +11,7 @@ ANIMATION_COLOR_ORIGIN :: rl.RED ANIMATION_COLOR_END :: rl.BLUE RectangleCorners :: struct {tl, tr, br, bl: v2} +RectangleCornersCorner :: enum {Tl, Tr, Br, Bl} rectangle_corners_from_rect :: proc "contextless" (rect: rect2) -> RectangleCorners { return { @@ -39,6 +40,53 @@ rectangle_corners_lerp :: proc "contextless" (a, b: RectangleCorners, t: f32) -> } } +rectangle_corners_move_corner :: proc "contextless" (corners: RectangleCorners, position: v2, corner: RectangleCornersCorner) -> RectangleCorners { + corners := corners + switch corner { + case .Tl: + corners = _rectangle_corners_move_corner_resolve_tl(corners, position) + case .Tr: + corners = _rectangle_corners_move_corner_resolve_tr(corners, position) + case .Br: + corners = _rectangle_corners_move_corner_resolve_br(corners, position) + case .Bl: + corners = _rectangle_corners_move_corner_resolve_bl(corners, position) + } + return corners +} + +_rectangle_corners_move_corner_resolve_tl :: proc "contextless" (corners: RectangleCorners, position: v2) -> RectangleCorners { + corners := corners + corners.tl = position + corners.bl.x = position.x + corners.tr.y = position.y + return corners +} + +_rectangle_corners_move_corner_resolve_tr :: proc "contextless" (corners: RectangleCorners, position: v2) -> RectangleCorners { + corners := corners + corners.tr = position + corners.br.x = position.x + corners.tl.y = position.y + return corners +} + +_rectangle_corners_move_corner_resolve_br :: proc "contextless" (corners: RectangleCorners, position: v2) -> RectangleCorners { + corners := corners + corners.br = position + corners.tr.x = position.x + corners.bl.y = position.y + return corners +} + +_rectangle_corners_move_corner_resolve_bl :: proc "contextless" (corners: RectangleCorners, position: v2) -> RectangleCorners { + corners := corners + corners.bl = position + corners.tl.x = position.x + corners.br.y = position.y + return corners +} + rectangle_corners_transform_mat2 :: proc "contextless" (corners: RectangleCorners, transform: mat2) -> RectangleCorners { return {corners.tl * transform, corners.tr * transform, corners.br * transform, corners.bl * transform} } diff --git a/libraries/snths_ui/ui.odin b/libraries/snths_ui/ui.odin index cff42d9..2a9eabf 100644 --- a/libraries/snths_ui/ui.odin +++ b/libraries/snths_ui/ui.odin @@ -63,6 +63,7 @@ ElementType :: enum { InputText, Dropdown, Label, + Divider, Custom0, Custom1, Custom2, diff --git a/program.odin b/program.odin index 8ca4cdf..d0f764c 100644 --- a/program.odin +++ b/program.odin @@ -184,11 +184,22 @@ ProgramAnimationState :: enum { MouseDraggableType :: enum { Point, + RectangleCorner, } -MouseDraggable :: struct { - data: rawptr, - type: MouseDraggableType, +MouseDraggable_Point :: struct { + ref: ^v2, +} + +MouseDraggable_RectangleCornerData :: struct { + corner: RectangleCornersCorner, + corners_ref: ^RectangleCorners, + corner_ref: ^v2, +} + +MouseDraggable :: union { + MouseDraggable_Point, + MouseDraggable_RectangleCornerData, } Program :: struct { @@ -419,10 +430,22 @@ program_update :: proc() { switch animation.type { case .Rectangle: - append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.tl, .Point}) - append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.tr, .Point}) - append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.bl, .Point}) - append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.br, .Point}) + append(&program.mouse_draggables, MouseDraggable_RectangleCornerData{ + corner = .Tl, + corners_ref = &animation.shapes.rectangle, + corner_ref = &animation.shapes.rectangle.tl}) + append(&program.mouse_draggables, MouseDraggable_RectangleCornerData{ + corner = .Tr, + corners_ref = &animation.shapes.rectangle, + corner_ref = &animation.shapes.rectangle.tr}) + append(&program.mouse_draggables, MouseDraggable_RectangleCornerData{ + corner = .Bl, + corners_ref = &animation.shapes.rectangle, + corner_ref = &animation.shapes.rectangle.bl}) + append(&program.mouse_draggables, MouseDraggable_RectangleCornerData{ + corner = .Br, + corners_ref = &animation.shapes.rectangle, + corner_ref = &animation.shapes.rectangle.br}) } } @@ -564,6 +587,11 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> ui.same_line() ui.element(.Button, button_dimensions, button_config, button_data) + divider_dimensions := ui.Dimensions{ui.Size_Pixels(4.0), ui.Size_Percentage(1.0)} + divider_config := ui.ElementConfiguration{margin = 8.0, color = ui.col(rl.WHITE)} + ui.same_line() + ui.element(.Divider, divider_dimensions, divider_config) + play_button_label: cstring button_data = new(UiElementData_Button, context.temp_allocator) switch program.animation_state { @@ -611,10 +639,12 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_ grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) for draggable in program.mouse_draggables { - switch draggable.type { - case .Point: - position := cast(^v2)draggable.data - position_world := (v3{**position^, 1.0} * grid_to_world_matrix).xy + switch draggable in draggable { + case MouseDraggable_Point: + position_world := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy + rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN) + case MouseDraggable_RectangleCornerData: + position_world := (v3{**draggable.corner_ref^, 1.0} * grid_to_world_matrix).xy rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN) } } @@ -629,10 +659,15 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_ } if rl.IsMouseButtonPressed(.LEFT) { for draggable in program.mouse_draggables { - switch draggable.type { - case .Point: - position := cast(^v2)draggable.data - circle_position := (v3{**position^, 1.0} * grid_to_world_matrix).xy + switch draggable in draggable { + case MouseDraggable_Point: + circle_position := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy + if linalg.distance(mouse, circle_position) <= program.mouse_draggable_radius { + program.mouse_current_draggable = draggable + return .DraggingDraggable + } + case MouseDraggable_RectangleCornerData: + circle_position := (v3{**draggable.corner_ref^, 1.0} * grid_to_world_matrix).xy if linalg.distance(mouse, circle_position) <= program.mouse_draggable_radius { program.mouse_current_draggable = draggable return .DraggingDraggable @@ -649,10 +684,13 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_ return .Hover } draggable := program.mouse_current_draggable - switch draggable.type { - case .Point: - vector := cast(^v2)draggable.data - vector^ = (v3{**mouse, 1.0} * world_to_grid_matrix).xy + switch draggable in draggable { + case MouseDraggable_Point: + draggable.ref^ = (v3{**mouse, 1.0} * world_to_grid_matrix).xy + case MouseDraggable_RectangleCornerData: + position := (v3{**mouse, 1.0} * world_to_grid_matrix).xy + corners := rectangle_corners_move_corner(draggable.corners_ref^, position, draggable.corner) + draggable.corners_ref^ = corners } case .DraggingGrid: program.grid.offset -= rl.GetMouseDelta() @@ -824,6 +862,8 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u } case .Label: rl.DrawTextEx(font_style.font, element.label, rect_get_tl(area), font_style.size, font_style.spacing, color) + case .Divider: + rl.DrawRectangleRec(area, color) case: rl.DrawRectangleRec(area, rl.MAGENTA) } diff --git a/project.odin b/project.odin index 717e69e..46386be 100644 --- a/project.odin +++ b/project.odin @@ -1,5 +1,11 @@ package main +/* + TODO (synthas): Things to save to the project file + - Grid configuration + - Shape configuration +*/ + import "core:os" import "core:io" import "core:mem"