diff --git a/Userland/Applications/FontEditor/FontEditor.cpp b/Userland/Applications/FontEditor/FontEditor.cpp index 17b4f0532a..d4c0714ade 100644 --- a/Userland/Applications/FontEditor/FontEditor.cpp +++ b/Userland/Applications/FontEditor/FontEditor.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -269,6 +270,53 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr&& }); m_show_metadata_action->set_checked(true); m_show_metadata_action->set_status_tip("Show or hide metadata about the current font"); + 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"), [&](auto&) { + String input; + if (GUI::InputBox::show(window(), input, "Hexadecimal:", "Go to Glyph") == GUI::InputBox::ExecOK && !input.is_empty()) { + int code_point = strtoul(&input[0], nullptr, 16); + code_point = clamp(code_point, 0x0000, 0x10FFFF); + m_glyph_map_widget->set_focus(true); + m_glyph_map_widget->set_selected_glyph(code_point); + m_glyph_map_widget->scroll_to_glyph(code_point); + } + }); + 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"), [&](auto&) { + bool search_wrapped = false; + for (int i = m_glyph_map_widget->selected_glyph() - 1;; --i) { + if (i < 0 && !search_wrapped) { + i = 0x10FFFF; + search_wrapped = true; + } else if (i < 0 && search_wrapped) { + break; + } + if (m_edited_font->raw_glyph_width(i) > 0) { + m_glyph_map_widget->set_focus(true); + m_glyph_map_widget->set_selected_glyph(i); + m_glyph_map_widget->scroll_to_glyph(i); + break; + } + } + }); + 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"), [&](auto&) { + bool search_wrapped = false; + for (int i = m_glyph_map_widget->selected_glyph() + 1;; ++i) { + if (i > 0x10FFFF && !search_wrapped) { + i = 0; + search_wrapped = true; + } else if (i > 0x10FFFF && search_wrapped) { + break; + } + if (m_edited_font->raw_glyph_width(i) > 0) { + m_glyph_map_widget->set_focus(true); + m_glyph_map_widget->set_selected_glyph(i); + m_glyph_map_widget->scroll_to_glyph(i); + break; + } + } + }); + m_next_glyph_action->set_status_tip("Seek the next visible glyph"); toolbar.add_action(*m_new_action); toolbar.add_action(*m_open_action); @@ -283,6 +331,10 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr&& 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); m_scale_five_action = GUI::Action::create_checkable("500%", { Mod_Ctrl, Key_1 }, [&](auto&) { m_glyph_editor_widget->set_scale(5); @@ -525,6 +577,10 @@ void FontEditorWidget::initialize_menubar(GUI::Window& window) 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_previous_glyph_action); + edit_menu.add_action(*m_next_glyph_action); + edit_menu.add_action(*m_go_to_glyph_action); auto& view_menu = window.add_menu("&View"); view_menu.add_action(*m_open_preview_action); diff --git a/Userland/Applications/FontEditor/FontEditor.h b/Userland/Applications/FontEditor/FontEditor.h index d78311e363..a2b25e30d0 100644 --- a/Userland/Applications/FontEditor/FontEditor.h +++ b/Userland/Applications/FontEditor/FontEditor.h @@ -61,6 +61,10 @@ private: RefPtr m_undo_glyph; OwnPtr m_undo_stack; + RefPtr m_go_to_glyph_action; + RefPtr m_previous_glyph_action; + RefPtr m_next_glyph_action; + RefPtr m_open_preview_action; RefPtr m_show_metadata_action;