Quit prompt, always show coordinates, web build, always draw rect
This commit is contained in:
parent
40062fcdc2
commit
28b5fb0a42
6 changed files with 87 additions and 44 deletions
14
TODO.MD
14
TODO.MD
|
|
@ -1,7 +1,13 @@
|
|||
- Centered justification in UI
|
||||
- Web build
|
||||
- Web read/write
|
||||
- Remove default project load error message on startup
|
||||
- Ship with default setup
|
||||
- Fix -vet errors
|
||||
- Snap to grid option
|
||||
- Set grid
|
||||
- Set animation value
|
||||
|
||||
DONE:
|
||||
- When there is no matrix it should still draw the rectangle
|
||||
- Keyboard input doesnt work on web
|
||||
- Resizing doesn't work on web
|
||||
- Always show coordinates
|
||||
- Web build
|
||||
- Escape closes dialogue if on dialogue. Otherwise stops program if on desktop, but not without an unsaved changes warning.
|
||||
|
|
|
|||
|
|
@ -196,11 +196,16 @@ animation_draw :: proc(animation: ^Animation, global_transform: mat3, mode: Anim
|
|||
transform *= mat
|
||||
rectangles[i + 1] = rectangle_corners_transform_mat3(transform, animation.shapes.rectangle)
|
||||
}
|
||||
if animation.matrix_count == 0 {
|
||||
rectangle_world := rectangle_corners_transform_mat3(global_transform, rectangles[0])
|
||||
draw_animation_rectangle_corners(rectangle_world, ANIMATION_COLOR_ORIGIN)
|
||||
} else {
|
||||
for rectangle, i in rectangles {
|
||||
color := linalg.lerp(color_origin, color_end, f32(i) / f32(animation.matrix_count))
|
||||
rectangle_world := rectangle_corners_transform_mat3(global_transform, rectangle)
|
||||
draw_animation_rectangle_corners(rectangle_world, rl.Color(color))
|
||||
}
|
||||
}
|
||||
if animation.matrix_count <= 0 {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -996,6 +996,7 @@ RLAPI bool IsWindowMaximized(void); // Check if wi
|
|||
RLAPI bool IsWindowFocused(void); // Check if window is currently focused
|
||||
RLAPI bool IsWindowResized(void); // Check if window has been resized last frame
|
||||
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
|
||||
RLAPI bool IsWindowCloseFlagSet(); // Check if the close flag has been set
|
||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags
|
||||
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
|
||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
|
||||
|
|
|
|||
|
|
@ -794,6 +794,11 @@ bool IsWindowState(unsigned int flag)
|
|||
return FLAG_IS_SET(CORE.Window.flags, flag);
|
||||
}
|
||||
|
||||
bool IsWindowCloseFlagSet()
|
||||
{
|
||||
return CORE.Window.shouldClose;
|
||||
}
|
||||
|
||||
// Get current screen width
|
||||
int GetScreenWidth(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ init :: proc() {
|
|||
rl.SetConfigFlags({.VSYNC_HINT})
|
||||
rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_CAPTION)
|
||||
rl.SetTargetFPS(WINDOW_FRAMERATE)
|
||||
rl.SetExitKey(.KEY_NULL)
|
||||
program_init()
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ shutdown :: proc() {
|
|||
|
||||
should_run :: proc() -> bool {
|
||||
when ODIN_OS != .JS {
|
||||
if rl.WindowShouldClose() {
|
||||
if program.window_should_close || rl.WindowShouldClose() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ UiButtonType :: enum {
|
|||
MatrixMoveUp,
|
||||
MatrixMoveDown,
|
||||
CenterView,
|
||||
CloseProgram,
|
||||
}
|
||||
|
||||
UiButtonRecalculateFinishGroup :: bit_set[UiButtonType]{
|
||||
|
|
@ -191,6 +192,7 @@ ProgramDialogType :: enum {
|
|||
CreateSkewMatrix,
|
||||
SaveProject,
|
||||
LoadProject,
|
||||
CloseUnsavedProjectPrompt,
|
||||
Error,
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +203,7 @@ ProgramDialogType :: enum {
|
|||
.CreateSkewMatrix = "Create skew matrix",
|
||||
.SaveProject = "Save project",
|
||||
.LoadProject = "Load project",
|
||||
.CloseUnsavedProjectPrompt = "Unsaved project",
|
||||
.Error = "Error",
|
||||
}
|
||||
|
||||
|
|
@ -263,11 +266,6 @@ RotationMode :: enum {
|
|||
Radians,
|
||||
}
|
||||
|
||||
ProgramShowAnimationCoords :: enum {
|
||||
NoCoords,
|
||||
Coords,
|
||||
}
|
||||
|
||||
Program :: struct {
|
||||
ui_context: ui.Context,
|
||||
ui_element_focus: ui.ElementId,
|
||||
|
|
@ -287,6 +285,7 @@ Program :: struct {
|
|||
mouse_draggable_radius: f32,
|
||||
project_save_string: [DIALOG_STATE_TEXT_INPUT_FIELD_COUNT]byte,
|
||||
rotation_mode: RotationMode,
|
||||
saved_project_data: ProjectData,
|
||||
grid: Grid,
|
||||
grid_zoom_x_only: bool,
|
||||
grid_zoom_y_only: bool,
|
||||
|
|
@ -301,7 +300,6 @@ Program :: struct {
|
|||
animation_state: ProgramAnimationState,
|
||||
animation_speed: f32,
|
||||
animation_mode: AnimationMode,
|
||||
animation_show_coordinates: ProgramShowAnimationCoords,
|
||||
window_should_close: bool,
|
||||
}
|
||||
|
||||
|
|
@ -347,14 +345,20 @@ matrix_move_to :: proc(floats: []f32, inputs: []InputFloatField, from, to: int)
|
|||
}
|
||||
|
||||
program_save_project :: proc(program: ^Program, path: string) -> ProjectWriteError {
|
||||
project := ProjectData {
|
||||
project := program_create_project_data(program^)
|
||||
project_write(&project, path) or_return
|
||||
program.saved_project_data = project
|
||||
program.saved_project_data.matrices = slice.clone(program.saved_project_data.matrices)
|
||||
return nil
|
||||
}
|
||||
|
||||
program_create_project_data :: proc(program: Program) -> ProjectData {
|
||||
return {
|
||||
matrix_count = u32(program.matrix_count),
|
||||
matrices = program.matrix_float_pool,
|
||||
grid = program.grid,
|
||||
shapes = program.animation.shapes,
|
||||
}
|
||||
project_write(&project, path) or_return
|
||||
return nil
|
||||
}
|
||||
|
||||
program_save_project_from_project_string_or_open_dialog :: proc(program: ^Program) {
|
||||
|
|
@ -385,6 +389,8 @@ program_load_project :: proc(program: ^Program, path: string) -> ProjectReadErro
|
|||
write_matrix_to_values_and_value_strings(program.matrix_float_pool[start:end], program.matrix_value_string_pool[start:end], mat)
|
||||
}
|
||||
program.animation.matrix_count = program.matrix_count
|
||||
program.saved_project_data = project
|
||||
program.saved_project_data.matrices = slice.clone(program.saved_project_data.matrices)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -432,8 +438,6 @@ program_init :: proc(allocator := context.allocator) {
|
|||
animation_init(&program.animation, program.matrix_float_pool)
|
||||
|
||||
if err := program_load_project(&program, default_project_load_location); err != nil {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
@ -550,6 +554,8 @@ program_update :: proc() {
|
|||
} else {
|
||||
program.state = .Normal
|
||||
}
|
||||
case .CloseUnsavedProjectPrompt:
|
||||
program.window_should_close = true
|
||||
case .Error:
|
||||
program.state = .Normal
|
||||
}
|
||||
|
|
@ -558,6 +564,36 @@ program_update :: proc() {
|
|||
}
|
||||
}
|
||||
|
||||
if rl.IsKeyPressed(.ESCAPE) {
|
||||
switch program.state {
|
||||
case .Normal:
|
||||
when ODIN_OS != .JS {
|
||||
current_project_data := program_create_project_data(program)
|
||||
|
||||
current_matrices_ptr := cast([^]byte)raw_data(current_project_data.matrices)
|
||||
current_matrices := current_matrices_ptr[:current_project_data.matrix_count * 9 * 4]
|
||||
last_saved_matrices_ptr := cast([^]byte)raw_data(program.saved_project_data.matrices)
|
||||
last_saved_matrices := last_saved_matrices_ptr[:program.saved_project_data.matrix_count * 9 * 4]
|
||||
|
||||
current_project_grid_ptr := cast([^]byte)¤t_project_data.grid
|
||||
last_saved_grid_ptr := cast([^]byte)&program.saved_project_data.grid
|
||||
|
||||
current_project_shapes_ptr := cast([^]byte)¤t_project_data.shapes
|
||||
last_saved_shapes_ptr := cast([^]byte)&program.saved_project_data.shapes
|
||||
|
||||
if mem.compare(current_matrices, last_saved_matrices) == 0 &&
|
||||
mem.compare(current_project_grid_ptr[:size_of(Grid)], last_saved_grid_ptr[:size_of(Grid)]) == 0 &&
|
||||
mem.compare(current_project_shapes_ptr[:size_of(AnimationShapes)], last_saved_shapes_ptr[:size_of(AnimationShapes)]) == 0 {
|
||||
program.window_should_close = true
|
||||
}
|
||||
|
||||
program_show_dialog(&program, .CloseUnsavedProjectPrompt, "Are you sure you want to quit?");
|
||||
}
|
||||
case .Dialog:
|
||||
program.state = .Normal
|
||||
}
|
||||
}
|
||||
|
||||
clear(&program.mouse_draggables)
|
||||
|
||||
top_bar_container_br := rect_get_br(rect2(top_bar_container.area))
|
||||
|
|
@ -637,11 +673,9 @@ program_update :: proc() {
|
|||
ui_overlay_elements)
|
||||
}
|
||||
|
||||
if (program.animation_show_coordinates == .Coords) {
|
||||
shape_coords_string_position := program_screen_size() - 4.0
|
||||
draw_text_aligned(shape_coord_string, shape_coords_string_position, program.font_style, .Right, .Bottom, rl.WHITE)
|
||||
}
|
||||
}
|
||||
|
||||
program_add_identity_matrix :: proc() {
|
||||
value_strings, values := matrix_pool_get_mat3()
|
||||
|
|
@ -731,7 +765,7 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
|||
} else {
|
||||
button_type = .AddScaleMatrixConfirm
|
||||
}
|
||||
ui_confirm_and_cancel_buttons(button_type, element_margin)
|
||||
ui_confirm_and_cancel_buttons("Add", button_type, element_margin)
|
||||
case .CreateRotationMatrix:
|
||||
ui_labeled_input_float_element("Angle", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0])
|
||||
toggle_group_dimensions := ui.dimensions_pixels(128.0, 32.0)
|
||||
|
|
@ -740,17 +774,19 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType
|
|||
toggle_group_data := new(UiElementData_ToggleGroup)
|
||||
toggle_group_data^ = {value = cast(^i32)&program.rotation_mode}
|
||||
ui.element(.ToggleGroup, toggle_group_dimensions, toggle_group_config, toggle_group_data)
|
||||
ui_confirm_and_cancel_buttons(.AddRotationMatrixConfirm, element_margin)
|
||||
ui_confirm_and_cancel_buttons("Add", .AddRotationMatrixConfirm, element_margin)
|
||||
case .CreateSkewMatrix:
|
||||
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("Y", 4.0, &dialog_data.input_float_values[1], &dialog_data.input_float_value_strings[1])
|
||||
ui_confirm_and_cancel_buttons(.AddSkewMatrixConfirm, element_margin)
|
||||
ui_confirm_and_cancel_buttons("Add", .AddSkewMatrixConfirm, element_margin)
|
||||
case .SaveProject:
|
||||
ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:])
|
||||
ui_confirm_and_cancel_buttons(.ProjectSaveConfirm, element_margin)
|
||||
ui_confirm_and_cancel_buttons("Add", .ProjectSaveConfirm, element_margin)
|
||||
case .LoadProject:
|
||||
ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:])
|
||||
ui_confirm_and_cancel_buttons(.ProjectLoadConfirm, element_margin)
|
||||
ui_confirm_and_cancel_buttons("Add", .ProjectLoadConfirm, element_margin)
|
||||
case .CloseUnsavedProjectPrompt:
|
||||
ui_confirm_and_cancel_buttons("Confirm", .CloseProgram, element_margin)
|
||||
case .Error:
|
||||
button_data: ^UiElementData_Button
|
||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||
|
|
@ -898,10 +934,6 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
|
|||
ui.same_line()
|
||||
ui.element(.Slider, slider_dimensions, slider_config, slider_data)
|
||||
|
||||
// label_config := ui.ElementConfiguration{margin = button_margin, label = "Animation mode: ", color = ui.col(rl.WHITE)}
|
||||
// ui.same_line()
|
||||
// ui.element(.Label, ui.dimensions_auto(), label_config)
|
||||
|
||||
toggle_group_config: ui.ElementConfiguration
|
||||
toggle_group_dimensions := ui.Dimensions{top_bar_button_width * 3.0, ui.Size_Percentage(1.0)}
|
||||
toggle_group_data: ^UiElementData_ToggleGroup
|
||||
|
|
@ -914,15 +946,6 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element,
|
|||
toggle_group_data^ = {value = cast(^i32)&program.animation_mode}
|
||||
ui.same_line()
|
||||
ui.element(.ToggleGroup, toggle_group_dimensions, toggle_group_config, toggle_group_data)
|
||||
|
||||
toggle_group_config = {
|
||||
margin = button_margin,
|
||||
label = enum_to_raygui_options_string(ProgramShowAnimationCoords, context.temp_allocator),
|
||||
}
|
||||
toggle_group_data = new(UiElementData_ToggleGroup, context.temp_allocator)
|
||||
toggle_group_data^ = {value = cast(^i32)&program.animation_show_coordinates}
|
||||
ui.same_line()
|
||||
ui.element(.ToggleGroup, toggle_group_dimensions, toggle_group_config, toggle_group_data)
|
||||
}
|
||||
ui.container_end()
|
||||
|
||||
|
|
@ -1180,6 +1203,8 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u
|
|||
program.grid.cell_size_px = 50.0
|
||||
case .DismissError:
|
||||
program.state = .Normal
|
||||
case .CloseProgram:
|
||||
program.window_should_close = true
|
||||
}
|
||||
if data.type in UiButtonRecalculateFinishGroup {
|
||||
program.animation.matrix_count = program.matrix_count
|
||||
|
|
@ -1241,11 +1266,11 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u
|
|||
return focus_element_id
|
||||
}
|
||||
|
||||
ui_confirm_and_cancel_buttons :: proc(button_type_add: UiButtonType, margin: f32) {
|
||||
ui_confirm_and_cancel_buttons :: proc(confirm_label: cstring, button_type_add: UiButtonType, margin: f32) {
|
||||
button_data: ^UiElementData_Button
|
||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||
button_data^ = {type = button_type_add}
|
||||
ui.element(.Button, ui.dimensions_pixels(96.0, 32.0), {label = "Add", margin = margin}, button_data)
|
||||
ui.element(.Button, ui.dimensions_pixels(96.0, 32.0), {label = confirm_label, margin = margin}, button_data)
|
||||
|
||||
button_data = new(UiElementData_Button, context.temp_allocator)
|
||||
button_data^ = {type = .ExitDialog}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue