Input matrix fields
This commit is contained in:
parent
7d1ebdee0b
commit
c739f34581
1 changed files with 88 additions and 81 deletions
159
program.odin
159
program.odin
|
|
@ -4,6 +4,7 @@ import rl "libraries/raylib"
|
||||||
import ui "libraries/snths_ui"
|
import ui "libraries/snths_ui"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:math/linalg"
|
import "core:math/linalg"
|
||||||
|
import "core:strconv"
|
||||||
|
|
||||||
UiContainerType :: enum {
|
UiContainerType :: enum {
|
||||||
Normal,
|
Normal,
|
||||||
|
|
@ -63,18 +64,6 @@ MatrixTypes :: enum {
|
||||||
.Rotation = rl.KeyboardKey.R,
|
.Rotation = rl.KeyboardKey.R,
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix_add_hotkey_proc_identity :: proc() {program_add_identity_matrix()}
|
|
||||||
matrix_add_hotkey_proc_translation :: proc() {program_show_dialog(&program, .CreateTranslationMatrix)}
|
|
||||||
matrix_add_hotkey_proc_scale :: proc() {program_show_dialog(&program, .CreateScaleMatrix)}
|
|
||||||
matrix_add_hotkey_proc_rotation :: proc() {program_show_dialog(&program, .CreateRotationMatrix)}
|
|
||||||
|
|
||||||
@rodata matrix_add_procs := [MatrixTypes](proc()) {
|
|
||||||
.Identity = matrix_add_hotkey_proc_identity,
|
|
||||||
.Translation = matrix_add_hotkey_proc_translation,
|
|
||||||
.Scale = matrix_add_hotkey_proc_scale,
|
|
||||||
.Rotation = matrix_add_hotkey_proc_rotation,
|
|
||||||
}
|
|
||||||
|
|
||||||
FontStyle :: struct {
|
FontStyle :: struct {
|
||||||
font: rl.Font,
|
font: rl.Font,
|
||||||
size, spacing: f32
|
size, spacing: f32
|
||||||
|
|
@ -161,6 +150,16 @@ matrix_pool_get_mat3 :: proc() -> ^mat3 {
|
||||||
return mat
|
return mat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matrix_pool_get_mat3_2 :: proc() -> []InputFloatField {
|
||||||
|
assert(program.matrix_count + 1 < matrix_pool_max(), "Max matrix count exceeded")
|
||||||
|
value_strings := program.matrix_value_string_pool[program.matrix_count * 9 : program.matrix_count * 9 + 9]
|
||||||
|
for &str in value_strings {
|
||||||
|
str[0] = '0'
|
||||||
|
}
|
||||||
|
program.matrix_count += 1
|
||||||
|
return value_strings
|
||||||
|
}
|
||||||
|
|
||||||
program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType) {
|
program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType) {
|
||||||
program.dialog_data = {}
|
program.dialog_data = {}
|
||||||
program.ui_overlay_queue_focus_first = true
|
program.ui_overlay_queue_focus_first = true
|
||||||
|
|
@ -198,22 +197,29 @@ program_update :: proc() {
|
||||||
ui_elements, matrix_container := program_build_workspace_ui(&program.ui_context)
|
ui_elements, matrix_container := program_build_workspace_ui(&program.ui_context)
|
||||||
ui_overlay_elements: []ui.Element
|
ui_overlay_elements: []ui.Element
|
||||||
|
|
||||||
for hotkey, i in matrix_add_hotkeys {
|
|
||||||
if rl.IsKeyPressed(hotkey) {
|
|
||||||
matrix_add_procs[i]()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch program.state {
|
switch program.state {
|
||||||
case .Normal:
|
case .Normal:
|
||||||
program.mouse_state = program_handle_mouse_workspace(program.mouse_state, matrix_container)
|
program.mouse_state = program_handle_mouse_workspace(program.mouse_state, matrix_container)
|
||||||
if rl.IsKeyPressed(.TAB) {
|
if rl.IsKeyPressed(.TAB) {
|
||||||
program.ui_element_focus = ui.focus_next_element(program.ui_element_focus, ui_elements, UI_ALLOWED_FOCUS)
|
program.ui_element_focus = ui.focus_next_element(program.ui_element_focus, ui_elements, UI_ALLOWED_FOCUS)
|
||||||
}
|
}
|
||||||
|
for hotkey, index in matrix_add_hotkeys {
|
||||||
|
if rl.IsKeyPressed(hotkey) {
|
||||||
|
switch index {
|
||||||
|
case .Identity: program_add_identity_matrix()
|
||||||
|
case .Translation: program_show_dialog(&program, .CreateTranslationMatrix)
|
||||||
|
case .Scale: program_show_dialog(&program, .CreateScaleMatrix)
|
||||||
|
case .Rotation: program_show_dialog(&program, .CreateRotationMatrix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
case .Message:
|
case .Message:
|
||||||
|
|
||||||
case .Dialog:
|
case .Dialog:
|
||||||
ui_overlay_elements = program_build_dialog_ui(&program.ui_overlay_context, program.dialog_type)
|
ui_overlay_elements = program_build_dialog_ui(&program.ui_overlay_context, program.dialog_type)
|
||||||
|
if rl.IsKeyPressed(.TAB) {
|
||||||
|
program.ui_overlay_element_focus = ui.focus_next_element(program.ui_overlay_element_focus, ui_overlay_elements, UI_ALLOWED_FOCUS)
|
||||||
|
}
|
||||||
if rl.IsKeyDown(.ENTER) {
|
if rl.IsKeyDown(.ENTER) {
|
||||||
vals := program.dialog_data.input_values
|
vals := program.dialog_data.input_values
|
||||||
switch program.dialog_type {
|
switch program.dialog_type {
|
||||||
|
|
@ -234,7 +240,9 @@ program_update :: proc() {
|
||||||
grid_inner_position := rect_get_tl(grid.inner_area)
|
grid_inner_position := rect_get_tl(grid.inner_area)
|
||||||
draw_grid(grid.area, {32.0, 32.0}, rl.GRAY)
|
draw_grid(grid.area, {32.0, 32.0}, rl.GRAY)
|
||||||
|
|
||||||
program.ui_element_focus = program_render_ui_and_handle_focus(&program.ui_context, program.ui_element_focus, program.font_style, ui_elements)
|
ui_element_focus := program.state == .Normal ? program.ui_element_focus : ui.element_id_invalid()
|
||||||
|
program.ui_element_focus = program_render_ui_and_handle_focus(&program.ui_context, ui_element_focus, program.font_style, ui_elements)
|
||||||
|
|
||||||
if len(ui_overlay_elements) > 0 {
|
if len(ui_overlay_elements) > 0 {
|
||||||
rl.DrawRectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, {0, 0, 0, 192})
|
rl.DrawRectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, {0, 0, 0, 192})
|
||||||
program.ui_overlay_element_focus = program_render_ui_and_handle_focus(
|
program.ui_overlay_element_focus = program_render_ui_and_handle_focus(
|
||||||
|
|
@ -246,40 +254,43 @@ program_update :: proc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
program_add_identity_matrix :: proc() {
|
program_add_identity_matrix :: proc() {
|
||||||
mat := matrix_pool_get_mat3()
|
value_strings := matrix_pool_get_mat3_2()
|
||||||
mat^ = {
|
value_strings[0][0] = '1'
|
||||||
1, 0, 0,
|
value_strings[4][0] = '1'
|
||||||
0, 1, 0,
|
value_strings[8][0] = '1'
|
||||||
0, 0, 1,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
program_add_translation_matrix :: proc(x, y, z: f32) {
|
program_add_translation_matrix :: proc(x, y, z: f32) {
|
||||||
mat := matrix_pool_get_mat3()
|
value_strings := matrix_pool_get_mat3_2()
|
||||||
mat^ = {
|
fmt.bprint(value_strings[2][:], x)
|
||||||
1, 0, x,
|
fmt.bprint(value_strings[5][:], y)
|
||||||
0, 1, y,
|
fmt.bprint(value_strings[8][:], z)
|
||||||
0, 0, z,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
program_add_scalar_matrix :: proc(x, y, z: f32) {
|
program_add_scalar_matrix :: proc(x, y, z: f32) {
|
||||||
mat := matrix_pool_get_mat3()
|
value_strings := matrix_pool_get_mat3_2()
|
||||||
mat^ = {
|
fmt.bprint(value_strings[0][:], x)
|
||||||
x, 0, 0,
|
fmt.bprint(value_strings[4][:], y)
|
||||||
0, y, 0,
|
fmt.bprint(value_strings[8][:], z)
|
||||||
0, 0, z,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
program_add_rotation_matrix :: proc(angle: f32) {
|
program_add_rotation_matrix :: proc(angle: f32) {
|
||||||
mat := matrix_pool_get_mat3()
|
value_strings := matrix_pool_get_mat3_2()
|
||||||
rotmat := linalg.matrix2_rotate_f32(angle)
|
rotmat := linalg.matrix2_rotate_f32(angle)
|
||||||
mat^ = {
|
fmt.bprint(value_strings[0][:], rotmat[0, 0])
|
||||||
rotmat[0, 0], rotmat[0, 1], 0,
|
fmt.bprint(value_strings[1][:], rotmat[0, 1])
|
||||||
rotmat[1, 0], rotmat[1, 1], 0,
|
fmt.bprint(value_strings[3][:], rotmat[1, 0])
|
||||||
0, 0, 1,
|
fmt.bprint(value_strings[4][:], rotmat[1, 1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui_labeled_input_float_element :: proc(label: cstring, margin: f32, value: ^f32, value_string: ^InputFloatField, allocator := context.temp_allocator) -> ^ui.Element {
|
||||||
|
label := fmt.ctprintf("%s: ", label)
|
||||||
|
label_element := ui.element(.Label, {}, {label = label, color = ui.col(rl.WHITE), margin = margin})
|
||||||
|
dimensions := ui.Dimensions{ui.Size_Pixels(64.0), ui.dimensions_pixels(ui.rect_get_size(ui.get_element_outer_area(label_element^))).height}
|
||||||
|
ui.same_line()
|
||||||
|
input_data := new(UiElementData_FloatInput, context.temp_allocator)
|
||||||
|
input_data^ = {value = value, value_string = cstring(&value_string[0])}
|
||||||
|
return ui.element(.InputFloat, dimensions, {margin = margin}, input_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType) -> []ui.Element {
|
program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType) -> []ui.Element {
|
||||||
|
|
@ -297,11 +308,17 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
||||||
|
|
||||||
ui.start(ctx, V2_ZERO, {WINDOW_WIDTH, WINDOW_HEIGHT})
|
ui.start(ctx, V2_ZERO, {WINDOW_WIDTH, WINDOW_HEIGHT})
|
||||||
ui.container_begin(ui.dimensions_auto(), {margin = container_margin, padding = 8.0})
|
ui.container_begin(ui.dimensions_auto(), {margin = container_margin, padding = 8.0})
|
||||||
|
switch dialog_type {
|
||||||
|
case .CreateTranslationMatrix, .CreateScaleMatrix:
|
||||||
ui.element(.Label, {}, {label = program_dialog_messages[program.dialog_type], color = ui.col(rl.WHITE), margin = element_margin})
|
ui.element(.Label, {}, {label = program_dialog_messages[program.dialog_type], color = ui.col(rl.WHITE), margin = element_margin})
|
||||||
ui_labeled_input_float_element("X", 4.0, &dialog_data.input_values[0], &dialog_data.input_value_strings[0])
|
ui_labeled_input_float_element("X", 4.0, &dialog_data.input_values[0], &dialog_data.input_value_strings[0])
|
||||||
ui_labeled_input_float_element("Y", 4.0, &dialog_data.input_values[1], &dialog_data.input_value_strings[1])
|
ui_labeled_input_float_element("Y", 4.0, &dialog_data.input_values[1], &dialog_data.input_value_strings[1])
|
||||||
ui_labeled_input_float_element("Z", 4.0, &dialog_data.input_values[2], &dialog_data.input_value_strings[2])
|
ui_labeled_input_float_element("Z", 4.0, &dialog_data.input_values[2], &dialog_data.input_value_strings[2])
|
||||||
|
|
||||||
|
case .CreateRotationMatrix:
|
||||||
|
ui.element(.Label, {}, {label = program_dialog_messages[program.dialog_type], color = ui.col(rl.WHITE), margin = element_margin})
|
||||||
|
ui_labeled_input_float_element("Angle", 4.0, &dialog_data.input_values[0], &dialog_data.input_value_strings[0])
|
||||||
|
}
|
||||||
button_data: ^UiElementData_Button
|
button_data: ^UiElementData_Button
|
||||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
button_data^ = {type = button_type}
|
button_data^ = {type = button_type}
|
||||||
|
|
@ -315,39 +332,6 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
||||||
return ui.end()
|
return ui.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_labeled_input_float_element :: proc(label: cstring, margin: f32, value: ^f32, value_string: ^InputFloatField, allocator := context.temp_allocator) -> ^ui.Element {
|
|
||||||
label := fmt.ctprintf("%s: ", label)
|
|
||||||
label_element := ui.element(.Label, {}, {label = label, color = ui.col(rl.WHITE), margin = margin})
|
|
||||||
dimensions := ui.Dimensions{ui.Size_Pixels(64.0), ui.dimensions_pixels(ui.rect_get_size(ui.get_element_outer_area(label_element^))).height}
|
|
||||||
ui.same_line()
|
|
||||||
input_data := new(UiElementData_FloatInput, context.temp_allocator)
|
|
||||||
input_data^ = {value = value, value_string = cstring(&value_string[0])}
|
|
||||||
return ui.element(.InputFloat, dimensions, {margin = margin}, input_data)
|
|
||||||
}
|
|
||||||
|
|
||||||
program_handle_mouse_workspace :: proc(mouse_state: MouseState, matrix_container: ^ui.Element) -> MouseState {
|
|
||||||
mouse := rl.GetMousePosition()
|
|
||||||
switch mouse_state {
|
|
||||||
case .Hover:
|
|
||||||
if rl.IsMouseButtonPressed(.LEFT) {
|
|
||||||
return .DraggingGrid
|
|
||||||
} else if rect_has_point(rect2(matrix_container.area), mouse) {
|
|
||||||
return .HoverMatrices
|
|
||||||
}
|
|
||||||
case .DraggingGrid:
|
|
||||||
program.grid.inner_area = rect_translate(program.grid.inner_area, rl.GetMouseDelta())
|
|
||||||
if !rl.IsMouseButtonDown(.LEFT) {
|
|
||||||
return .Hover
|
|
||||||
}
|
|
||||||
case .HoverMatrices:
|
|
||||||
program.matrix_scroll = max(0, program.matrix_scroll - rl.GetMouseWheelMove() * program.matrix_scroll_speed)
|
|
||||||
if !rect_has_point(rect2(matrix_container.area), mouse) {
|
|
||||||
return .Hover
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mouse_state
|
|
||||||
}
|
|
||||||
|
|
||||||
program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element, matrix_container: ^ui.Element) {
|
program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element, matrix_container: ^ui.Element) {
|
||||||
ui.start(ctx, {0, 0}, {WINDOW_WIDTH, WINDOW_HEIGHT})
|
ui.start(ctx, {0, 0}, {WINDOW_WIDTH, WINDOW_HEIGHT})
|
||||||
top_bar_container_config := ui.ElementConfiguration {margin = 4.0}
|
top_bar_container_config := ui.ElementConfiguration {margin = 4.0}
|
||||||
|
|
@ -404,6 +388,29 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
program_handle_mouse_workspace :: proc(mouse_state: MouseState, matrix_container: ^ui.Element) -> MouseState {
|
||||||
|
mouse := rl.GetMousePosition()
|
||||||
|
switch mouse_state {
|
||||||
|
case .Hover:
|
||||||
|
if rl.IsMouseButtonPressed(.LEFT) {
|
||||||
|
return .DraggingGrid
|
||||||
|
} else if rect_has_point(rect2(matrix_container.area), mouse) {
|
||||||
|
return .HoverMatrices
|
||||||
|
}
|
||||||
|
case .DraggingGrid:
|
||||||
|
program.grid.inner_area = rect_translate(program.grid.inner_area, rl.GetMouseDelta())
|
||||||
|
if !rl.IsMouseButtonDown(.LEFT) {
|
||||||
|
return .Hover
|
||||||
|
}
|
||||||
|
case .HoverMatrices:
|
||||||
|
program.matrix_scroll = max(0, program.matrix_scroll - rl.GetMouseWheelMove() * program.matrix_scroll_speed)
|
||||||
|
if !rect_has_point(rect2(matrix_container.area), mouse) {
|
||||||
|
return .Hover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mouse_state
|
||||||
|
}
|
||||||
|
|
||||||
program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: ui.ElementId, font_style: FontStyle, elements: []ui.Element) -> (focus: ui.ElementId) {
|
program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: ui.ElementId, font_style: FontStyle, elements: []ui.Element) -> (focus: ui.ElementId) {
|
||||||
scissor_container: ^ui.Element
|
scissor_container: ^ui.Element
|
||||||
render_above: ui.Element
|
render_above: ui.Element
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue