diff options
author | thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> | 2022-07-04 22:22:06 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-07-06 14:25:30 +0200 |
commit | 9962a744ebd659360222da84a0fd6720907d058b (patch) | |
tree | 05ad204b6f65f62aed2f5790c4d263cae4f5036a | |
parent | 0a62fcfbdfe190945868f19f49a7e34a50b4468a (diff) | |
download | serenity-9962a744ebd659360222da84a0fd6720907d058b.zip |
FontEditor: Improve error propagation during construction
FontEditor now builds its actions, toolbars, models and menus
with fallible methods. Widget assignment from GML is now organized
in order of use.
-rw-r--r-- | Userland/Applications/FontEditor/FontEditor.cpp | 356 | ||||
-rw-r--r-- | Userland/Applications/FontEditor/FontEditor.h | 23 | ||||
-rw-r--r-- | Userland/Applications/FontEditor/main.cpp | 6 |
3 files changed, 217 insertions, 168 deletions
diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp index 5ae381154e..fdc7906296 100644 --- a/Userland/Applications/FontEditor/FontEditor.cpp +++ b/Userland/Applications/FontEditor/FontEditor.cpp @@ -111,38 +111,9 @@ static RefPtr<GUI::Window> create_font_preview_window(FontEditorWidget& editor) return window; } -FontEditorWidget::FontEditorWidget() +ErrorOr<void> FontEditorWidget::create_actions() { - load_from_gml(font_editor_window_gml); - - 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"); - - 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_left_column_container = *find_descendant_of_type_named<GUI::Widget>("left_column_container"); - m_glyph_editor_width_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("glyph_editor_width_spinbox"); - m_glyph_editor_present_checkbox = *find_descendant_of_type_named<GUI::CheckBox>("glyph_editor_present_checkbox"); - m_name_textbox = *find_descendant_of_type_named<GUI::TextBox>("name_textbox"); - m_family_textbox = *find_descendant_of_type_named<GUI::TextBox>("family_textbox"); - m_presentation_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("presentation_spinbox"); - m_weight_combobox = *find_descendant_of_type_named<GUI::ComboBox>("weight_combobox"); - m_slope_combobox = *find_descendant_of_type_named<GUI::ComboBox>("slope_combobox"); - m_spacing_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("spacing_spinbox"); - m_mean_line_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("mean_line_spinbox"); - m_baseline_spinbox = *find_descendant_of_type_named<GUI::SpinBox>("baseline_spinbox"); - m_fixed_width_checkbox = *find_descendant_of_type_named<GUI::CheckBox>("fixed_width_checkbox"); - m_font_metadata_groupbox = *find_descendant_of_type_named<GUI::GroupBox>("font_metadata_groupbox"); - m_unicode_block_listview = *find_descendant_of_type_named<GUI::ListView>("unicode_block_listview"); - m_search_textbox = *find_descendant_of_type_named<GUI::TextBox>("search_textbox"); - m_unicode_block_container = *find_descendant_of_type_named<GUI::Widget>("unicode_block_container"); - - m_glyph_editor_widget = m_glyph_editor_container->add<GlyphEditorWidget>(); - m_glyph_map_widget = glyph_map_container.add<GUI::GlyphMapWidget>(); - - m_new_action = GUI::Action::create("&New Font...", { Mod_Ctrl, Key_N }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/filetype-font.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_new_action = GUI::Action::create("&New Font...", { Mod_Ctrl, Key_N }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/filetype-font.png")), [&](auto&) { if (!request_close()) return; auto new_font_wizard = NewFontDialog::construct(window()); @@ -157,26 +128,27 @@ FontEditorWidget::FontEditorWidget() new_font->set_baseline(metadata.baseline); new_font->set_mean_line(metadata.mean_line); window()->set_modified(true); - initialize({}, move(new_font)); + MUST(initialize({}, move(new_font))); } }); m_new_action->set_status_tip("Create a new font"); + m_open_action = GUI::CommonActions::make_open_action([&](auto&) { if (!request_close()) return; - Optional<String> open_path = GUI::FilePicker::get_open_filepath(window(), {}, "/res/fonts/"); if (!open_path.has_value()) return; - open_file(open_path.value()); }); + m_save_action = GUI::CommonActions::make_save_action([&](auto&) { if (m_path.is_empty()) m_save_as_action->activate(); else save_file(m_path); }); + m_save_as_action = GUI::CommonActions::make_save_as_action([&](auto&) { LexicalPath lexical_path(m_path.is_empty() ? "Untitled.font" : m_path); Optional<String> save_path = GUI::FilePicker::get_save_filepath(window(), lexical_path.title(), lexical_path.extension()); @@ -184,25 +156,37 @@ FontEditorWidget::FontEditorWidget() return; save_file(save_path.value()); }); + m_cut_action = GUI::CommonActions::make_cut_action([&](auto&) { cut_selected_glyphs(); }); + m_copy_action = GUI::CommonActions::make_copy_action([&](auto&) { copy_selected_glyphs(); }); + m_paste_action = GUI::CommonActions::make_paste_action([&](auto&) { paste_glyphs(); }); m_paste_action->set_enabled(GUI::Clipboard::the().fetch_mime_type() == "glyph/x-fonteditor"); + + GUI::Clipboard::the().on_change = [&](String const& data_type) { + m_paste_action->set_enabled(data_type == "glyph/x-fonteditor"); + }; + m_delete_action = GUI::CommonActions::make_delete_action([this](auto&) { delete_selected_glyphs(); }); + m_undo_action = GUI::CommonActions::make_undo_action([&](auto&) { undo(); }); + m_undo_action->set_enabled(false); + m_redo_action = GUI::CommonActions::make_redo_action([&](auto&) { redo(); }); + m_redo_action->set_enabled(false); m_select_all_action = GUI::CommonActions::make_select_all_action([this](auto&) { m_glyph_map_widget->set_selection(m_range.first, m_range.last - m_range.first + 1); @@ -239,7 +223,7 @@ FontEditorWidget::FontEditorWidget() m_show_unicode_blocks_action->set_checked(show_unicode_blocks); m_show_unicode_blocks_action->set_status_tip("Show or hide the Unicode block list"); - m_go_to_glyph_action = GUI::Action::create("&Go to Glyph...", { Mod_Ctrl, Key_G }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-to.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_go_to_glyph_action = GUI::Action::create("&Go to Glyph...", { Mod_Ctrl, Key_G }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-to.png")), [&](auto&) { String input; if (GUI::InputBox::show(window(), input, "Hexadecimal:", "Go to glyph") == GUI::InputBox::ExecResult::OK && !input.is_empty()) { auto maybe_code_point = AK::StringUtils::convert_to_uint_from_hex(input); @@ -253,35 +237,19 @@ FontEditorWidget::FontEditorWidget() } }); m_go_to_glyph_action->set_status_tip("Go to the specified code point"); - m_previous_glyph_action = GUI::Action::create("Pre&vious Glyph", { Mod_Alt, Key_Left }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + + m_previous_glyph_action = GUI::Action::create("Pre&vious Glyph", { Mod_Alt, Key_Left }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png")), [&](auto&) { m_glyph_map_widget->select_previous_existing_glyph(); }); m_previous_glyph_action->set_status_tip("Seek the previous visible glyph"); - m_next_glyph_action = GUI::Action::create("&Next Glyph", { Mod_Alt, Key_Right }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + + m_next_glyph_action = GUI::Action::create("&Next Glyph", { Mod_Alt, Key_Right }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png")), [&](auto&) { m_glyph_map_widget->select_next_existing_glyph(); }); m_next_glyph_action->set_status_tip("Seek the next visible glyph"); - toolbar.add_action(*m_new_action); - toolbar.add_action(*m_open_action); - toolbar.add_action(*m_save_action); - toolbar.add_separator(); - toolbar.add_action(*m_cut_action); - toolbar.add_action(*m_copy_action); - toolbar.add_action(*m_paste_action); - toolbar.add_action(*m_delete_action); - toolbar.add_separator(); - toolbar.add_action(*m_undo_action); - toolbar.add_action(*m_redo_action); - toolbar.add_separator(); - toolbar.add_action(*m_open_preview_action); - toolbar.add_separator(); - toolbar.add_action(*m_previous_glyph_action); - toolbar.add_action(*m_next_glyph_action); - toolbar.add_action(*m_go_to_glyph_action); - i32 scale = Config::read_i32("FontEditor", "GlyphEditor", "Scale", 10); - + set_scale(scale); m_scale_five_action = GUI::Action::create_checkable("500%", { Mod_Ctrl, Key_1 }, [this](auto&) { set_scale_and_save(5); }); @@ -303,22 +271,19 @@ FontEditorWidget::FontEditorWidget() m_glyph_editor_scale_actions.add_action(*m_scale_fifteen_action); m_glyph_editor_scale_actions.set_exclusive(true); - 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_paint_glyph_action = GUI::Action::create_checkable("Paint Glyph", { Mod_Ctrl, KeyCode::Key_J }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/pixelpaint/pen.png")), [&](auto&) { m_glyph_editor_widget->set_mode(GlyphEditorWidget::Paint); }); m_paint_glyph_action->set_checked(true); - 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_move_glyph_action = GUI::Action::create_checkable("Move Glyph", { Mod_Ctrl, KeyCode::Key_K }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/selection-move.png")), [&](auto&) { m_glyph_editor_widget->set_mode(GlyphEditorWidget::Move); }); - m_glyph_tool_actions.add_action(*m_move_glyph_action); m_glyph_tool_actions.add_action(*m_paint_glyph_action); + m_glyph_tool_actions.add_action(*m_move_glyph_action); m_glyph_tool_actions.set_exclusive(true); - glyph_mode_toolbar.add_action(*m_paint_glyph_action); - glyph_mode_toolbar.add_action(*m_move_glyph_action); - m_rotate_counterclockwise_action = GUI::CommonActions::make_rotate_counterclockwise_action([&](auto&) { m_glyph_editor_widget->rotate_90(GlyphEditorWidget::Counterclockwise); }); @@ -327,15 +292,15 @@ FontEditorWidget::FontEditorWidget() m_glyph_editor_widget->rotate_90(GlyphEditorWidget::Clockwise); }); - m_flip_horizontal_action = GUI::Action::create("Flip Horizontally", { Mod_Ctrl | Mod_Shift, Key_Q }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_flip_horizontal_action = GUI::Action::create("Flip Horizontally", { Mod_Ctrl | Mod_Shift, Key_Q }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-horizontal.png")), [&](auto&) { m_glyph_editor_widget->flip_horizontally(); }); - m_flip_vertical_action = GUI::Action::create("Flip Vertically", { Mod_Ctrl | Mod_Shift, Key_W }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_flip_vertical_action = GUI::Action::create("Flip Vertically", { Mod_Ctrl | Mod_Shift, Key_W }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-flip-vertical.png")), [&](auto&) { m_glyph_editor_widget->flip_vertically(); }); - m_copy_text_action = GUI::Action::create("Copy as Te&xt", { Mod_Ctrl, Key_T }, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-copy.png").release_value_but_fixme_should_propagate_errors(), [&](auto&) { + m_copy_text_action = GUI::Action::create("Copy as Te&xt", { Mod_Ctrl, Key_T }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/edit-copy.png")), [&](auto&) { StringBuilder builder; auto selection = m_glyph_map_widget->selection().normalized(); for (auto code_point = selection.start(); code_point < selection.start() + selection.size(); ++code_point) { @@ -347,14 +312,105 @@ FontEditorWidget::FontEditorWidget() }); m_copy_text_action->set_status_tip("Copy to clipboard as text"); - 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); + return {}; +} - GUI::Clipboard::the().on_change = [&](String const& data_type) { - m_paste_action->set_enabled(data_type == "glyph/x-fonteditor"); +ErrorOr<void> FontEditorWidget::create_toolbars() +{ + auto& toolbar = *find_descendant_of_type_named<GUI::Toolbar>("toolbar"); + (void)TRY(toolbar.try_add_action(*m_new_action)); + (void)TRY(toolbar.try_add_action(*m_open_action)); + (void)TRY(toolbar.try_add_action(*m_save_action)); + TRY(toolbar.try_add_separator()); + (void)TRY(toolbar.try_add_action(*m_cut_action)); + (void)TRY(toolbar.try_add_action(*m_copy_action)); + (void)TRY(toolbar.try_add_action(*m_paste_action)); + (void)TRY(toolbar.try_add_action(*m_delete_action)); + TRY(toolbar.try_add_separator()); + (void)TRY(toolbar.try_add_action(*m_undo_action)); + (void)TRY(toolbar.try_add_action(*m_redo_action)); + TRY(toolbar.try_add_separator()); + (void)TRY(toolbar.try_add_action(*m_open_preview_action)); + TRY(toolbar.try_add_separator()); + (void)TRY(toolbar.try_add_action(*m_previous_glyph_action)); + (void)TRY(toolbar.try_add_action(*m_next_glyph_action)); + (void)TRY(toolbar.try_add_action(*m_go_to_glyph_action)); + + auto& glyph_transform_toolbar = *find_descendant_of_type_named<GUI::Toolbar>("glyph_transform_toolbar"); + (void)TRY(glyph_transform_toolbar.try_add_action(*m_flip_horizontal_action)); + (void)TRY(glyph_transform_toolbar.try_add_action(*m_flip_vertical_action)); + (void)TRY(glyph_transform_toolbar.try_add_action(*m_rotate_counterclockwise_action)); + (void)TRY(glyph_transform_toolbar.try_add_action(*m_rotate_clockwise_action)); + + auto& glyph_mode_toolbar = *find_descendant_of_type_named<GUI::Toolbar>("glyph_mode_toolbar"); + (void)TRY(glyph_mode_toolbar.try_add_action(*m_paint_glyph_action)); + (void)TRY(glyph_mode_toolbar.try_add_action(*m_move_glyph_action)); + + return {}; +} + +ErrorOr<void> FontEditorWidget::create_models() +{ + for (auto& it : Gfx::font_slope_names) + TRY(m_font_slope_list.try_append(it.name)); + m_slope_combobox->set_model(GUI::ItemListModel<String>::create(m_font_slope_list)); + + for (auto& it : Gfx::font_weight_names) + TRY(m_font_weight_list.try_append(it.name)); + m_weight_combobox->set_model(GUI::ItemListModel<String>::create(m_font_weight_list)); + + auto unicode_blocks = Unicode::block_display_names(); + TRY(m_unicode_block_list.try_append("Show All")); + for (auto& block : unicode_blocks) + TRY(m_unicode_block_list.try_append(block.display_name)); + + m_unicode_block_model = GUI::ItemListModel<String>::create(m_unicode_block_list); + m_filter_model = TRY(GUI::FilteringProxyModel::create(*m_unicode_block_model)); + m_filter_model->set_filter_term(""); + + m_unicode_block_listview = find_descendant_of_type_named<GUI::ListView>("unicode_block_listview"); + m_unicode_block_listview->on_selection_change = [this, unicode_blocks] { + auto index = m_unicode_block_listview->selection().first(); + auto mapped_index = m_filter_model->map(index); + if (mapped_index.row() > 0) + m_range = unicode_blocks[mapped_index.row() - 1].code_point_range; + else + m_range = { 0x0000, 0x10FFFF }; + m_glyph_map_widget->set_active_range(m_range); }; + m_unicode_block_listview->set_model(m_filter_model); + m_unicode_block_listview->set_activates_on_selection(true); + m_unicode_block_listview->horizontal_scrollbar().set_visible(false); + m_unicode_block_listview->set_cursor(m_unicode_block_model->index(0, 0), GUI::AbstractView::SelectionUpdate::Set); + + return {}; +} + +ErrorOr<void> FontEditorWidget::create_undo_stack() +{ + m_undo_stack = TRY(try_make<GUI::UndoStack>()); + m_undo_stack->on_state_change = [this] { + m_undo_action->set_enabled(m_undo_stack->can_undo()); + m_redo_action->set_enabled(m_undo_stack->can_redo()); + if (m_undo_stack->is_current_modified()) + did_modify_font(); + }; + + return {}; +} + +FontEditorWidget::FontEditorWidget() +{ + load_from_gml(font_editor_window_gml); + + m_font_metadata_groupbox = find_descendant_of_type_named<GUI::GroupBox>("font_metadata_groupbox"); + m_unicode_block_container = find_descendant_of_type_named<GUI::Widget>("unicode_block_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"); + + auto& glyph_map_container = *find_descendant_of_type_named<GUI::Widget>("glyph_map_container"); + m_glyph_editor_widget = m_glyph_editor_container->add<GlyphEditorWidget>(); + m_glyph_map_widget = glyph_map_container.add<GUI::GlyphMapWidget>(); m_glyph_editor_widget->on_glyph_altered = [this](int glyph) { m_glyph_map_widget->update_glyph(glyph); @@ -366,6 +422,8 @@ FontEditorWidget::FontEditorWidget() reset_selection_and_push_undo(); }; + m_glyph_editor_width_spinbox = find_descendant_of_type_named<GUI::SpinBox>("glyph_editor_width_spinbox"); + m_glyph_editor_present_checkbox = find_descendant_of_type_named<GUI::CheckBox>("glyph_editor_present_checkbox"); m_glyph_map_widget->on_active_glyph_changed = [this](int glyph) { if (m_undo_selection) { auto selection = m_glyph_map_widget->selection().normalized(); @@ -397,16 +455,19 @@ FontEditorWidget::FontEditorWidget() m_context_menu->popup(event.screen_position()); }; + m_name_textbox = find_descendant_of_type_named<GUI::TextBox>("name_textbox"); m_name_textbox->on_change = [&] { m_edited_font->set_name(m_name_textbox->text()); did_modify_font(); }; + m_family_textbox = find_descendant_of_type_named<GUI::TextBox>("family_textbox"); m_family_textbox->on_change = [&] { m_edited_font->set_family(m_family_textbox->text()); did_modify_font(); }; + m_fixed_width_checkbox = find_descendant_of_type_named<GUI::CheckBox>("fixed_width_checkbox"); m_fixed_width_checkbox->on_checked = [this](bool checked) { m_edited_font->set_fixed_width(checked); auto glyph_width = m_edited_font->raw_glyph_width(m_glyph_map_widget->active_glyph()); @@ -439,34 +500,33 @@ FontEditorWidget::FontEditorWidget() did_modify_font(); }; + m_weight_combobox = find_descendant_of_type_named<GUI::ComboBox>("weight_combobox"); m_weight_combobox->on_change = [this](auto&, auto&) { m_edited_font->set_weight(Gfx::name_to_weight(m_weight_combobox->text())); did_modify_font(); }; - for (auto& it : Gfx::font_weight_names) - m_font_weight_list.append(it.name); - m_weight_combobox->set_model(*GUI::ItemListModel<String>::create(m_font_weight_list)); + m_slope_combobox = find_descendant_of_type_named<GUI::ComboBox>("slope_combobox"); m_slope_combobox->on_change = [this](auto&, auto&) { m_edited_font->set_slope(Gfx::name_to_slope(m_slope_combobox->text())); did_modify_font(); }; - for (auto& it : Gfx::font_slope_names) - m_font_slope_list.append(it.name); - m_slope_combobox->set_model(*GUI::ItemListModel<String>::create(m_font_slope_list)); + m_presentation_spinbox = find_descendant_of_type_named<GUI::SpinBox>("presentation_spinbox"); m_presentation_spinbox->on_change = [this](int value) { m_edited_font->set_presentation_size(value); update_preview(); did_modify_font(); }; + m_spacing_spinbox = find_descendant_of_type_named<GUI::SpinBox>("spacing_spinbox"); m_spacing_spinbox->on_change = [this](int value) { m_edited_font->set_glyph_spacing(value); update_preview(); did_modify_font(); }; + m_baseline_spinbox = find_descendant_of_type_named<GUI::SpinBox>("baseline_spinbox"); m_baseline_spinbox->on_change = [this](int value) { m_edited_font->set_baseline(value); m_glyph_editor_widget->update(); @@ -474,6 +534,7 @@ FontEditorWidget::FontEditorWidget() did_modify_font(); }; + m_mean_line_spinbox = find_descendant_of_type_named<GUI::SpinBox>("mean_line_spinbox"); m_mean_line_spinbox->on_change = [this](int value) { m_edited_font->set_mean_line(value); m_glyph_editor_widget->update(); @@ -481,29 +542,7 @@ FontEditorWidget::FontEditorWidget() did_modify_font(); }; - auto unicode_blocks = Unicode::block_display_names(); - m_unicode_block_list.append("Show All"); - for (auto& block : unicode_blocks) - m_unicode_block_list.append(block.display_name); - - m_unicode_block_model = GUI::ItemListModel<String>::create(m_unicode_block_list); - m_filter_model = MUST(GUI::FilteringProxyModel::create(*m_unicode_block_model)); - m_filter_model->set_filter_term(""); - - m_unicode_block_listview->on_selection_change = [this, unicode_blocks] { - auto index = m_unicode_block_listview->selection().first(); - auto mapped_index = m_filter_model->map(index); - if (mapped_index.row() > 0) - m_range = unicode_blocks[mapped_index.row() - 1].code_point_range; - else - m_range = { 0x0000, 0x10FFFF }; - m_glyph_map_widget->set_active_range(m_range); - }; - m_unicode_block_listview->set_model(*m_filter_model); - m_unicode_block_listview->set_activates_on_selection(true); - m_unicode_block_listview->horizontal_scrollbar().set_visible(false); - m_unicode_block_listview->set_cursor(m_unicode_block_model->index(0, 0), GUI::AbstractView::SelectionUpdate::Set); - + m_search_textbox = find_descendant_of_type_named<GUI::TextBox>("search_textbox"); m_search_textbox->on_return_pressed = [this] { if (!m_unicode_block_listview->selection().is_empty()) m_unicode_block_listview->activate_selected(); @@ -523,6 +562,7 @@ FontEditorWidget::FontEditorWidget() m_unicode_block_listview->set_cursor(m_filter_model->index(0, 0), GUI::AbstractView::SelectionUpdate::Set); }; + m_statusbar = find_descendant_of_type_named<GUI::Statusbar>("statusbar"); GUI::Application::the()->on_action_enter = [this](GUI::Action& action) { auto text = action.status_tip(); if (text.is_empty()) @@ -533,14 +573,12 @@ FontEditorWidget::FontEditorWidget() GUI::Application::the()->on_action_leave = [this](GUI::Action&) { m_statusbar->set_override_text({}); }; - - set_scale(scale); } -void FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&& edited_font) +ErrorOr<void> FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&& edited_font) { if (m_edited_font == edited_font) - return; + return {}; m_path = path; m_edited_font = edited_font; @@ -584,6 +622,11 @@ void FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&& i++; } + m_undo_selection = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UndoSelection(m_glyph_map_widget->selection().start(), m_glyph_map_widget->selection().size(), m_glyph_map_widget->active_glyph(), *m_edited_font))); + m_undo_stack->clear(); + + update_statusbar(); + deferred_invoke([this] { auto glyph = m_glyph_map_widget->active_glyph(); m_glyph_map_widget->set_focus(true); @@ -592,71 +635,62 @@ void FontEditorWidget::initialize(String const& path, RefPtr<Gfx::BitmapFont>&& update_title(); }); - m_undo_stack = make<GUI::UndoStack>(); - m_undo_selection = adopt_ref(*new UndoSelection(m_glyph_map_widget->selection().start(), m_glyph_map_widget->selection().size(), m_glyph_map_widget->active_glyph(), *m_edited_font)); - - m_undo_stack->on_state_change = [this] { - m_undo_action->set_enabled(m_undo_stack->can_undo()); - m_redo_action->set_enabled(m_undo_stack->can_redo()); - did_modify_font(); - }; - m_undo_action->set_enabled(false); - m_redo_action->set_enabled(false); - - update_statusbar(); - if (on_initialize) on_initialize(); + + return {}; } -void FontEditorWidget::initialize_menubar(GUI::Window& window) +ErrorOr<void> FontEditorWidget::initialize_menubar(GUI::Window& window) { - auto& file_menu = window.add_menu("&File"); - file_menu.add_action(*m_new_action); - file_menu.add_action(*m_open_action); - file_menu.add_action(*m_save_action); - file_menu.add_action(*m_save_as_action); - file_menu.add_separator(); - file_menu.add_action(GUI::CommonActions::make_quit_action([this](auto&) { + auto file_menu = TRY(window.try_add_menu("&File")); + TRY(file_menu->try_add_action(*m_new_action)); + TRY(file_menu->try_add_action(*m_open_action)); + TRY(file_menu->try_add_action(*m_save_action)); + TRY(file_menu->try_add_action(*m_save_as_action)); + TRY(file_menu->try_add_separator()); + TRY(file_menu->try_add_action(GUI::CommonActions::make_quit_action([this](auto&) { if (!request_close()) return; GUI::Application::the()->quit(); - })); - - auto& edit_menu = window.add_menu("&Edit"); - edit_menu.add_action(*m_undo_action); - edit_menu.add_action(*m_redo_action); - edit_menu.add_separator(); - edit_menu.add_action(*m_cut_action); - edit_menu.add_action(*m_copy_action); - edit_menu.add_action(*m_paste_action); - edit_menu.add_action(*m_delete_action); - edit_menu.add_separator(); - edit_menu.add_action(*m_select_all_action); - edit_menu.add_separator(); - edit_menu.add_action(*m_copy_text_action); - - auto& go_menu = window.add_menu("&Go"); - go_menu.add_action(*m_previous_glyph_action); - go_menu.add_action(*m_next_glyph_action); - go_menu.add_action(*m_go_to_glyph_action); - - auto& view_menu = window.add_menu("&View"); - view_menu.add_action(*m_open_preview_action); - view_menu.add_separator(); - view_menu.add_action(*m_show_metadata_action); - view_menu.add_action(*m_show_unicode_blocks_action); - view_menu.add_separator(); - auto& scale_menu = view_menu.add_submenu("&Scale"); - scale_menu.add_action(*m_scale_five_action); - scale_menu.add_action(*m_scale_ten_action); - scale_menu.add_action(*m_scale_fifteen_action); - - auto& help_menu = window.add_menu("&Help"); - help_menu.add_action(GUI::CommonActions::make_help_action([](auto&) { + }))); + + auto edit_menu = TRY(window.try_add_menu("&Edit")); + TRY(edit_menu->try_add_action(*m_undo_action)); + TRY(edit_menu->try_add_action(*m_redo_action)); + TRY(edit_menu->try_add_separator()); + TRY(edit_menu->try_add_action(*m_cut_action)); + TRY(edit_menu->try_add_action(*m_copy_action)); + TRY(edit_menu->try_add_action(*m_paste_action)); + TRY(edit_menu->try_add_action(*m_delete_action)); + TRY(edit_menu->try_add_separator()); + TRY(edit_menu->try_add_action(*m_select_all_action)); + TRY(edit_menu->try_add_separator()); + TRY(edit_menu->try_add_action(*m_copy_text_action)); + + auto go_menu = TRY(window.try_add_menu("&Go")); + TRY(go_menu->try_add_action(*m_previous_glyph_action)); + TRY(go_menu->try_add_action(*m_next_glyph_action)); + TRY(go_menu->try_add_action(*m_go_to_glyph_action)); + + auto view_menu = TRY(window.try_add_menu("&View")); + TRY(view_menu->try_add_action(*m_open_preview_action)); + TRY(view_menu->try_add_separator()); + TRY(view_menu->try_add_action(*m_show_metadata_action)); + TRY(view_menu->try_add_action(*m_show_unicode_blocks_action)); + TRY(view_menu->try_add_separator()); + auto scale_menu = TRY(view_menu->try_add_submenu("&Scale")); + TRY(scale_menu->try_add_action(*m_scale_five_action)); + TRY(scale_menu->try_add_action(*m_scale_ten_action)); + TRY(scale_menu->try_add_action(*m_scale_fifteen_action)); + + auto help_menu = TRY(window.try_add_menu("&Help")); + TRY(help_menu->try_add_action(GUI::CommonActions::make_help_action([](auto&) { Desktop::Launcher::open(URL::create_with_file_protocol("/usr/share/man/man1/FontEditor.md"), "/bin/Help"); - })); - help_menu.add_action(GUI::CommonActions::make_about_action("Font Editor", GUI::Icon::default_icon("app-font-editor"), &window)); + }))); + TRY(help_menu->try_add_action(GUI::CommonActions::make_about_action("Font Editor", TRY(GUI::Icon::try_create_default_icon("app-font-editor")), &window))); + + return {}; } bool FontEditorWidget::save_file(String const& path) @@ -700,7 +734,7 @@ bool FontEditorWidget::open_file(String const& path) } auto new_font = bitmap_font->unmasked_character_set(); window()->set_modified(false); - initialize(path, move(new_font)); + MUST(initialize(path, move(new_font))); return true; } diff --git a/Userland/Applications/FontEditor/FontEditor.h b/Userland/Applications/FontEditor/FontEditor.h index f169ab7dc2..a23eb844c7 100644 --- a/Userland/Applications/FontEditor/FontEditor.h +++ b/Userland/Applications/FontEditor/FontEditor.h @@ -17,12 +17,24 @@ class GlyphEditorWidget; -class FontEditorWidget final - : public GUI::Widget { +class FontEditorWidget final : public GUI::Widget { C_OBJECT(FontEditorWidget) public: + static ErrorOr<NonnullRefPtr<FontEditorWidget>> try_create() + { + NonnullRefPtr<FontEditorWidget> font_editor = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) FontEditorWidget())); + TRY(font_editor->create_actions()); + TRY(font_editor->create_models()); + TRY(font_editor->create_toolbars()); + TRY(font_editor->create_undo_stack()); + return font_editor; + } + virtual ~FontEditorWidget() override = default; + ErrorOr<void> initialize(String const& path, RefPtr<Gfx::BitmapFont>&&); + ErrorOr<void> initialize_menubar(GUI::Window&); + bool open_file(String const&); bool save_file(String const&); bool request_close(); @@ -30,8 +42,6 @@ public: String const& path() { return m_path; } Gfx::BitmapFont const& edited_font() { return *m_edited_font; } - void initialize(String const& path, RefPtr<Gfx::BitmapFont>&&); - void initialize_menubar(GUI::Window&); bool is_showing_font_metadata() { return m_font_metadata; } void set_show_font_metadata(bool); @@ -44,6 +54,11 @@ public: private: FontEditorWidget(); + ErrorOr<void> create_actions(); + ErrorOr<void> create_models(); + ErrorOr<void> create_toolbars(); + ErrorOr<void> create_undo_stack(); + virtual void drop_event(GUI::DropEvent&) override; void undo(); diff --git a/Userland/Applications/FontEditor/main.cpp b/Userland/Applications/FontEditor/main.cpp index b05deab9a2..07cfa314fa 100644 --- a/Userland/Applications/FontEditor/main.cpp +++ b/Userland/Applications/FontEditor/main.cpp @@ -36,14 +36,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) args_parser.add_positional_argument(path, "The font file for editing.", "file", Core::ArgsParser::Required::No); args_parser.parse(arguments); - auto app_icon = GUI::Icon::default_icon("app-font-editor"); + auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-font-editor")); auto window = TRY(GUI::Window::try_create()); window->set_icon(app_icon.bitmap_for_size(16)); window->resize(640, 470); auto font_editor = TRY(window->try_set_main_widget<FontEditorWidget>()); - font_editor->initialize_menubar(*window); + TRY(font_editor->initialize_menubar(*window)); if (path) { auto success = font_editor->open_file(path); @@ -51,7 +51,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) return 1; } else { auto mutable_font = static_ptr_cast<Gfx::BitmapFont>(Gfx::FontDatabase::default_font().clone())->unmasked_character_set(); - font_editor->initialize({}, move(mutable_font)); + TRY(font_editor->initialize({}, move(mutable_font))); } window->on_close_request = [&]() -> GUI::Window::CloseRequestDecision { |