diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-28 10:57:09 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-28 10:57:09 +0100 |
commit | dc9f8a936158b586362cee689b26e095074e59bc (patch) | |
tree | 81d14ba66f69f165f46b13dd4025eb08f1c75660 | |
parent | b3ae1163efa0324f2062e12bba69463a01d63827 (diff) | |
download | serenity-dc9f8a936158b586362cee689b26e095074e59bc.zip |
LibGUI: Take ProcessManager's process view and turn it into GTableView.
Make it sufficiently generic that it can be reused for any table data. :^)
-rw-r--r-- | Applications/ProcessManager/Makefile | 2 | ||||
-rw-r--r-- | Applications/ProcessManager/ProcessTableModel.cpp | 2 | ||||
-rw-r--r-- | Applications/ProcessManager/ProcessTableView.cpp | 35 | ||||
-rw-r--r-- | Applications/ProcessManager/ProcessTableView.h | 24 | ||||
-rw-r--r-- | Applications/ProcessManager/ProcessView.h | 37 | ||||
-rw-r--r-- | Applications/ProcessManager/main.cpp | 10 | ||||
-rw-r--r-- | LibGUI/GTableModel.cpp | 33 | ||||
-rw-r--r-- | LibGUI/GTableModel.h | 20 | ||||
-rw-r--r-- | LibGUI/GTableView.cpp (renamed from Applications/ProcessManager/ProcessView.cpp) | 62 | ||||
-rw-r--r-- | LibGUI/GTableView.h | 34 | ||||
-rw-r--r-- | LibGUI/Makefile | 2 |
11 files changed, 173 insertions, 88 deletions
diff --git a/Applications/ProcessManager/Makefile b/Applications/ProcessManager/Makefile index b996d9443b..75c2566320 100644 --- a/Applications/ProcessManager/Makefile +++ b/Applications/ProcessManager/Makefile @@ -1,6 +1,6 @@ OBJS = \ ProcessTableModel.o \ - ProcessView.o \ + ProcessTableView.o \ main.o APP = ProcessManager diff --git a/Applications/ProcessManager/ProcessTableModel.cpp b/Applications/ProcessManager/ProcessTableModel.cpp index c94bc8fd45..28abcde9b1 100644 --- a/Applications/ProcessManager/ProcessTableModel.cpp +++ b/Applications/ProcessManager/ProcessTableModel.cpp @@ -141,6 +141,8 @@ void ProcessTableModel::update() } for (auto pid : pids_to_remove) m_processes.remove(pid); + + did_update(); } pid_t ProcessTableModel::selected_pid() const diff --git a/Applications/ProcessManager/ProcessTableView.cpp b/Applications/ProcessManager/ProcessTableView.cpp new file mode 100644 index 0000000000..0e761c852c --- /dev/null +++ b/Applications/ProcessManager/ProcessTableView.cpp @@ -0,0 +1,35 @@ +#include "ProcessTableView.h" +#include "ProcessTableModel.h" + + +ProcessTableView::ProcessTableView(GWidget* parent) + : GTableView(parent) +{ + set_model(make<ProcessTableModel>()); + start_timer(1000); + model().update(); +} + +ProcessTableView::~ProcessTableView() +{ +} + +void ProcessTableView::timer_event(GTimerEvent&) +{ + model().update(); +} + +pid_t ProcessTableView::selected_pid() const +{ + return model().selected_pid(); +} + +inline ProcessTableModel& ProcessTableView::model() +{ + return static_cast<ProcessTableModel&>(*GTableView::model()); +} + +inline const ProcessTableModel& ProcessTableView::model() const +{ + return static_cast<const ProcessTableModel&>(*GTableView::model()); +} diff --git a/Applications/ProcessManager/ProcessTableView.h b/Applications/ProcessManager/ProcessTableView.h new file mode 100644 index 0000000000..d1d823a6e4 --- /dev/null +++ b/Applications/ProcessManager/ProcessTableView.h @@ -0,0 +1,24 @@ +#pragma once + +#include <LibGUI/GTableView.h> +#include <AK/Function.h> +#include <unistd.h> + +class ProcessTableModel; + +class ProcessTableView final : public GTableView { +public: + explicit ProcessTableView(GWidget* parent); + virtual ~ProcessTableView() override; + + pid_t selected_pid() const; + + Function<void(String)> on_status_message; + +private: + virtual void timer_event(GTimerEvent&) override; + + ProcessTableModel& model(); + const ProcessTableModel& model() const; +}; + diff --git a/Applications/ProcessManager/ProcessView.h b/Applications/ProcessManager/ProcessView.h deleted file mode 100644 index 99e9bd79bd..0000000000 --- a/Applications/ProcessManager/ProcessView.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <LibGUI/GWidget.h> -#include <AK/Function.h> -#include <AK/HashMap.h> - -class GScrollBar; -class ProcessTableModel; - -class ProcessView final : public GWidget { -public: - ProcessView(GWidget* parent); - virtual ~ProcessView() override; - - void reload(); - - Function<void(String)> on_status_message; - - int header_height() const { return 16; } - int item_height() const { return 16; } - int item_count() const; - - pid_t selected_pid() const; - -private: - virtual void paint_event(GPaintEvent&) override; - virtual void resize_event(GResizeEvent&) override; - virtual void mousedown_event(GMouseEvent&) override; - virtual void timer_event(GTimerEvent&) override; - - void set_status_message(String&&); - Rect row_rect(int item_index) const; - - RetainPtr<GraphicsBitmap> m_process_icon; - GScrollBar* m_scrollbar { nullptr }; - OwnPtr<ProcessTableModel> m_model; -}; diff --git a/Applications/ProcessManager/main.cpp b/Applications/ProcessManager/main.cpp index cf6b4faa7e..8e1b8deae2 100644 --- a/Applications/ProcessManager/main.cpp +++ b/Applications/ProcessManager/main.cpp @@ -9,7 +9,7 @@ #include <unistd.h> #include <stdio.h> #include <signal.h> -#include "ProcessView.h" +#include "ProcessTableView.h" int main(int argc, char** argv) { @@ -19,14 +19,14 @@ int main(int argc, char** argv) widget->set_layout(make<GBoxLayout>(Orientation::Vertical)); auto* toolbar = new GToolBar(widget); - auto* process_view = new ProcessView(widget); + auto* process_table_view = new ProcessTableView(widget); auto* statusbar = new GStatusBar(widget); - process_view->on_status_message = [statusbar] (String message) { + process_table_view->on_status_message = [statusbar] (String message) { statusbar->set_text(move(message)); }; - auto kill_action = GAction::create("Kill process", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/kill16.rgb", { 16, 16 }), [process_view] (const GAction&) { - pid_t pid = process_view->selected_pid(); + auto kill_action = GAction::create("Kill process", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/kill16.rgb", { 16, 16 }), [process_table_view] (const GAction&) { + pid_t pid = process_table_view->selected_pid(); if (pid != -1) kill(pid, SIGKILL); }); diff --git a/LibGUI/GTableModel.cpp b/LibGUI/GTableModel.cpp new file mode 100644 index 0000000000..c45d615558 --- /dev/null +++ b/LibGUI/GTableModel.cpp @@ -0,0 +1,33 @@ +#include <LibGUI/GTableModel.h> +#include <LibGUI/GTableView.h> + +GTableModel::GTableModel() +{ +} + +GTableModel::~GTableModel() +{ +} + +void GTableModel::register_view(Badge<GTableView>, GTableView& view) +{ + m_views.set(&view); +} + +void GTableModel::unregister_view(Badge<GTableView>, GTableView& view) +{ + m_views.remove(&view); +} + +void GTableModel::for_each_view(Function<void(GTableView&)> callback) +{ + for (auto* view : m_views) + callback(*view); +} + +void GTableModel::did_update() +{ + for_each_view([] (GTableView& view) { + view.did_update_model(); + }); +} diff --git a/LibGUI/GTableModel.h b/LibGUI/GTableModel.h index 365bc84bf6..c1548718da 100644 --- a/LibGUI/GTableModel.h +++ b/LibGUI/GTableModel.h @@ -1,12 +1,16 @@ #pragma once #include <AK/AKString.h> +#include <AK/Badge.h> +#include <AK/Function.h> +#include <AK/HashTable.h> #include <LibGUI/GModelIndex.h> +class GTableView; + class GTableModel { public: - GTableModel() { } - virtual ~GTableModel() { } + virtual ~GTableModel(); virtual int row_count() const = 0; virtual int column_count() const = 0; @@ -22,4 +26,16 @@ public: { return index.row() >= 0 && index.row() < row_count() && index.column() >= 0 && index.column() < column_count(); } + + void register_view(Badge<GTableView>, GTableView&); + void unregister_view(Badge<GTableView>, GTableView&); + +protected: + GTableModel(); + + void for_each_view(Function<void(GTableView&)>); + void did_update(); + +private: + HashTable<GTableView*> m_views; }; diff --git a/Applications/ProcessManager/ProcessView.cpp b/LibGUI/GTableView.cpp index 7fbb68410d..0f98f1eac8 100644 --- a/Applications/ProcessManager/ProcessView.cpp +++ b/LibGUI/GTableView.cpp @@ -1,65 +1,52 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <AK/FileSystemPath.h> -#include <AK/HashMap.h> -#include <SharedGraphics/GraphicsBitmap.h> -#include <SharedGraphics/Painter.h> +#include <LibGUI/GTableView.h> +#include <LibGUI/GTableModel.h> #include <LibGUI/GScrollBar.h> -#include "ProcessTableModel.h" -#include "ProcessView.h" - -static HashMap<unsigned, String>* s_usernames; +#include <SharedGraphics/Painter.h> -ProcessView::ProcessView(GWidget* parent) +GTableView::GTableView(GWidget* parent) : GWidget(parent) { - m_process_icon = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/gear16.rgb", { 16, 16 }); - m_scrollbar = new GScrollBar(Orientation::Vertical, this); m_scrollbar->set_step(4); m_scrollbar->set_big_step(30); m_scrollbar->on_change = [this] (int) { update(); }; - - m_model = make<ProcessTableModel>(); - - start_timer(1000); - reload(); } -ProcessView::~ProcessView() +GTableView::~GTableView() { } -void ProcessView::timer_event(GTimerEvent&) +void GTableView::set_model(OwnPtr<GTableModel>&& model) { - reload(); + if (model.ptr() == m_model.ptr()) + return; + if (m_model) + m_model->unregister_view(Badge<GTableView>(), *this); + m_model = move(model); + if (m_model) + m_model->register_view(Badge<GTableView>(), *this); } -void ProcessView::resize_event(GResizeEvent& event) +void GTableView::resize_event(GResizeEvent& event) { m_scrollbar->set_relative_rect(event.size().width() - m_scrollbar->preferred_size().width(), 0, m_scrollbar->preferred_size().width(), event.size().height()); } -void ProcessView::reload() +void GTableView::did_update_model() { - m_model->update(); - int excess_height = max(0, (item_count() * item_height()) - height()); m_scrollbar->set_range(0, excess_height); - - set_status_message(String::format("%d processes", item_count())); update(); } -Rect ProcessView::row_rect(int item_index) const +Rect GTableView::row_rect(int item_index) const { return { 0, header_height() + (item_index * item_height()), width(), item_height() }; } -void ProcessView::mousedown_event(GMouseEvent& event) +void GTableView::mousedown_event(GMouseEvent& event) { auto adjusted_position = event.position().translated(0, m_scrollbar->value()); if (event.button() == GMouseButton::Left) { @@ -72,7 +59,7 @@ void ProcessView::mousedown_event(GMouseEvent& event) } } -void ProcessView::paint_event(GPaintEvent&) +void GTableView::paint_event(GPaintEvent&) { Painter painter(*this); @@ -124,18 +111,7 @@ void ProcessView::paint_event(GPaintEvent&) painter.draw_line({ 0, header_height() - 1 }, { width() - 1, header_height() - 1 }, Color::DarkGray); } -void ProcessView::set_status_message(String&& message) -{ - if (on_status_message) - on_status_message(move(message)); -} - -int ProcessView::item_count() const +int GTableView::item_count() const { return m_model->row_count(); } - -pid_t ProcessView::selected_pid() const -{ - return m_model->selected_pid(); -} diff --git a/LibGUI/GTableView.h b/LibGUI/GTableView.h new file mode 100644 index 0000000000..674014ce97 --- /dev/null +++ b/LibGUI/GTableView.h @@ -0,0 +1,34 @@ +#pragma once + +#include <LibGUI/GWidget.h> +#include <AK/Function.h> +#include <AK/HashMap.h> + +class GScrollBar; +class GTableModel; + +class GTableView : public GWidget { +public: + explicit GTableView(GWidget* parent); + virtual ~GTableView() override; + + virtual int header_height() const { return 16; } + virtual int item_height() const { return 16; } + + void set_model(OwnPtr<GTableModel>&&); + GTableModel* model() { return m_model.ptr(); } + const GTableModel* model() const { return m_model.ptr(); } + + void did_update_model(); + +private: + virtual void paint_event(GPaintEvent&) override; + virtual void resize_event(GResizeEvent&) override; + virtual void mousedown_event(GMouseEvent&) override; + + int item_count() const; + Rect row_rect(int item_index) const; + + GScrollBar* m_scrollbar { nullptr }; + OwnPtr<GTableModel> m_model; +}; diff --git a/LibGUI/Makefile b/LibGUI/Makefile index f3ac6e262b..b324290a32 100644 --- a/LibGUI/Makefile +++ b/LibGUI/Makefile @@ -28,6 +28,8 @@ LIBGUI_OBJS = \ GAction.o \ GFontDatabase.o \ GToolBar.o \ + GTableView.o \ + GTableModel.o \ GWindow.o OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS) |