FontEditor: Add move glyph tool

When toggled on, glyphs can now be repositioned within the glyph
editor by dragging the mouse
This commit is contained in:
thankyouverycool 2021-04-22 14:15:21 -04:00 committed by Andreas Kling
parent 44cd121e30
commit bada590b91
Notes: sideshowbarker 2024-07-18 19:12:39 +09:00
5 changed files with 101 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

View File

@ -108,6 +108,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
auto& toolbar = *find_descendant_of_type_named<GUI::Toolbar>("toolbar");
auto& statusbar = *find_descendant_of_type_named<GUI::Statusbar>("statusbar");
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");
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");
@ -299,6 +300,15 @@ FontEditorWidget::FontEditorWidget(const String& path, RefPtr<Gfx::BitmapFont>&&
m_glyph_editor_scale_actions.add_action(*m_scale_fifteen_action);
m_glyph_editor_scale_actions.set_exclusive(true);
move_glyph_button.on_click = [&] {
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_checkable(true);
move_glyph_button.set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/selection-move.png"));
GUI::Clipboard::the().on_change = [&](const String& data_type) {
m_paste_action->set_enabled(data_type == "glyph/x-fonteditor");
};

View File

@ -31,13 +31,24 @@
layout: @GUI::VerticalBoxLayout {
}
@GUI::SpinBox {
name: "glyph_editor_width_spinbox"
}
@GUI::Widget {
layout: @GUI::HorizontalBoxLayout {
}
@GUI::CheckBox {
name: "glyph_editor_present_checkbox"
text: "Glyph Present"
@GUI::SpinBox {
name: "glyph_editor_width_spinbox"
}
@GUI::CheckBox {
name: "glyph_editor_present_checkbox"
text: "Show"
}
@GUI::Button {
name: "move_glyph_button"
fixed_width: 22
button_style: "Coolbar"
}
}
}

View File

@ -11,6 +11,9 @@
#include <LibGfx/BitmapFont.h>
#include <LibGfx/Palette.h>
static int x_offset;
static int y_offset;
GlyphEditorWidget::~GlyphEditorWidget()
{
}
@ -153,13 +156,49 @@ void GlyphEditorWidget::paint_event(GUI::PaintEvent& event)
void GlyphEditorWidget::mousedown_event(GUI::MouseEvent& event)
{
draw_at_mouse(event);
if (!(font().raw_glyph_width(m_glyph) > 0))
return;
if (on_undo_event)
on_undo_event(false);
if (mode() == Paint) {
draw_at_mouse(event);
} else {
memset(m_movable_bits, 0, sizeof(m_movable_bits));
auto bitmap = font().glyph(m_glyph).glyph_bitmap();
for (int x = s_max_width; x < s_max_width + bitmap.width(); x++)
for (int y = s_max_height; y < s_max_height + bitmap.height(); y++)
m_movable_bits[x][y] = bitmap.bit_at(x - s_max_width, y - s_max_height);
x_offset = (event.x() - 1) / m_scale;
y_offset = (event.y() - 1) / m_scale;
move_at_mouse(event);
}
}
void GlyphEditorWidget::mouseup_event(GUI::MouseEvent&)
{
if (on_undo_event)
on_undo_event(true);
}
void GlyphEditorWidget::mousemove_event(GUI::MouseEvent& event)
{
if (event.buttons() & (GUI::MouseButton::Left | GUI::MouseButton::Right))
if (!(font().raw_glyph_width(m_glyph) > 0))
return;
if (!(event.buttons() & (GUI::MouseButton::Left | GUI::MouseButton::Right)))
return;
if (mode() == Paint)
draw_at_mouse(event);
else
move_at_mouse(event);
}
void GlyphEditorWidget::enter_event(Core::Event&)
{
if (mode() == Move)
set_override_cursor(Gfx::StandardCursor::Move);
else
set_override_cursor(Gfx::StandardCursor::None);
}
void GlyphEditorWidget::draw_at_mouse(const GUI::MouseEvent& event)
@ -183,6 +222,23 @@ void GlyphEditorWidget::draw_at_mouse(const GUI::MouseEvent& event)
update();
}
void GlyphEditorWidget::move_at_mouse(const GUI::MouseEvent& event)
{
int x_delta = ((event.x() - 1) / m_scale) - x_offset;
int y_delta = ((event.y() - 1) / m_scale) - y_offset;
auto bitmap = font().glyph(m_glyph).glyph_bitmap();
if (abs(x_delta) > bitmap.width() || abs(y_delta) > bitmap.height())
return;
for (int x = 0; x < bitmap.width(); x++) {
for (int y = 0; y < bitmap.height(); y++) {
bitmap.set_bit_at(x, y, m_movable_bits[s_max_width + x - x_delta][s_max_height + y - y_delta]);
}
}
if (on_glyph_altered)
on_glyph_altered(m_glyph);
update();
}
int GlyphEditorWidget::preferred_width() const
{
return frame_thickness() * 2 + font().max_glyph_width() * m_scale - 1;

View File

@ -10,9 +10,17 @@
#include <LibGUI/Frame.h>
#include <LibGfx/BitmapFont.h>
static constexpr int s_max_width = 32;
static constexpr int s_max_height = 36;
class GlyphEditorWidget final : public GUI::Frame {
C_OBJECT(GlyphEditorWidget)
public:
enum Mode {
Paint,
Move
};
virtual ~GlyphEditorWidget() override;
void initialize(Gfx::BitmapFont&);
@ -34,6 +42,9 @@ public:
int scale() const { return m_scale; }
void set_scale(int scale);
Mode mode() const { return m_mode; }
void set_mode(Mode mode) { m_mode = mode; }
Function<void(int)> on_glyph_altered;
Function<void(bool finalize)> on_undo_event;
@ -42,10 +53,15 @@ private:
virtual void paint_event(GUI::PaintEvent&) override;
virtual void mousedown_event(GUI::MouseEvent&) override;
virtual void mousemove_event(GUI::MouseEvent&) override;
virtual void mouseup_event(GUI::MouseEvent&) override;
virtual void enter_event(Core::Event&) override;
void draw_at_mouse(const GUI::MouseEvent&);
void move_at_mouse(const GUI::MouseEvent&);
RefPtr<Gfx::BitmapFont> m_font;
int m_glyph { 0 };
int m_scale { 10 };
u8 m_movable_bits[s_max_width * 3][s_max_height * 3] = {};
Mode m_mode { Paint };
};