mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 22:57:34 +00:00
LibGUI: Add a GToolBar class that can be populated with GActions.
The same action can be added to both a menu and a toolbar. Use this to put a toolbar into FileManager. This is pretty neat. :^)
This commit is contained in:
parent
4804609b7e
commit
b704d3d295
24 changed files with 196 additions and 44 deletions
|
@ -1,8 +1,8 @@
|
|||
#include <LibGUI/GAction.h>
|
||||
|
||||
GAction::GAction(const String& text, const String& custom_data, Function<void(const GAction&)> on_activation_callback)
|
||||
: m_text(text)
|
||||
, on_activation(move(on_activation_callback))
|
||||
: on_activation(move(on_activation_callback))
|
||||
, m_text(text)
|
||||
, m_custom_data(custom_data)
|
||||
{
|
||||
}
|
||||
|
@ -12,6 +12,13 @@ GAction::GAction(const String& text, Function<void(const GAction&)> on_activatio
|
|||
{
|
||||
}
|
||||
|
||||
GAction::GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> on_activation_callback)
|
||||
: on_activation(move(on_activation_callback))
|
||||
, m_text(text)
|
||||
, m_icon(move(icon))
|
||||
{
|
||||
}
|
||||
|
||||
GAction::~GAction()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -2,22 +2,41 @@
|
|||
|
||||
#include <AK/AKString.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/RetainPtr.h>
|
||||
#include <SharedGraphics/GraphicsBitmap.h>
|
||||
|
||||
class GAction {
|
||||
class GAction : public Retainable<GAction> {
|
||||
public:
|
||||
GAction(const String& text, Function<void(const GAction&)> = nullptr);
|
||||
GAction(const String& text, const String& custom_data = String(), Function<void(const GAction&)> = nullptr);
|
||||
static RetainPtr<GAction> create(const String& text, Function<void(const GAction&)> callback)
|
||||
{
|
||||
return adopt(*new GAction(text, move(callback)));
|
||||
}
|
||||
static RetainPtr<GAction> create(const String& text, const String& custom_data, Function<void(const GAction&)> callback)
|
||||
{
|
||||
return adopt(*new GAction(text, custom_data, move(callback)));
|
||||
}
|
||||
static RetainPtr<GAction> create(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> callback)
|
||||
{
|
||||
return adopt(*new GAction(text, move(icon), move(callback)));
|
||||
}
|
||||
~GAction();
|
||||
|
||||
String text() const { return m_text; }
|
||||
String custom_data() const { return m_custom_data; }
|
||||
const GraphicsBitmap* icon() const { return m_icon.ptr(); }
|
||||
|
||||
Function<void(GAction&)> on_activation;
|
||||
|
||||
void activate();
|
||||
|
||||
private:
|
||||
GAction(const String& text, Function<void(const GAction&)> = nullptr);
|
||||
GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> = nullptr);
|
||||
GAction(const String& text, const String& custom_data = String(), Function<void(const GAction&)> = nullptr);
|
||||
|
||||
String m_text;
|
||||
String m_custom_data;
|
||||
RetainPtr<GraphicsBitmap> m_icon;
|
||||
};
|
||||
|
||||
|
|
|
@ -52,12 +52,14 @@ void GBoxLayout::run(GWidget& widget)
|
|||
|
||||
Size automatic_size;
|
||||
|
||||
if (m_orientation == Orientation::Horizontal) {
|
||||
automatic_size.set_width(available_size.width() / number_of_entries_with_automatic_size);
|
||||
automatic_size.set_height(widget.height());
|
||||
} else {
|
||||
automatic_size.set_width(widget.width());
|
||||
automatic_size.set_height(available_size.height() / number_of_entries_with_automatic_size);
|
||||
if (number_of_entries_with_automatic_size) {
|
||||
if (m_orientation == Orientation::Horizontal) {
|
||||
automatic_size.set_width(available_size.width() / number_of_entries_with_automatic_size);
|
||||
automatic_size.set_height(widget.height());
|
||||
} else {
|
||||
automatic_size.set_width(widget.width());
|
||||
automatic_size.set_height(available_size.height() / number_of_entries_with_automatic_size);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GBOXLAYOUT_DEBUG
|
||||
|
|
|
@ -29,7 +29,7 @@ GMenu::~GMenu()
|
|||
unrealize_menu();
|
||||
}
|
||||
|
||||
void GMenu::add_action(OwnPtr<GAction>&& action)
|
||||
void GMenu::add_action(RetainPtr<GAction>&& action)
|
||||
{
|
||||
m_items.append(make<GMenuItem>(move(action)));
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
|
||||
GAction* action_at(size_t);
|
||||
|
||||
void add_action(OwnPtr<GAction>&&);
|
||||
void add_action(RetainPtr<GAction>&&);
|
||||
void add_separator();
|
||||
|
||||
Function<void(unsigned)> on_item_activation;
|
||||
|
|
|
@ -6,7 +6,7 @@ GMenuItem::GMenuItem(Type type)
|
|||
{
|
||||
}
|
||||
|
||||
GMenuItem::GMenuItem(OwnPtr<GAction>&& action)
|
||||
GMenuItem::GMenuItem(RetainPtr<GAction>&& action)
|
||||
: m_type(Action)
|
||||
, m_action(move(action))
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ public:
|
|||
enum Type { Invalid, Action, Separator };
|
||||
|
||||
explicit GMenuItem(Type);
|
||||
explicit GMenuItem(OwnPtr<GAction>&&);
|
||||
explicit GMenuItem(RetainPtr<GAction>&&);
|
||||
~GMenuItem();
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
@ -21,6 +21,6 @@ public:
|
|||
private:
|
||||
Type m_type { Invalid };
|
||||
unsigned m_identifier { 0 };
|
||||
OwnPtr<GAction> m_action;
|
||||
RetainPtr<GAction> m_action;
|
||||
};
|
||||
|
||||
|
|
58
LibGUI/GToolBar.cpp
Normal file
58
LibGUI/GToolBar.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <LibGUI/GToolBar.h>
|
||||
#include <LibGUI/GBoxLayout.h>
|
||||
#include <LibGUI/GButton.h>
|
||||
#include <LibGUI/GAction.h>
|
||||
#include <SharedGraphics/Painter.h>
|
||||
|
||||
GToolBar::GToolBar(GWidget* parent)
|
||||
: GWidget(parent)
|
||||
{
|
||||
set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||
set_preferred_size({ 0, 24 });
|
||||
set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
||||
}
|
||||
|
||||
GToolBar::~GToolBar()
|
||||
{
|
||||
}
|
||||
|
||||
void GToolBar::add_action(RetainPtr<GAction>&& action)
|
||||
{
|
||||
ASSERT(action);
|
||||
GAction* raw_action_ptr = action.ptr();
|
||||
auto item = make<Item>();
|
||||
item->type = Item::Action;
|
||||
item->action = move(action);
|
||||
|
||||
auto* button = new GButton(this);
|
||||
if (item->action->icon())
|
||||
button->set_icon(item->action->icon());
|
||||
else
|
||||
button->set_caption(item->action->text());
|
||||
button->on_click = [raw_action_ptr] (const GButton&) {
|
||||
raw_action_ptr->activate();
|
||||
};
|
||||
|
||||
#if 0
|
||||
// FIXME: Gotta fix GBoxLayout for this to work.
|
||||
button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
||||
button->set_preferred_size({ 16, 16 });
|
||||
#endif
|
||||
|
||||
m_items.append(move(item));
|
||||
}
|
||||
|
||||
void GToolBar::add_separator()
|
||||
{
|
||||
auto item = make<Item>();
|
||||
item->type = Item::Separator;
|
||||
m_items.append(move(item));
|
||||
}
|
||||
|
||||
void GToolBar::paint_event(GPaintEvent& event)
|
||||
{
|
||||
Painter painter(*this);
|
||||
painter.set_clip_rect(event.rect());
|
||||
painter.fill_rect({ 0, 0, width(), height() - 1 }, Color::LightGray);
|
||||
painter.draw_line({ 0, rect().bottom() }, { width() - 1, rect().bottom() }, Color::DarkGray);
|
||||
}
|
25
LibGUI/GToolBar.h
Normal file
25
LibGUI/GToolBar.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/GWidget.h>
|
||||
|
||||
class GAction;
|
||||
|
||||
class GToolBar : public GWidget {
|
||||
public:
|
||||
explicit GToolBar(GWidget* parent);
|
||||
virtual ~GToolBar() override;
|
||||
|
||||
void add_action(RetainPtr<GAction>&&);
|
||||
void add_separator();
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "GToolBar"; }
|
||||
virtual void paint_event(GPaintEvent&) override;
|
||||
|
||||
struct Item {
|
||||
enum Type { Invalid, Separator, Action };
|
||||
Type type { Invalid };
|
||||
RetainPtr<GAction> action;
|
||||
};
|
||||
Vector<OwnPtr<Item>> m_items;
|
||||
};
|
|
@ -73,6 +73,13 @@ void GWidget::handle_paint_event(GPaintEvent& event)
|
|||
if (fill_with_background_color()) {
|
||||
Painter painter(*this);
|
||||
painter.fill_rect(event.rect(), background_color());
|
||||
} else {
|
||||
#ifdef DEBUG_WIDGET_UNDERDRAW
|
||||
// FIXME: This is a bit broken.
|
||||
// If the widget is not opaque, let's not mess it up with debugging color.
|
||||
Painter painter(*this);
|
||||
painter.fill_rect(rect(), Color::Red);
|
||||
#endif
|
||||
}
|
||||
paint_event(event);
|
||||
for (auto* ch : children()) {
|
||||
|
|
|
@ -27,6 +27,7 @@ LIBGUI_OBJS = \
|
|||
GApplication.o \
|
||||
GAction.o \
|
||||
GFontDatabase.o \
|
||||
GToolBar.o \
|
||||
GWindow.o
|
||||
|
||||
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue