Moving corners like intended
This commit is contained in:
parent
4918501712
commit
6bd838968d
4 changed files with 114 additions and 19 deletions
|
|
@ -11,6 +11,7 @@ ANIMATION_COLOR_ORIGIN :: rl.RED
|
||||||
ANIMATION_COLOR_END :: rl.BLUE
|
ANIMATION_COLOR_END :: rl.BLUE
|
||||||
|
|
||||||
RectangleCorners :: struct {tl, tr, br, bl: v2}
|
RectangleCorners :: struct {tl, tr, br, bl: v2}
|
||||||
|
RectangleCornersCorner :: enum {Tl, Tr, Br, Bl}
|
||||||
|
|
||||||
rectangle_corners_from_rect :: proc "contextless" (rect: rect2) -> RectangleCorners {
|
rectangle_corners_from_rect :: proc "contextless" (rect: rect2) -> RectangleCorners {
|
||||||
return {
|
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 {
|
rectangle_corners_transform_mat2 :: proc "contextless" (corners: RectangleCorners, transform: mat2) -> RectangleCorners {
|
||||||
return {corners.tl * transform, corners.tr * transform, corners.br * transform, corners.bl * transform}
|
return {corners.tl * transform, corners.tr * transform, corners.br * transform, corners.bl * transform}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ ElementType :: enum {
|
||||||
InputText,
|
InputText,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Label,
|
Label,
|
||||||
|
Divider,
|
||||||
Custom0,
|
Custom0,
|
||||||
Custom1,
|
Custom1,
|
||||||
Custom2,
|
Custom2,
|
||||||
|
|
|
||||||
78
program.odin
78
program.odin
|
|
@ -184,11 +184,22 @@ ProgramAnimationState :: enum {
|
||||||
|
|
||||||
MouseDraggableType :: enum {
|
MouseDraggableType :: enum {
|
||||||
Point,
|
Point,
|
||||||
|
RectangleCorner,
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseDraggable :: struct {
|
MouseDraggable_Point :: struct {
|
||||||
data: rawptr,
|
ref: ^v2,
|
||||||
type: MouseDraggableType,
|
}
|
||||||
|
|
||||||
|
MouseDraggable_RectangleCornerData :: struct {
|
||||||
|
corner: RectangleCornersCorner,
|
||||||
|
corners_ref: ^RectangleCorners,
|
||||||
|
corner_ref: ^v2,
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseDraggable :: union {
|
||||||
|
MouseDraggable_Point,
|
||||||
|
MouseDraggable_RectangleCornerData,
|
||||||
}
|
}
|
||||||
|
|
||||||
Program :: struct {
|
Program :: struct {
|
||||||
|
|
@ -419,10 +430,22 @@ program_update :: proc() {
|
||||||
|
|
||||||
switch animation.type {
|
switch animation.type {
|
||||||
case .Rectangle:
|
case .Rectangle:
|
||||||
append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.tl, .Point})
|
append(&program.mouse_draggables, MouseDraggable_RectangleCornerData{
|
||||||
append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.tr, .Point})
|
corner = .Tl,
|
||||||
append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.bl, .Point})
|
corners_ref = &animation.shapes.rectangle,
|
||||||
append(&program.mouse_draggables, MouseDraggable{&animation.shapes.rectangle.br, .Point})
|
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.same_line()
|
||||||
ui.element(.Button, button_dimensions, button_config, button_data)
|
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
|
play_button_label: cstring
|
||||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
switch program.animation_state {
|
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)
|
grid_to_world_matrix := linalg.inverse(world_to_grid_matrix)
|
||||||
|
|
||||||
for draggable in program.mouse_draggables {
|
for draggable in program.mouse_draggables {
|
||||||
switch draggable.type {
|
switch draggable in draggable {
|
||||||
case .Point:
|
case MouseDraggable_Point:
|
||||||
position := cast(^v2)draggable.data
|
position_world := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy
|
||||||
position_world := (v3{**position^, 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)
|
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) {
|
if rl.IsMouseButtonPressed(.LEFT) {
|
||||||
for draggable in program.mouse_draggables {
|
for draggable in program.mouse_draggables {
|
||||||
switch draggable.type {
|
switch draggable in draggable {
|
||||||
case .Point:
|
case MouseDraggable_Point:
|
||||||
position := cast(^v2)draggable.data
|
circle_position := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy
|
||||||
circle_position := (v3{**position^, 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 {
|
if linalg.distance(mouse, circle_position) <= program.mouse_draggable_radius {
|
||||||
program.mouse_current_draggable = draggable
|
program.mouse_current_draggable = draggable
|
||||||
return .DraggingDraggable
|
return .DraggingDraggable
|
||||||
|
|
@ -649,10 +684,13 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_
|
||||||
return .Hover
|
return .Hover
|
||||||
}
|
}
|
||||||
draggable := program.mouse_current_draggable
|
draggable := program.mouse_current_draggable
|
||||||
switch draggable.type {
|
switch draggable in draggable {
|
||||||
case .Point:
|
case MouseDraggable_Point:
|
||||||
vector := cast(^v2)draggable.data
|
draggable.ref^ = (v3{**mouse, 1.0} * world_to_grid_matrix).xy
|
||||||
vector^ = (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:
|
case .DraggingGrid:
|
||||||
program.grid.offset -= rl.GetMouseDelta()
|
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:
|
case .Label:
|
||||||
rl.DrawTextEx(font_style.font, element.label, rect_get_tl(area), font_style.size, font_style.spacing, color)
|
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:
|
case:
|
||||||
rl.DrawRectangleRec(area, rl.MAGENTA)
|
rl.DrawRectangleRec(area, rl.MAGENTA)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO (synthas): Things to save to the project file
|
||||||
|
- Grid configuration
|
||||||
|
- Shape configuration
|
||||||
|
*/
|
||||||
|
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue