Better saving/loading
This commit is contained in:
parent
ebd0ef76d3
commit
e6bb0cb1f7
3 changed files with 139 additions and 43 deletions
5
TODO.MD
5
TODO.MD
|
|
@ -1,12 +1,9 @@
|
||||||
- Grid line changing
|
|
||||||
- Zoom sensitivity
|
|
||||||
- Playback slider
|
- Playback slider
|
||||||
- Save grid and animation data to file
|
- Save grid and animation data to file
|
||||||
- Load project
|
|
||||||
- Fix focus on submenu
|
- Fix focus on submenu
|
||||||
- Centered justification in UI
|
- Centered justification in UI
|
||||||
- Get a more legible theme + consistency
|
- Get a more legible theme + consistency
|
||||||
- Fix delay on control points
|
- Fix delay on control points
|
||||||
- Fix build
|
|
||||||
- Error handling (dialog with message)
|
- Error handling (dialog with message)
|
||||||
- Make web build
|
- Make web build
|
||||||
|
- Zoom sensitivity
|
||||||
|
|
|
||||||
148
program.odin
148
program.odin
|
|
@ -20,7 +20,8 @@ TRANSFORMATION_RECTANGLE_COLOR_MIDDLE :: rl.MAGENTA
|
||||||
TRANSFORMATION_RECTANGLE_COLOR_NEXT :: rl.GRAY
|
TRANSFORMATION_RECTANGLE_COLOR_NEXT :: rl.GRAY
|
||||||
TRANSFORMATION_RECTANGLE_COLOR_LAST :: rl.BLUE
|
TRANSFORMATION_RECTANGLE_COLOR_LAST :: rl.BLUE
|
||||||
|
|
||||||
DEFAULT_PROJECT_LOAD_LOCATION :: "default"
|
|
||||||
|
@rodata default_project_load_location := "default"
|
||||||
|
|
||||||
UiContainerType :: enum {
|
UiContainerType :: enum {
|
||||||
Normal,
|
Normal,
|
||||||
|
|
@ -56,6 +57,13 @@ UiElementData_Dropdown :: struct {
|
||||||
|
|
||||||
UiButtonType :: enum {
|
UiButtonType :: enum {
|
||||||
Nothing,
|
Nothing,
|
||||||
|
ProjectSave,
|
||||||
|
ProjectSaveAs,
|
||||||
|
ProjectLoad,
|
||||||
|
ProjectNew,
|
||||||
|
ProjectSaveConfirm,
|
||||||
|
ProjectLoadConfirm,
|
||||||
|
DismissError,
|
||||||
AddIdentity,
|
AddIdentity,
|
||||||
AddTranslation,
|
AddTranslation,
|
||||||
AddScale,
|
AddScale,
|
||||||
|
|
@ -68,7 +76,6 @@ UiButtonType :: enum {
|
||||||
PauseTransformation,
|
PauseTransformation,
|
||||||
ResumeTransformation,
|
ResumeTransformation,
|
||||||
ResetTransformation,
|
ResetTransformation,
|
||||||
SaveProjectConfirm,
|
|
||||||
MatrixDelete,
|
MatrixDelete,
|
||||||
MatrixMoveUp,
|
MatrixMoveUp,
|
||||||
MatrixMoveDown,
|
MatrixMoveDown,
|
||||||
|
|
@ -145,6 +152,7 @@ ProgramDialogType :: enum {
|
||||||
CreateRotationMatrix,
|
CreateRotationMatrix,
|
||||||
SaveProject,
|
SaveProject,
|
||||||
LoadProject,
|
LoadProject,
|
||||||
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
@rodata program_dialog_messages := [ProgramDialogType]cstring {
|
@rodata program_dialog_messages := [ProgramDialogType]cstring {
|
||||||
|
|
@ -153,6 +161,7 @@ ProgramDialogType :: enum {
|
||||||
.CreateRotationMatrix = "Create rotation matrix",
|
.CreateRotationMatrix = "Create rotation matrix",
|
||||||
.SaveProject = "Save project",
|
.SaveProject = "Save project",
|
||||||
.LoadProject = "Load project",
|
.LoadProject = "Load project",
|
||||||
|
.Error = "Error",
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramMessageType :: enum {
|
ProgramMessageType :: enum {
|
||||||
|
|
@ -226,6 +235,7 @@ Program :: struct {
|
||||||
mouse_draggables: [dynamic; 64]MouseDraggable,
|
mouse_draggables: [dynamic; 64]MouseDraggable,
|
||||||
mouse_current_draggable: MouseDraggable,
|
mouse_current_draggable: MouseDraggable,
|
||||||
mouse_draggable_radius: f32,
|
mouse_draggable_radius: f32,
|
||||||
|
project_save_string: [DIALOG_STATE_TEXT_INPUT_FIELD_COUNT]byte,
|
||||||
grid: Grid,
|
grid: Grid,
|
||||||
grid_zoom_x_only: bool,
|
grid_zoom_x_only: bool,
|
||||||
grid_zoom_y_only: bool,
|
grid_zoom_y_only: bool,
|
||||||
|
|
@ -235,6 +245,7 @@ Program :: struct {
|
||||||
message_type: ProgramMessageType,
|
message_type: ProgramMessageType,
|
||||||
dialog_type: ProgramDialogType,
|
dialog_type: ProgramDialogType,
|
||||||
dialog_data: ProgramData_DialogState,
|
dialog_data: ProgramData_DialogState,
|
||||||
|
dialog_message: cstring,
|
||||||
animation: Animation,
|
animation: Animation,
|
||||||
animation_state: ProgramAnimationState,
|
animation_state: ProgramAnimationState,
|
||||||
animation_speed: f32,
|
animation_speed: f32,
|
||||||
|
|
@ -259,20 +270,35 @@ matrix_pool_get_mat3 :: proc() -> (value_strings: []InputFloatField, values: []f
|
||||||
return value_strings, values
|
return value_strings, values
|
||||||
}
|
}
|
||||||
|
|
||||||
program_save_project :: proc(program: ^Program, path: string) -> os.Error {
|
program_save_project :: proc(program: ^Program, path: string) -> ProjectWriteError {
|
||||||
project := ProjectData {
|
project := ProjectData {
|
||||||
matrix_count = u32(program.matrix_count),
|
matrix_count = u32(program.matrix_count),
|
||||||
matrices = program.matrix_float_pool,
|
matrices = program.matrix_float_pool,
|
||||||
}
|
}
|
||||||
project_write(&project, string(program.dialog_data.input_text_buffers[0][:])) or_return
|
project_write(&project, path) or_return
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
program_save_project_from_project_string_or_open_dialog :: proc(program: ^Program) {
|
||||||
|
path: string
|
||||||
|
project_save_string := strings.string_from_null_terminated_ptr(&program.project_save_string[0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
||||||
|
if len(project_save_string) > 0 {
|
||||||
|
if err := program_save_project(program, path); err != nil {
|
||||||
|
msg := fmt.caprint("Failed to save project to '", path, "'\n" ,typeid_of(type_of(err)), ".", err, sep = "")
|
||||||
|
program_show_dialog(program, .Error, msg)
|
||||||
|
} else {
|
||||||
|
program.state = .Normal
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
program_show_dialog(program, .SaveProject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
program_load_project :: proc(program: ^Program, path: string) -> ProjectReadError {
|
program_load_project :: proc(program: ^Program, path: string) -> ProjectReadError {
|
||||||
project: ProjectData
|
project: ProjectData
|
||||||
project_read(&project, path, context.temp_allocator) or_return
|
project.matrices = program.matrix_float_pool
|
||||||
|
project_read(&project, path) or_return
|
||||||
program.matrix_count = int(project.matrix_count)
|
program.matrix_count = int(project.matrix_count)
|
||||||
mem.copy(raw_data(program.matrix_float_pool), raw_data(project.matrices), len(project.matrices) * size_of(f32) * 9)
|
|
||||||
for val, i in program.matrix_float_pool[:program.matrix_count * 9] {
|
for val, i in program.matrix_float_pool[:program.matrix_count * 9] {
|
||||||
fmt.bprint(program.matrix_value_string_pool[i][:], val)
|
fmt.bprint(program.matrix_value_string_pool[i][:], val)
|
||||||
}
|
}
|
||||||
|
|
@ -280,11 +306,12 @@ program_load_project :: proc(program: ^Program, path: string) -> ProjectReadErro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType) {
|
program_show_dialog :: proc(program: ^Program, dialog_type: ProgramDialogType, message: cstring = "") {
|
||||||
program.dialog_data = {}
|
program.dialog_data = {}
|
||||||
program.ui_overlay_queue_focus_first = true
|
program.ui_overlay_queue_focus_first = true
|
||||||
program.state = .Dialog
|
program.state = .Dialog
|
||||||
program.dialog_type = dialog_type
|
program.dialog_type = dialog_type
|
||||||
|
program.dialog_message = message
|
||||||
}
|
}
|
||||||
|
|
||||||
program_init :: proc(allocator := context.allocator) {
|
program_init :: proc(allocator := context.allocator) {
|
||||||
|
|
@ -313,8 +340,10 @@ program_init :: proc(allocator := context.allocator) {
|
||||||
|
|
||||||
animation_init(&program.animation, program.matrix_float_pool)
|
animation_init(&program.animation, program.matrix_float_pool)
|
||||||
|
|
||||||
if err := program_load_project(&program, DEFAULT_PROJECT_LOAD_LOCATION); err != nil {
|
if err := program_load_project(&program, default_project_load_location); err != nil {
|
||||||
fmt.println("ERROR:", err)
|
program_show_dialog(&program, .Error, fmt.caprint(typeid_of(type_of(err)), ".", err))
|
||||||
|
} else {
|
||||||
|
mem.copy(&program.project_save_string[0], raw_data(default_project_load_location), len(default_project_load_location))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,8 +388,9 @@ program_update :: proc() {
|
||||||
if rl.IsKeyPressed(hotkey) {
|
if rl.IsKeyPressed(hotkey) {
|
||||||
switch index {
|
switch index {
|
||||||
case .Save:
|
case .Save:
|
||||||
program_show_dialog(&program, .SaveProject)
|
program_save_project_from_project_string_or_open_dialog(&program)
|
||||||
case .Open:
|
case .Open:
|
||||||
|
program_show_dialog(&program, .LoadProject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -370,16 +400,12 @@ program_update :: proc() {
|
||||||
#partial switch index {
|
#partial switch index {
|
||||||
case .AddIdentity:
|
case .AddIdentity:
|
||||||
program_add_identity_matrix()
|
program_add_identity_matrix()
|
||||||
program.ui_overlay_queue_focus_first = true
|
|
||||||
case .AddTranslation:
|
case .AddTranslation:
|
||||||
program_show_dialog(&program, .CreateTranslationMatrix)
|
program_show_dialog(&program, .CreateTranslationMatrix)
|
||||||
program.ui_overlay_queue_focus_first = true
|
|
||||||
case .AddScale:
|
case .AddScale:
|
||||||
program_show_dialog(&program, .CreateScaleMatrix)
|
program_show_dialog(&program, .CreateScaleMatrix)
|
||||||
program.ui_overlay_queue_focus_first = true
|
|
||||||
case .AddRotation:
|
case .AddRotation:
|
||||||
program_show_dialog(&program, .CreateRotationMatrix)
|
program_show_dialog(&program, .CreateRotationMatrix)
|
||||||
program.ui_overlay_queue_focus_first = true
|
|
||||||
case .ZoomXOnly:
|
case .ZoomXOnly:
|
||||||
if program.grid_zoom_x_only {
|
if program.grid_zoom_x_only {
|
||||||
program.grid_zoom_x_only = false
|
program.grid_zoom_x_only = false
|
||||||
|
|
@ -413,14 +439,22 @@ program_update :: proc() {
|
||||||
case .CreateScaleMatrix: program_add_scalar_matrix(vals[0], vals[1], vals[2])
|
case .CreateScaleMatrix: program_add_scalar_matrix(vals[0], vals[1], vals[2])
|
||||||
case .CreateRotationMatrix: program_add_rotation_matrix(vals[0])
|
case .CreateRotationMatrix: program_add_rotation_matrix(vals[0])
|
||||||
case .SaveProject:
|
case .SaveProject:
|
||||||
input := &program.dialog_data.input_text_buffers[0][0]
|
path := strings.string_from_null_terminated_ptr(&program.dialog_data.input_text_buffers[0][0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
||||||
path := strings.string_from_null_terminated_ptr(input, DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
|
||||||
if err := program_save_project(&program, path); err != nil {
|
if err := program_save_project(&program, path); err != nil {
|
||||||
// TODO (Synthas): show error message
|
// TODO (Synthas): show error message
|
||||||
|
} else {
|
||||||
|
program.project_save_string = program.dialog_data.input_text_buffers[0]
|
||||||
|
program.state = .Normal
|
||||||
|
}
|
||||||
|
case .LoadProject:
|
||||||
|
path := strings.string_from_null_terminated_ptr(&program.dialog_data.input_text_buffers[0][0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
||||||
|
if err := program_load_project(&program, path); err != nil {
|
||||||
|
// TODO (Synthas): show error message
|
||||||
} else {
|
} else {
|
||||||
program.state = .Normal
|
program.state = .Normal
|
||||||
}
|
}
|
||||||
case .LoadProject:
|
case .Error:
|
||||||
|
program.state = .Normal
|
||||||
}
|
}
|
||||||
program.animation.matrix_count = program.matrix_count
|
program.animation.matrix_count = program.matrix_count
|
||||||
program.state = .Normal
|
program.state = .Normal
|
||||||
|
|
@ -539,7 +573,18 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
||||||
|
|
||||||
ui.start(ctx, V2_ZERO, program_screen_size())
|
ui.start(ctx, V2_ZERO, program_screen_size())
|
||||||
ui.container_begin(ui.dimensions_auto(), {margin = container_margin, padding = 8.0})
|
ui.container_begin(ui.dimensions_auto(), {margin = container_margin, padding = 8.0})
|
||||||
ui.element(.Label, {}, {label = program_dialog_messages[program.dialog_type], color = ui.col(rl.WHITE), margin = element_margin})
|
header_label_config := ui.ElementConfiguration{label = program_dialog_messages[program.dialog_type], margin = element_margin}
|
||||||
|
if dialog_type == .Error {
|
||||||
|
header_label_config.color = ui.col(rl.RED)
|
||||||
|
} else {
|
||||||
|
header_label_config.color = ui.col(rl.WHITE)
|
||||||
|
}
|
||||||
|
ui.element(.Label, {}, header_label_config)
|
||||||
|
|
||||||
|
if (len(program.dialog_message) > 0) {
|
||||||
|
ui.element(.Label, {}, {label = program.dialog_message, color = ui.col(rl.WHITE), margin = element_margin})
|
||||||
|
}
|
||||||
|
|
||||||
switch dialog_type {
|
switch dialog_type {
|
||||||
case .CreateTranslationMatrix, .CreateScaleMatrix:
|
case .CreateTranslationMatrix, .CreateScaleMatrix:
|
||||||
ui_labeled_input_float_element("X", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0])
|
ui_labeled_input_float_element("X", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0])
|
||||||
|
|
@ -551,14 +596,21 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
||||||
} else {
|
} else {
|
||||||
button_type = .AddScaleMatrixConfirm
|
button_type = .AddScaleMatrixConfirm
|
||||||
}
|
}
|
||||||
ui_add_matrix_footer_buttons(button_type, element_margin)
|
ui_confirm_and_cancel_buttons(button_type, element_margin)
|
||||||
case .CreateRotationMatrix:
|
case .CreateRotationMatrix:
|
||||||
ui_labeled_input_float_element("Angle", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0])
|
ui_labeled_input_float_element("Angle", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0])
|
||||||
ui_add_matrix_footer_buttons(.AddRotationMatrixConfirm, element_margin)
|
ui_confirm_and_cancel_buttons(.AddRotationMatrixConfirm, element_margin)
|
||||||
case .SaveProject:
|
case .SaveProject:
|
||||||
ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:])
|
ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:])
|
||||||
ui_add_matrix_footer_buttons(.SaveProjectConfirm, element_margin)
|
ui_confirm_and_cancel_buttons(.ProjectSaveConfirm, element_margin)
|
||||||
case .LoadProject:
|
case .LoadProject:
|
||||||
|
ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:])
|
||||||
|
ui_confirm_and_cancel_buttons(.ProjectLoadConfirm, element_margin)
|
||||||
|
case .Error:
|
||||||
|
button_data: ^UiElementData_Button
|
||||||
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
button_data^ = {type = .DismissError}
|
||||||
|
ui.element(.Button, ui.dimensions_pixels(96.0, 32.0), {label = "Ok", margin = element_margin}, button_data)
|
||||||
}
|
}
|
||||||
ui.container_end()
|
ui.container_end()
|
||||||
return ui.end()
|
return ui.end()
|
||||||
|
|
@ -584,10 +636,39 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) ->
|
||||||
button_config: ui.ElementConfiguration
|
button_config: ui.ElementConfiguration
|
||||||
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_config := ui.ElementConfiguration{padding = 4.0, color = ui.col(rl.WHITE)}
|
||||||
|
|
||||||
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
button_config = {margin = button_margin, label = "S", tooltip = "Save project\n(ctrl+s)"}
|
||||||
|
button_data^ = {type = .ProjectSave}
|
||||||
|
ui.element(.Button, button_dimensions, button_config, button_data)
|
||||||
|
|
||||||
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
button_config = {margin = button_margin, label = "SA", tooltip = "Save project as..."}
|
||||||
|
button_data^ = {type = .ProjectSaveAs}
|
||||||
|
ui.same_line()
|
||||||
|
ui.element(.Button, button_dimensions, button_config, button_data)
|
||||||
|
|
||||||
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
button_config = {margin = button_margin, label = "L", tooltip = "Load project\n(ctrl+o)"}
|
||||||
|
button_data^ = {type = .ProjectLoad}
|
||||||
|
ui.same_line()
|
||||||
|
ui.element(.Button, button_dimensions, button_config, button_data)
|
||||||
|
|
||||||
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
button_config = {margin = button_margin, label = "N", tooltip = "New project"}
|
||||||
|
button_data^ = {type = .ProjectNew}
|
||||||
|
ui.same_line()
|
||||||
|
ui.element(.Button, button_dimensions, button_config, button_data)
|
||||||
|
|
||||||
|
ui.same_line()
|
||||||
|
ui.element(.Divider, divider_dimensions, divider_config)
|
||||||
|
|
||||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
button_config = {margin = button_margin, label = "I", tooltip = "Add identity\nmatrix"}
|
button_config = {margin = button_margin, label = "I", tooltip = "Add identity\nmatrix"}
|
||||||
button_data^ = {type = .AddIdentity}
|
button_data^ = {type = .AddIdentity}
|
||||||
|
ui.same_line()
|
||||||
ui.element(.Button, button_dimensions, button_config, button_data)
|
ui.element(.Button, button_dimensions, button_config, button_data)
|
||||||
|
|
||||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||||
|
|
@ -609,10 +690,8 @@ 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(1.0), ui.Size_Percentage(1.0)}
|
|
||||||
// TODO (synthas): Use raygui border theme color for consistency
|
// TODO (synthas): Use raygui border theme color for consistency
|
||||||
// TODO (synthas): Padding and margin doesn't work here for some reason
|
// TODO (synthas): Padding and margin doesn't work here for some reason
|
||||||
divider_config := ui.ElementConfiguration{padding = 4.0, color = ui.col(rl.WHITE)}
|
|
||||||
ui.same_line()
|
ui.same_line()
|
||||||
ui.element(.Divider, divider_dimensions, divider_config)
|
ui.element(.Divider, divider_dimensions, divider_config)
|
||||||
|
|
||||||
|
|
@ -859,10 +938,16 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u
|
||||||
program.animation_state = .Playing
|
program.animation_state = .Playing
|
||||||
case .ResetTransformation:
|
case .ResetTransformation:
|
||||||
program.animation.matrix_index = 0.0
|
program.animation.matrix_index = 0.0
|
||||||
case .SaveProjectConfirm:
|
case .ProjectSaveConfirm:
|
||||||
input := &program.dialog_data.input_text_buffers[0][0]
|
path := strings.string_from_null_terminated_ptr(&program.dialog_data.input_text_buffers[0][0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
||||||
path := strings.string_from_null_terminated_ptr(input, DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
|
||||||
if err := program_save_project(&program, path); err != nil {
|
if err := program_save_project(&program, path); err != nil {
|
||||||
|
program_show_dialog(&program, .Error, fmt.caprint(typeid_of(type_of(err)), ".", err))
|
||||||
|
} else {
|
||||||
|
program.state = .Normal
|
||||||
|
}
|
||||||
|
case .ProjectLoadConfirm:
|
||||||
|
path := strings.string_from_null_terminated_ptr(&program.dialog_data.input_text_buffers[0][0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE)
|
||||||
|
if err := program_load_project(&program, path); err != nil {
|
||||||
// TODO (Synthas): show error message
|
// TODO (Synthas): show error message
|
||||||
} else {
|
} else {
|
||||||
program.state = .Normal
|
program.state = .Normal
|
||||||
|
|
@ -891,6 +976,15 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u
|
||||||
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.grid.world_size / 2.0
|
||||||
program.grid.offset = center
|
program.grid.offset = center
|
||||||
|
case .ProjectSave:
|
||||||
|
program_save_project_from_project_string_or_open_dialog(&program)
|
||||||
|
case .ProjectSaveAs:
|
||||||
|
program_show_dialog(&program, .SaveProject)
|
||||||
|
case .ProjectLoad:
|
||||||
|
program_show_dialog(&program, .LoadProject)
|
||||||
|
case .ProjectNew:
|
||||||
|
case .DismissError:
|
||||||
|
program.state = .Normal
|
||||||
}
|
}
|
||||||
if data.type in UiButtonRecalculateFinishGroup {
|
if data.type in UiButtonRecalculateFinishGroup {
|
||||||
program.animation.matrix_count = program.matrix_count
|
program.animation.matrix_count = program.matrix_count
|
||||||
|
|
@ -987,7 +1081,7 @@ matrix_move_to :: proc(floats: []f32, inputs: []InputFloatField, from, to: int)
|
||||||
mem.copy(inputs_moved_to_matrix, &inputs_temp[0][0], inputs_buffer_size)
|
mem.copy(inputs_moved_to_matrix, &inputs_temp[0][0], inputs_buffer_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_add_matrix_footer_buttons :: proc(button_type_add: UiButtonType, margin: f32) {
|
ui_confirm_and_cancel_buttons :: proc(button_type_add: UiButtonType, margin: f32) {
|
||||||
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_add}
|
button_data^ = {type = button_type_add}
|
||||||
|
|
|
||||||
31
project.odin
31
project.odin
|
|
@ -17,27 +17,28 @@ ProjectData :: struct {
|
||||||
version: u32,
|
version: u32,
|
||||||
matrix_count: u32,
|
matrix_count: u32,
|
||||||
matrices: []f32,
|
matrices: []f32,
|
||||||
|
grid: Grid,
|
||||||
|
animation: Animation,
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteProjectError :: union {
|
ProjectWriteError :: union {
|
||||||
os.Error,
|
os.Error,
|
||||||
|
io.Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteProjectErrorType :: enum {
|
project_write :: proc(project: ^ProjectData, path: string) -> ProjectWriteError {
|
||||||
IncompatibleVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
project_write :: proc(project: ^ProjectData, path: string) -> os.Error {
|
|
||||||
f := os.open(path, {.Create, .Trunc, .Write}) or_return
|
f := os.open(path, {.Create, .Trunc, .Write}) or_return
|
||||||
defer os.close(f)
|
defer os.close(f)
|
||||||
w := io.to_writer(os.to_stream(f))
|
w := io.to_writer(os.to_stream(f))
|
||||||
version: u32 = PROJECT_DATA_VERSION
|
version: u32 = PROJECT_DATA_VERSION
|
||||||
header := PROJECT_DATA_HEADER
|
header := PROJECT_DATA_HEADER
|
||||||
|
|
||||||
io.write_full(w, transmute([]u8)header)
|
io.write_full(w, transmute([]u8)header) or_return
|
||||||
io.write_ptr(w, &version, size_of(version))
|
io.write_ptr(w, &version, size_of(version)) or_return
|
||||||
io.write_ptr(w, &project.matrix_count, size_of(project.matrix_count))
|
io.write_ptr(w, &project.matrix_count, size_of(project.matrix_count)) or_return
|
||||||
io.write_ptr(w, raw_data(project.matrices), int(project.matrix_count) * 9 * size_of(f32))
|
n := io.write_ptr(w, raw_data(project.matrices), int(project.matrix_count) * 9 * size_of(f32)) or_return
|
||||||
|
fmt.println(n)
|
||||||
|
// io.write_ptr(w, &project.grid, size_of(Grid))
|
||||||
os.close(f)
|
os.close(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +55,9 @@ ProjectReadErrorType :: enum {
|
||||||
VersionNeedsUpgrade,
|
VersionNeedsUpgrade,
|
||||||
}
|
}
|
||||||
|
|
||||||
project_read :: proc(project: ^ProjectData, path: string, allocator: mem.Allocator) -> ProjectReadError {
|
import "core:fmt"
|
||||||
|
|
||||||
|
project_read :: proc(project: ^ProjectData, path: string) -> ProjectReadError {
|
||||||
f := os.open(path, {.Read}) or_return
|
f := os.open(path, {.Read}) or_return
|
||||||
defer os.close(f)
|
defer os.close(f)
|
||||||
r := io.to_reader(os.to_stream(f))
|
r := io.to_reader(os.to_stream(f))
|
||||||
|
|
@ -71,7 +74,9 @@ project_read :: proc(project: ^ProjectData, path: string, allocator: mem.Allocat
|
||||||
return ProjectReadErrorType.VersionNeedsUpgrade
|
return ProjectReadErrorType.VersionNeedsUpgrade
|
||||||
}
|
}
|
||||||
_ = io.read_ptr(r, &project.matrix_count, size_of(project.matrix_count)) or_return
|
_ = io.read_ptr(r, &project.matrix_count, size_of(project.matrix_count)) or_return
|
||||||
project.matrices = make([]f32, size_of(f32) * int(project.matrix_count) * 9)
|
n := io.read_ptr(r, raw_data(project.matrices), size_of(f32) * len(project.matrices)) or_return
|
||||||
_ = io.read_ptr(r, raw_data(project.matrices), size_of(f32) * len(project.matrices)) or_return
|
fmt.println(n)
|
||||||
|
// _ = io.read_ptr(r, &project.grid, size_of(Grid)) or_return
|
||||||
|
// _ = io.read_ptr(r, &project.animation, size_of(Animation)) or_return
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue