diff --git a/Applications/FontEditor/FontEditor.cpp b/Applications/FontEditor/FontEditor.cpp index dc23c23ca4..86f39c5c31 100644 --- a/Applications/FontEditor/FontEditor.cpp +++ b/Applications/FontEditor/FontEditor.cpp @@ -6,6 +6,7 @@ #include #include #include +#include FontEditorWidget::FontEditorWidget(const String& path, RetainPtr&& edited_font, GWidget* parent) : GWidget(parent) @@ -62,8 +63,9 @@ FontEditorWidget::FontEditorWidget(const String& path, RetainPtr&& edited_ info_label->set_text_alignment(TextAlignment::CenterLeft); info_label->set_relative_rect({ 5, 110, 100, 20 }); - auto* width_textbox = new GTextBox(this); - width_textbox->set_relative_rect({ 5, 135, 100, 20 }); + auto* width_spinbox = new GSpinBox(this); + width_spinbox->set_range(0, 32); + width_spinbox->set_relative_rect({ 5, 135, 100, 20 }); auto* demo_label_1 = new GLabel(this); demo_label_1->set_font(m_edited_font.copy_ref()); @@ -85,27 +87,23 @@ FontEditorWidget::FontEditorWidget(const String& path, RetainPtr&& edited_ update_demo(); }; - m_glyph_map_widget->on_glyph_selected = [this, info_label, width_textbox] (byte glyph) { + m_glyph_map_widget->on_glyph_selected = [this, info_label, width_spinbox] (byte glyph) { m_glyph_editor_widget->set_glyph(glyph); - width_textbox->set_text(String::format("%u", m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph()))); + width_spinbox->set_value(m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph())); info_label->set_text(String::format("0x%b (%c)", glyph, glyph)); }; - fixed_width_checkbox->on_change = [this, width_textbox, update_demo] (GCheckBox&, bool is_checked) { + fixed_width_checkbox->on_change = [this, width_spinbox, update_demo] (GCheckBox&, bool is_checked) { m_edited_font->set_fixed_width(is_checked); - width_textbox->set_text(String::format("%u", m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph()))); + width_spinbox->set_value(m_edited_font->glyph_width(m_glyph_map_widget->selected_glyph())); m_glyph_editor_widget->update(); update_demo(); }; - width_textbox->on_change = [this, update_demo] (GTextBox& textbox) { - bool ok; - unsigned width = textbox.text().to_uint(ok); - if (ok) { - m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), width); - m_glyph_editor_widget->update(); - update_demo(); - } + width_spinbox->on_change = [this, update_demo] (int value) { + m_edited_font->set_glyph_width(m_glyph_map_widget->selected_glyph(), value); + m_glyph_editor_widget->update(); + update_demo(); }; m_glyph_map_widget->set_selected_glyph('A'); diff --git a/LibGUI/GSpinBox.cpp b/LibGUI/GSpinBox.cpp new file mode 100644 index 0000000000..1f00d1bbe9 --- /dev/null +++ b/LibGUI/GSpinBox.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +GSpinBox::GSpinBox(GWidget* parent) + : GWidget(parent) +{ + m_editor = new GTextEditor(GTextEditor::Type::SingleLine, this); + m_editor->on_change = [this] { + bool ok; + int value = m_editor->text().to_uint(ok); + if (ok) + set_value(value); + else + m_editor->set_text(String::format("%d", m_value)); + }; + m_increment_button = new GButton(this); + m_increment_button->set_caption("+"); + m_increment_button->on_click = [this] (GButton&) { set_value(m_value + 1); }; + m_decrement_button = new GButton(this); + m_decrement_button->set_caption("-"); + m_decrement_button->on_click = [this] (GButton&) { set_value(m_value - 1); }; +} + +GSpinBox::~GSpinBox() +{ +} + +void GSpinBox::set_value(int value) +{ + if (value < m_min) + value = m_min; + if (value > m_max) + value = m_max; + if (m_value == value) + return; + m_value = value; + m_editor->set_text(String::format("%d", value)); + update(); + if (on_change) + on_change(value); +} + +void GSpinBox::set_range(int min, int max) +{ + ASSERT(min <= max); + if (m_min == min && m_max == max) + return; + + m_min = min; + m_max = max; + + int old_value = m_value; + if (m_value < m_min) + m_value = m_min; + if (m_value > m_max) + m_value = m_max; + if (on_change && m_value != old_value) + on_change(m_value); + + update(); +} + +void GSpinBox::resize_event(GResizeEvent& event) +{ + int button_height = event.size().height() / 2; + int button_width = 16; + m_increment_button->set_relative_rect(width() - button_width, 0, button_width, button_height); + m_decrement_button->set_relative_rect(width() - button_width, button_height, button_width, button_height); + m_editor->set_relative_rect(0, 0, width() - button_width, height()); +} diff --git a/LibGUI/GSpinBox.h b/LibGUI/GSpinBox.h new file mode 100644 index 0000000000..67b2e6d116 --- /dev/null +++ b/LibGUI/GSpinBox.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +class GButton; +class GTextEditor; + +class GSpinBox : public GWidget { +public: + GSpinBox(GWidget* parent = nullptr); + virtual ~GSpinBox() override; + + int value() const { return m_value; } + void set_value(int); + + void set_range(int min, int max); + + Function on_change; + +protected: + virtual void resize_event(GResizeEvent&) override; + +private: + GTextEditor* m_editor { nullptr }; + GButton* m_increment_button { nullptr }; + GButton* m_decrement_button { nullptr }; + + int m_min { 0 }; + int m_max { 100 }; + int m_value { 0 }; +}; diff --git a/LibGUI/Makefile b/LibGUI/Makefile index 4053ecf04f..f36ebbedf8 100644 --- a/LibGUI/Makefile +++ b/LibGUI/Makefile @@ -63,6 +63,7 @@ LIBGUI_OBJS = \ GHttpRequest.o \ GHttpResponse.o \ GHttpJob.o \ + GSpinBox.o \ GWindow.o OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)