From 1e052f5a9136b063f722f7ff5a12a88cadfcf031 Mon Sep 17 00:00:00 2001 From: thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> Date: Mon, 29 Nov 2021 09:26:24 -0500 Subject: [PATCH] FontEditor: Convert mode and transform buttons into toolbar actions This will let us more easily organize and assign shortcuts to new modes and transformations as they are built, and it generally looks more polished as a uniform interface. Also adds a counterclockwise option to the rotate action, moves Copy as Character to the edit menu as it doesn't directly impact GlyphEditor, and makes the paint and move modes exclusive checkables to make the editor's state more visually obvious. --- .../Applications/FontEditor/FontEditor.cpp | 65 +++++++++------ Userland/Applications/FontEditor/FontEditor.h | 10 +++ .../FontEditor/FontEditorWindow.gml | 82 ++++--------------- .../FontEditor/GlyphEditorWidget.cpp | 8 +- .../FontEditor/GlyphEditorWidget.h | 7 +- 5 files changed, 75 insertions(+), 97 deletions(-) diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp index 60652d2524..8eb74ae199 100644 --- a/Userland/Applications/FontEditor/FontEditor.cpp +++ b/Userland/Applications/FontEditor/FontEditor.cpp @@ -111,12 +111,10 @@ FontEditorWidget::FontEditorWidget() load_from_gml(font_editor_window_gml); auto& toolbar = *find_descendant_of_type_named("toolbar"); + auto& glyph_mode_toolbar = *find_descendant_of_type_named("glyph_mode_toolbar"); + auto& glyph_transform_toolbar = *find_descendant_of_type_named("glyph_transform_toolbar"); auto& glyph_map_container = *find_descendant_of_type_named("glyph_map_container"); - auto& move_glyph_button = *find_descendant_of_type_named("move_glyph_button"); - auto& rotate_90_button = *find_descendant_of_type_named("rotate_90"); - auto& flip_vertical_button = *find_descendant_of_type_named("flip_vertical"); - auto& flip_horizontal_button = *find_descendant_of_type_named("flip_horizontal"); - auto& copy_code_point_button = *find_descendant_of_type_named("copy_code_point"); + m_statusbar = *find_descendant_of_type_named("statusbar"); m_glyph_editor_container = *find_descendant_of_type_named("glyph_editor_container"); m_left_column_container = *find_descendant_of_type_named("left_column_container"); @@ -325,35 +323,48 @@ FontEditorWidget::FontEditorWidget() m_glyph_editor_scale_actions.add_action(*m_scale_fifteen_action); m_glyph_editor_scale_actions.set_exclusive(true); - move_glyph_button.on_click = [&](auto) { - if (move_glyph_button.is_checked()) - m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move); - else - m_glyph_editor_widget->set_mode(GlyphEditorWidget::Paint); - }; - move_glyph_button.set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/selection-move.png").release_value_but_fixme_should_propagate_errors()); + m_paint_glyph_action = GUI::Action::create_checkable("Paint Glyph", { Mod_Ctrl, KeyCode::Key_J }, Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/pen.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_glyph_editor_widget->set_mode(GlyphEditorWidget::Paint); + }); + m_paint_glyph_action->set_checked(true); - rotate_90_button.on_click = [&](auto) { - m_glyph_editor_widget->rotate_90(); - }; - rotate_90_button.set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-rotate-cw.png").release_value_but_fixme_should_propagate_errors()); + m_move_glyph_action = GUI::Action::create_checkable("Move Glyph", { Mod_Ctrl, KeyCode::Key_K }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/selection-move.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move); + }); - flip_vertical_button.on_click = [&](auto) { - m_glyph_editor_widget->flip_vertically(); - }; - flip_vertical_button.set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png").release_value_but_fixme_should_propagate_errors()); + m_glyph_tool_actions.add_action(*m_move_glyph_action); + m_glyph_tool_actions.add_action(*m_paint_glyph_action); + m_glyph_tool_actions.set_exclusive(true); - flip_horizontal_button.on_click = [&](auto) { + glyph_mode_toolbar.add_action(*m_paint_glyph_action); + glyph_mode_toolbar.add_action(*m_move_glyph_action); + + m_rotate_counterclockwise_action = GUI::Action::create("Rotate Counterclockwise", { Mod_Ctrl | Mod_Shift, Key_Z }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-rotate-ccw.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_glyph_editor_widget->rotate_90(GlyphEditorWidget::Counterclockwise); + }); + + m_rotate_clockwise_action = GUI::Action::create("Rotate Clockwise", { Mod_Ctrl | Mod_Shift, Key_X }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-rotate-cw.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_glyph_editor_widget->rotate_90(GlyphEditorWidget::Clockwise); + }); + + m_flip_horizontal_action = GUI::Action::create("Flip Horizontally", { Mod_Ctrl | Mod_Shift, Key_A }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { m_glyph_editor_widget->flip_horizontally(); - }; - flip_horizontal_button.set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png").release_value_but_fixme_should_propagate_errors()); + }); - copy_code_point_button.on_click = [&](auto) { + m_flip_vertical_action = GUI::Action::create("Flip Vertically", { Mod_Ctrl | Mod_Shift, Key_S }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_glyph_editor_widget->flip_vertically(); + }); + + m_copy_character_action = GUI::Action::create("Cop&y as Character", { Mod_Ctrl | Mod_Shift, Key_C }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-copy.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { StringBuilder glyph_builder; glyph_builder.append_code_point(m_glyph_editor_widget->glyph()); GUI::Clipboard::the().set_plain_text(glyph_builder.build()); - }; - copy_code_point_button.set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-copy.png").release_value_but_fixme_should_propagate_errors()); + }); + + glyph_transform_toolbar.add_action(*m_flip_horizontal_action); + glyph_transform_toolbar.add_action(*m_flip_vertical_action); + glyph_transform_toolbar.add_action(*m_rotate_counterclockwise_action); + glyph_transform_toolbar.add_action(*m_rotate_clockwise_action); GUI::Clipboard::the().on_change = [&](const String& data_type) { m_paste_action->set_enabled(data_type == "glyph/x-fonteditor"); @@ -574,6 +585,8 @@ void FontEditorWidget::initialize_menubar(GUI::Window& window) edit_menu.add_action(*m_paste_action); edit_menu.add_action(*m_delete_action); edit_menu.add_separator(); + edit_menu.add_action(*m_copy_character_action); + edit_menu.add_separator(); edit_menu.add_action(*m_previous_glyph_action); edit_menu.add_action(*m_next_glyph_action); edit_menu.add_action(*m_go_to_glyph_action); diff --git a/Userland/Applications/FontEditor/FontEditor.h b/Userland/Applications/FontEditor/FontEditor.h index a4af6ac5b8..5245e5f5d8 100644 --- a/Userland/Applications/FontEditor/FontEditor.h +++ b/Userland/Applications/FontEditor/FontEditor.h @@ -78,6 +78,16 @@ private: RefPtr m_scale_ten_action; RefPtr m_scale_fifteen_action; + GUI::ActionGroup m_glyph_tool_actions; + RefPtr m_move_glyph_action; + RefPtr m_paint_glyph_action; + + RefPtr m_flip_horizontal_action; + RefPtr m_flip_vertical_action; + RefPtr m_rotate_clockwise_action; + RefPtr m_rotate_counterclockwise_action; + RefPtr m_copy_character_action; + RefPtr m_statusbar; RefPtr m_font_preview_window; RefPtr m_left_column_container; diff --git a/Userland/Applications/FontEditor/FontEditorWindow.gml b/Userland/Applications/FontEditor/FontEditorWindow.gml index a3cf68b1ae..a4a4322062 100644 --- a/Userland/Applications/FontEditor/FontEditorWindow.gml +++ b/Userland/Applications/FontEditor/FontEditorWindow.gml @@ -31,81 +31,31 @@ } @GUI::Widget { + shrink_to_fit: true + layout: @GUI::VerticalBoxLayout { } - @GUI::Widget { - shrink_to_fit: true - - layout: @GUI::HorizontalBoxLayout { - } - - @GUI::SpinBox { - name: "glyph_editor_width_spinbox" - } - - @GUI::CheckBox { - name: "glyph_editor_present_checkbox" - text: "Present" - focus_policy: "TabFocus" - } - - @GUI::Button { - name: "move_glyph_button" - fixed_width: 22 - tooltip: "Move Glyph" - button_style: "Coolbar" - checkable: true - } + @GUI::SpinBox { + name: "glyph_editor_width_spinbox" } - @GUI::Widget { - shrink_to_fit: true + @GUI::CheckBox { + name: "glyph_editor_present_checkbox" + text: "Present" + focus_policy: "TabFocus" + } + } - layout: @GUI::HorizontalBoxLayout { - } + @GUI::ToolbarContainer { + name: "glyph_toolbar_container" - @GUI::Button { - name: "flip_vertical" - fixed_width: 22 - tooltip: "Flip vertically (top to bottom)" - button_style: "Coolbar" - focus_policy: "TabFocus" - } - - @GUI::Button { - name: "flip_horizontal" - fixed_width: 22 - tooltip: "Flip horizontally (left to right)" - button_style: "Coolbar" - focus_policy: "TabFocus" - } + @GUI::Toolbar { + name: "glyph_mode_toolbar" } - @GUI::Widget { - shrink_to_fit: true - - layout: @GUI::HorizontalBoxLayout { - } - - @GUI::Button { - name: "rotate_90" - fixed_width: 22 - tooltip: "Rotate 90° clockwise" - button_style: "Coolbar" - focus_policy: "TabFocus" - } - - @GUI::Widget { - } - - @GUI::Button { - name: "copy_code_point" - fixed_width: 22 - tooltip: "Copy this codepoint (not glyph)" - button_style: "Coolbar" - focus_policy: "TabFocus" - } + @GUI::Toolbar { + name: "glyph_transform_toolbar" } } } diff --git a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp index acde46891f..a59298bdef 100644 --- a/Userland/Applications/FontEditor/GlyphEditorWidget.cpp +++ b/Userland/Applications/FontEditor/GlyphEditorWidget.cpp @@ -276,7 +276,7 @@ static Vector> glyph_as_matrix(Gfx::GlyphBitmap const& bitmap) return result; } -void GlyphEditorWidget::rotate_90() +void GlyphEditorWidget::rotate_90(Direction direction) { if (on_undo_event) on_undo_event(); @@ -286,11 +286,11 @@ void GlyphEditorWidget::rotate_90() for (int y = 0; y < bitmap.height(); y++) { for (int x = 0; x < bitmap.width(); x++) { - int source_x = y; - int source_y = bitmap.width() - 1 - x; + int source_x = (direction == Counterclockwise) ? max(bitmap.width() - 1 - y, 0) : y; + int source_y = (direction == Counterclockwise) ? x : bitmap.width() - 1 - x; bool value = false; if (source_x < bitmap.width() && source_y < bitmap.height()) { - value = matrix[source_y][source_x]; + value = (direction == Counterclockwise && y >= bitmap.width()) ? false : matrix[source_y][source_x]; } bitmap.set_bit_at(x, y, value); } diff --git a/Userland/Applications/FontEditor/GlyphEditorWidget.h b/Userland/Applications/FontEditor/GlyphEditorWidget.h index 6cc42c44ab..c743fcdabc 100644 --- a/Userland/Applications/FontEditor/GlyphEditorWidget.h +++ b/Userland/Applications/FontEditor/GlyphEditorWidget.h @@ -21,6 +21,11 @@ public: Move }; + enum Direction { + Clockwise, + Counterclockwise + }; + virtual ~GlyphEditorWidget() override; void initialize(Gfx::BitmapFont&); @@ -34,7 +39,7 @@ public: void delete_glyph(); bool is_glyph_empty(); - void rotate_90(); + void rotate_90(Direction); void flip_vertically(); void flip_horizontally();