Serenity Operating System
at master 111 lines 3.2 kB view raw
1/* 2 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2022, the SerenityOS developers. 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include "ProcessStateWidget.h" 9#include "ProcessModel.h" 10#include <LibCore/Timer.h> 11#include <LibGUI/BoxLayout.h> 12#include <LibGUI/HeaderView.h> 13#include <LibGUI/Painter.h> 14#include <LibGUI/TableView.h> 15#include <LibGUI/Widget.h> 16#include <LibGfx/Font/FontDatabase.h> 17#include <LibGfx/Palette.h> 18 19REGISTER_WIDGET(SystemMonitor, ProcessStateWidget) 20 21namespace SystemMonitor { 22 23class ProcessStateModel final 24 : public GUI::Model 25 , public GUI::ModelClient { 26public: 27 explicit ProcessStateModel(ProcessModel& target, pid_t pid) 28 : m_target(target) 29 , m_pid(pid) 30 { 31 m_target.register_client(*this); 32 refresh(); 33 } 34 35 virtual ~ProcessStateModel() override 36 { 37 m_target.unregister_client(*this); 38 } 39 40 virtual int row_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return m_target.column_count({}); } 41 virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return 2; } 42 43 virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role = GUI::ModelRole::Display) const override 44 { 45 if (role == GUI::ModelRole::Display) { 46 if (index.column() == 0) { 47 if (index.row() == ProcessModel::Column::Icon) { 48 // NOTE: The icon column is nameless in ProcessModel, but we want it to have a name here. 49 return "Icon"; 50 } 51 return m_target.column_name(index.row()); 52 } 53 return m_target_index.sibling_at_column(index.row()).data(); 54 } 55 56 if (role == GUI::ModelRole::Font) { 57 if (index.column() == 0) { 58 return Gfx::FontDatabase::default_font().bold_variant(); 59 } 60 } 61 62 return {}; 63 } 64 65 virtual void model_did_update([[maybe_unused]] unsigned flags) override 66 { 67 refresh(); 68 } 69 70 void refresh() 71 { 72 m_target_index = {}; 73 for (int row = 0; row < m_target.row_count({}); ++row) { 74 auto index = m_target.index(row, ProcessModel::Column::PID); 75 if (index.data().to_i32() == m_pid) { 76 m_target_index = index; 77 break; 78 } 79 } 80 did_update(GUI::Model::UpdateFlag::DontInvalidateIndices); 81 } 82 83 void set_pid(pid_t pid) 84 { 85 m_pid = pid; 86 refresh(); 87 } 88 pid_t pid() const { return m_pid; } 89 90private: 91 ProcessModel& m_target; 92 GUI::ModelIndex m_target_index; 93 pid_t m_pid { -1 }; 94}; 95 96ProcessStateWidget::ProcessStateWidget() 97{ 98 set_layout<GUI::VerticalBoxLayout>(4); 99 m_table_view = add<GUI::TableView>(); 100 m_table_view->set_model(adopt_ref(*new ProcessStateModel(ProcessModel::the(), 0))); 101 m_table_view->column_header().set_visible(false); 102 m_table_view->column_header().set_section_size(0, 90); 103} 104 105void ProcessStateWidget::set_pid(pid_t pid) 106{ 107 static_cast<ProcessStateModel*>(m_table_view->model())->set_pid(pid); 108 update(); 109} 110 111}