1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:17:34 +00:00

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.
This commit is contained in:
thankyouverycool 2021-11-29 09:26:24 -05:00 committed by Andreas Kling
parent b7c8dee29a
commit 1e052f5a91
5 changed files with 75 additions and 97 deletions

View file

@ -111,12 +111,10 @@ FontEditorWidget::FontEditorWidget()
load_from_gml(font_editor_window_gml); load_from_gml(font_editor_window_gml);
auto& toolbar = *find_descendant_of_type_named<GUI::Toolbar>("toolbar"); auto& toolbar = *find_descendant_of_type_named<GUI::Toolbar>("toolbar");
auto& glyph_mode_toolbar = *find_descendant_of_type_named<GUI::Toolbar>("glyph_mode_toolbar");
auto& glyph_transform_toolbar = *find_descendant_of_type_named<GUI::Toolbar>("glyph_transform_toolbar");
auto& glyph_map_container = *find_descendant_of_type_named<GUI::Widget>("glyph_map_container"); auto& glyph_map_container = *find_descendant_of_type_named<GUI::Widget>("glyph_map_container");
auto& move_glyph_button = *find_descendant_of_type_named<GUI::Button>("move_glyph_button");
auto& rotate_90_button = *find_descendant_of_type_named<GUI::Button>("rotate_90");
auto& flip_vertical_button = *find_descendant_of_type_named<GUI::Button>("flip_vertical");
auto& flip_horizontal_button = *find_descendant_of_type_named<GUI::Button>("flip_horizontal");
auto& copy_code_point_button = *find_descendant_of_type_named<GUI::Button>("copy_code_point");
m_statusbar = *find_descendant_of_type_named<GUI::Statusbar>("statusbar"); m_statusbar = *find_descendant_of_type_named<GUI::Statusbar>("statusbar");
m_glyph_editor_container = *find_descendant_of_type_named<GUI::Widget>("glyph_editor_container"); m_glyph_editor_container = *find_descendant_of_type_named<GUI::Widget>("glyph_editor_container");
m_left_column_container = *find_descendant_of_type_named<GUI::Widget>("left_column_container"); m_left_column_container = *find_descendant_of_type_named<GUI::Widget>("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.add_action(*m_scale_fifteen_action);
m_glyph_editor_scale_actions.set_exclusive(true); m_glyph_editor_scale_actions.set_exclusive(true);
move_glyph_button.on_click = [&](auto) { 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&) {
if (move_glyph_button.is_checked()) m_glyph_editor_widget->set_mode(GlyphEditorWidget::Paint);
m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move); });
else m_paint_glyph_action->set_checked(true);
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());
rotate_90_button.on_click = [&](auto) { 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->rotate_90(); m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move);
}; });
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());
flip_vertical_button.on_click = [&](auto) { m_glyph_tool_actions.add_action(*m_move_glyph_action);
m_glyph_editor_widget->flip_vertically(); m_glyph_tool_actions.add_action(*m_paint_glyph_action);
}; m_glyph_tool_actions.set_exclusive(true);
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());
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(); 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; StringBuilder glyph_builder;
glyph_builder.append_code_point(m_glyph_editor_widget->glyph()); glyph_builder.append_code_point(m_glyph_editor_widget->glyph());
GUI::Clipboard::the().set_plain_text(glyph_builder.build()); 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) { GUI::Clipboard::the().on_change = [&](const String& data_type) {
m_paste_action->set_enabled(data_type == "glyph/x-fonteditor"); 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_paste_action);
edit_menu.add_action(*m_delete_action); edit_menu.add_action(*m_delete_action);
edit_menu.add_separator(); 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_previous_glyph_action);
edit_menu.add_action(*m_next_glyph_action); edit_menu.add_action(*m_next_glyph_action);
edit_menu.add_action(*m_go_to_glyph_action); edit_menu.add_action(*m_go_to_glyph_action);

View file

@ -78,6 +78,16 @@ private:
RefPtr<GUI::Action> m_scale_ten_action; RefPtr<GUI::Action> m_scale_ten_action;
RefPtr<GUI::Action> m_scale_fifteen_action; RefPtr<GUI::Action> m_scale_fifteen_action;
GUI::ActionGroup m_glyph_tool_actions;
RefPtr<GUI::Action> m_move_glyph_action;
RefPtr<GUI::Action> m_paint_glyph_action;
RefPtr<GUI::Action> m_flip_horizontal_action;
RefPtr<GUI::Action> m_flip_vertical_action;
RefPtr<GUI::Action> m_rotate_clockwise_action;
RefPtr<GUI::Action> m_rotate_counterclockwise_action;
RefPtr<GUI::Action> m_copy_character_action;
RefPtr<GUI::Statusbar> m_statusbar; RefPtr<GUI::Statusbar> m_statusbar;
RefPtr<GUI::Window> m_font_preview_window; RefPtr<GUI::Window> m_font_preview_window;
RefPtr<GUI::Widget> m_left_column_container; RefPtr<GUI::Widget> m_left_column_container;

View file

@ -31,81 +31,31 @@
} }
@GUI::Widget { @GUI::Widget {
shrink_to_fit: true
layout: @GUI::VerticalBoxLayout { layout: @GUI::VerticalBoxLayout {
} }
@GUI::Widget { @GUI::SpinBox {
shrink_to_fit: true name: "glyph_editor_width_spinbox"
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::Widget { @GUI::CheckBox {
shrink_to_fit: true name: "glyph_editor_present_checkbox"
text: "Present"
focus_policy: "TabFocus"
}
}
layout: @GUI::HorizontalBoxLayout { @GUI::ToolbarContainer {
} name: "glyph_toolbar_container"
@GUI::Button { @GUI::Toolbar {
name: "flip_vertical" name: "glyph_mode_toolbar"
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::Widget { @GUI::Toolbar {
shrink_to_fit: true name: "glyph_transform_toolbar"
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"
}
} }
} }
} }

View file

@ -276,7 +276,7 @@ static Vector<Vector<u8>> glyph_as_matrix(Gfx::GlyphBitmap const& bitmap)
return result; return result;
} }
void GlyphEditorWidget::rotate_90() void GlyphEditorWidget::rotate_90(Direction direction)
{ {
if (on_undo_event) if (on_undo_event)
on_undo_event(); on_undo_event();
@ -286,11 +286,11 @@ void GlyphEditorWidget::rotate_90()
for (int y = 0; y < bitmap.height(); y++) { for (int y = 0; y < bitmap.height(); y++) {
for (int x = 0; x < bitmap.width(); x++) { for (int x = 0; x < bitmap.width(); x++) {
int source_x = y; int source_x = (direction == Counterclockwise) ? max(bitmap.width() - 1 - y, 0) : y;
int source_y = bitmap.width() - 1 - x; int source_y = (direction == Counterclockwise) ? x : bitmap.width() - 1 - x;
bool value = false; bool value = false;
if (source_x < bitmap.width() && source_y < bitmap.height()) { 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); bitmap.set_bit_at(x, y, value);
} }

View file

@ -21,6 +21,11 @@ public:
Move Move
}; };
enum Direction {
Clockwise,
Counterclockwise
};
virtual ~GlyphEditorWidget() override; virtual ~GlyphEditorWidget() override;
void initialize(Gfx::BitmapFont&); void initialize(Gfx::BitmapFont&);
@ -34,7 +39,7 @@ public:
void delete_glyph(); void delete_glyph();
bool is_glyph_empty(); bool is_glyph_empty();
void rotate_90(); void rotate_90(Direction);
void flip_vertically(); void flip_vertically();
void flip_horizontally(); void flip_horizontally();