Animation slider

This commit is contained in:
Synthasmagoria 2026-08-28 10:08:53 +02:00
commit 75602ea8d1
2 changed files with 31 additions and 12 deletions

View file

@ -6,7 +6,7 @@ import rl "libraries/raylib"
Grid :: struct { Grid :: struct {
cell_size_px: v2, cell_size_px: v2,
zoom_previous, zoom: v2, zoom_previous, zoom: v2,
world_position, world_size, offset: v2, offset: v2,
} }
grid_get_zoom :: proc(zoom: v2) -> v2 { grid_get_zoom :: proc(zoom: v2) -> v2 {
@ -44,20 +44,22 @@ grid_world_to_grid_matrix :: proc(zoom, offset: v2) -> mat3 {
linalg.matrix3_scale(v3{**zoom_amount, 1.0})) linalg.matrix3_scale(v3{**zoom_amount, 1.0}))
} }
draw_grid :: proc(grid: Grid, text_draw, text_clip: rect2) { draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2) {
world_to_grid_matrix := grid_world_to_grid_matrix(grid.zoom, grid.offset) world_to_grid_matrix := grid_world_to_grid_matrix(grid.zoom, grid.offset)
grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) grid_to_world_matrix := linalg.inverse(world_to_grid_matrix)
grid_world_br := grid.world_position + grid.world_size position := rect_get_tl(area)
size := rect_get_size(area)
grid_world_br := position + size
grid_color := rl.Color{64, 64, 64, 255} grid_color := rl.Color{64, 64, 64, 255}
sep := grid_get_line_separation(grid.zoom, grid.cell_size_px) sep := grid_get_line_separation(grid.zoom, grid.cell_size_px)
tl := (v3{**grid.world_position, 1.0} * world_to_grid_matrix).xy tl := (v3{**position, 1.0} * world_to_grid_matrix).xy
tl = linalg.floor(tl / sep) * sep tl = linalg.floor(tl / sep) * sep
br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy
for x: f32 = tl.x; x < br.x; x += sep.x { for x: f32 = tl.x; x < br.x; x += sep.x {
world_position_x := (v3{x, 0.0, 1.0} * grid_to_world_matrix).x world_position_x := (v3{x, 0.0, 1.0} * grid_to_world_matrix).x
p1 := v2{world_position_x, grid.world_position.y} p1 := v2{world_position_x, position.y}
p2 := v2{world_position_x, grid_world_br.y} p2 := v2{world_position_x, grid_world_br.y}
rl.DrawLineV(p1, p2, grid_color) rl.DrawLineV(p1, p2, grid_color)
if p1.x >= text_clip.x && p1.x < text_clip.x + text_clip.width { if p1.x >= text_clip.x && p1.x < text_clip.x + text_clip.width {
@ -67,7 +69,7 @@ draw_grid :: proc(grid: Grid, text_draw, text_clip: rect2) {
for y: f32 = tl.y; y < br.y; y += sep.y { for y: f32 = tl.y; y < br.y; y += sep.y {
world_position_y := (v3{0.0, y, 1.0} * grid_to_world_matrix).y world_position_y := (v3{0.0, y, 1.0} * grid_to_world_matrix).y
p1 := v2{grid.world_position.x, world_position_y} p1 := v2{position.x, world_position_y}
p2 := v2{grid_world_br.x, world_position_y} p2 := v2{grid_world_br.x, world_position_y}
rl.DrawLineV(p1, p2, grid_color) rl.DrawLineV(p1, p2, grid_color)
if p1.y >= text_clip.y && p1.y < text_clip.y + text_clip.height { if p1.y >= text_clip.y && p1.y < text_clip.y + text_clip.height {

View file

@ -357,8 +357,7 @@ program_init :: proc(allocator := context.allocator) {
program.grid = { program.grid = {
cell_size_px = 40.0, cell_size_px = 40.0,
zoom = 1.0, zoom = 1.0,
world_position = 0.0, offset = -program_screen_size() / 2.0,
world_size = program_screen_size()
} }
program.grid_zoom_speed = 1.0 program.grid_zoom_speed = 1.0
program.mouse_draggable_radius = 6.0 program.mouse_draggable_radius = 6.0
@ -497,9 +496,9 @@ program_update :: proc() {
top_bar_container_br := rect_get_br(rect2(top_bar_container.area)) top_bar_container_br := rect_get_br(rect2(top_bar_container.area))
matrix_container_br := rect_get_br(rect2(matrix_container.area)) matrix_container_br := rect_get_br(rect2(matrix_container.area))
program.grid.world_size = program_screen_size()
grid_text_clip := rect_from_area(v2{matrix_container_br.x, top_bar_container_br.y}, program_screen_size()) grid_text_clip := rect_from_area(v2{matrix_container_br.x, top_bar_container_br.y}, program_screen_size())
draw_grid(program.grid, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0)) grid_area := rect2{0.0, 0.0, **program_screen_size()}
draw_grid(program.grid, grid_area, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0))
{ {
animation := &program.animation animation := &program.animation
@ -671,7 +670,8 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
top_bar_element_margin: f32 = 4.0 top_bar_element_margin: f32 = 4.0
top_bar_container = ui.container_begin({ui.Size_Percentage(1.0), ui.Size_Pixels(48.0)}, top_bar_container_config) top_bar_container = ui.container_begin({ui.Size_Percentage(1.0), ui.Size_Pixels(48.0)}, top_bar_container_config)
top_bar_inner_height := ui.get_element_inner_area(top_bar_container^).height top_bar_inner_height := ui.get_element_inner_area(top_bar_container^).height
top_bar_button_dimensions := ui.Dimensions {ui.Size_Pixels(top_bar_inner_height), ui.Size_Pixels(top_bar_inner_height)} top_bar_button_width := ui.Size_Pixels(top_bar_inner_height)
top_bar_button_dimensions := ui.Dimensions {top_bar_button_width, ui.Size_Percentage(1.0)}
top_bar_button_config := ui.ElementConfiguration {margin = top_bar_element_margin} top_bar_button_config := ui.ElementConfiguration {margin = top_bar_element_margin}
top_bar_dropdown_dimensions := ui.Dimensions {ui.Size_Pixels(160.0), ui.Size_Percentage(1.0)} top_bar_dropdown_dimensions := ui.Dimensions {ui.Size_Pixels(160.0), ui.Size_Percentage(1.0)}
top_bar_dropdown_config := ui.ElementConfiguration {margin = top_bar_element_margin} top_bar_dropdown_config := ui.ElementConfiguration {margin = top_bar_element_margin}
@ -681,6 +681,7 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
button_tooltip: cstring button_tooltip: cstring
button_dimensions := top_bar_button_dimensions button_dimensions := top_bar_button_dimensions
button_data: ^UiElementData_Button button_data: ^UiElementData_Button
divider_dimensions := ui.Dimensions{ui.Size_Pixels(1.0), ui.Size_Percentage(1.0)} divider_dimensions := ui.Dimensions{ui.Size_Pixels(1.0), ui.Size_Percentage(1.0)}
divider_config := ui.ElementConfiguration{padding = 4.0, color = ui.col(rl.WHITE)} divider_config := ui.ElementConfiguration{padding = 4.0, color = ui.col(rl.WHITE)}
@ -772,6 +773,22 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
button_data^ = {type = .CenterView} button_data^ = {type = .CenterView}
ui.same_line() ui.same_line()
ui.element(.Button, button_dimensions, button_config, button_data) ui.element(.Button, button_dimensions, button_config, button_data)
ui.same_line()
ui.element(.Divider, divider_dimensions, divider_config)
slider_config: ui.ElementConfiguration
slider_data: ^UiElementData_Slider
slider_dimensions := ui.Dimensions {top_bar_button_width * 5.0, ui.Size_Percentage(1.0)}
slider_config = {margin = top_bar_element_margin * 2}
slider_data = new(UiElementData_Slider, context.temp_allocator)
slider_data^ = {
value = &program.animation.matrix_index,
max = f32(program.animation.matrix_count),
min = 0.0
}
ui.same_line()
ui.element(.Slider, slider_dimensions, slider_config, slider_data)
} }
ui.container_end() ui.container_end()
@ -1013,7 +1030,7 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u
// TODO (synthas): Reset zoom // TODO (synthas): Reset zoom
world_to_grid_matrix := grid_world_to_grid_matrix(program.grid.zoom, program.grid.offset) world_to_grid_matrix := grid_world_to_grid_matrix(program.grid.zoom, program.grid.offset)
grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) grid_to_world_matrix := linalg.inverse(world_to_grid_matrix)
center := animation_get_center(program.animation) / grid_get_zoom(program.grid.zoom) - program.grid.world_size / 2.0 center := animation_get_center(program.animation) / grid_get_zoom(program.grid.zoom) - program_screen_size() / 2.0
program.grid.offset = center program.grid.offset = center
case .ProjectSave: case .ProjectSave:
program_save_project_from_project_string_or_open_dialog(&program) program_save_project_from_project_string_or_open_dialog(&program)