ProcessStateWidget.cpp 3.1 KB

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