Jelajahi Sumber

FontEditor: Add new tools to navigate code points

Visible glyphs can now be cycled through, or a code point specified
and jumped to directly.
thankyouverycool 3 tahun lalu
induk
melakukan
dc65535b7c

+ 56 - 0
Userland/Applications/FontEditor/FontEditor.cpp

@@ -22,6 +22,7 @@
 #include <LibGUI/FilePicker.h>
 #include <LibGUI/FilePicker.h>
 #include <LibGUI/FontPickerWeightModel.h>
 #include <LibGUI/FontPickerWeightModel.h>
 #include <LibGUI/GroupBox.h>
 #include <LibGUI/GroupBox.h>
+#include <LibGUI/InputBox.h>
 #include <LibGUI/Label.h>
 #include <LibGUI/Label.h>
 #include <LibGUI/Menu.h>
 #include <LibGUI/Menu.h>
 #include <LibGUI/Menubar.h>
 #include <LibGUI/Menubar.h>
@@ -269,6 +270,53 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
     });
     });
     m_show_metadata_action->set_checked(true);
     m_show_metadata_action->set_checked(true);
     m_show_metadata_action->set_status_tip("Show or hide metadata about the current font");
     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_new_action);
     toolbar.add_action(*m_open_action);
     toolbar.add_action(*m_open_action);
@@ -283,6 +331,10 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
     toolbar.add_action(*m_redo_action);
     toolbar.add_action(*m_redo_action);
     toolbar.add_separator();
     toolbar.add_separator();
     toolbar.add_action(*m_open_preview_action);
     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_scale_five_action = GUI::Action::create_checkable("500%", { Mod_Ctrl, Key_1 }, [&](auto&) {
         m_glyph_editor_widget->set_scale(5);
         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_copy_action);
     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_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");
     auto& view_menu = window.add_menu("&View");
     view_menu.add_action(*m_open_preview_action);
     view_menu.add_action(*m_open_preview_action);

+ 4 - 0
Userland/Applications/FontEditor/FontEditor.h

@@ -61,6 +61,10 @@ private:
     RefPtr<UndoGlyph> m_undo_glyph;
     RefPtr<UndoGlyph> m_undo_glyph;
     OwnPtr<GUI::UndoStack> m_undo_stack;
     OwnPtr<GUI::UndoStack> m_undo_stack;
 
 
+    RefPtr<GUI::Action> m_go_to_glyph_action;
+    RefPtr<GUI::Action> m_previous_glyph_action;
+    RefPtr<GUI::Action> m_next_glyph_action;
+
     RefPtr<GUI::Action> m_open_preview_action;
     RefPtr<GUI::Action> m_open_preview_action;
     RefPtr<GUI::Action> m_show_metadata_action;
     RefPtr<GUI::Action> m_show_metadata_action;