WidgetTreeModel.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "WidgetTreeModel.h"
  7. #include <AK/StringBuilder.h>
  8. #include <LibGUI/Widget.h>
  9. namespace HackStudio {
  10. WidgetTreeModel::WidgetTreeModel(GUI::Widget& root)
  11. : m_root(root)
  12. {
  13. m_widget_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/inspector-object.png"));
  14. }
  15. WidgetTreeModel::~WidgetTreeModel()
  16. {
  17. }
  18. GUI::ModelIndex WidgetTreeModel::index(int row, int column, const GUI::ModelIndex& parent) const
  19. {
  20. if (!parent.is_valid()) {
  21. return create_index(row, column, m_root.ptr());
  22. }
  23. auto& parent_node = *static_cast<GUI::Widget*>(parent.internal_data());
  24. return create_index(row, column, parent_node.child_widgets().at(row));
  25. }
  26. GUI::ModelIndex WidgetTreeModel::parent_index(const GUI::ModelIndex& index) const
  27. {
  28. if (!index.is_valid())
  29. return {};
  30. auto& widget = *static_cast<GUI::Widget*>(index.internal_data());
  31. if (&widget == m_root.ptr())
  32. return {};
  33. if (widget.parent_widget() == m_root.ptr())
  34. return create_index(0, 0, m_root.ptr());
  35. // Walk the grandparent's children to find the index of widget's parent in its parent.
  36. // (This is needed to produce the row number of the GUI::ModelIndex corresponding to widget's parent.)
  37. int grandparent_child_index = 0;
  38. for (auto& grandparent_child : widget.parent_widget()->parent_widget()->child_widgets()) {
  39. if (grandparent_child == widget.parent_widget())
  40. return create_index(grandparent_child_index, 0, widget.parent_widget());
  41. ++grandparent_child_index;
  42. }
  43. VERIFY_NOT_REACHED();
  44. return {};
  45. }
  46. int WidgetTreeModel::row_count(const GUI::ModelIndex& index) const
  47. {
  48. if (!index.is_valid())
  49. return 1;
  50. auto& widget = *static_cast<GUI::Widget*>(index.internal_data());
  51. return widget.child_widgets().size();
  52. }
  53. int WidgetTreeModel::column_count(const GUI::ModelIndex&) const
  54. {
  55. return 1;
  56. }
  57. GUI::Variant WidgetTreeModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
  58. {
  59. auto* widget = static_cast<GUI::Widget*>(index.internal_data());
  60. if (role == GUI::ModelRole::Icon) {
  61. return m_widget_icon;
  62. }
  63. if (role == GUI::ModelRole::Display) {
  64. return String::formatted("{} ({})", widget->class_name(), widget->relative_rect());
  65. }
  66. return {};
  67. }
  68. void WidgetTreeModel::update()
  69. {
  70. did_update();
  71. }
  72. GUI::ModelIndex WidgetTreeModel::index_for_widget(GUI::Widget& widget) const
  73. {
  74. int parent_child_index = 0;
  75. for (auto& parent_child : widget.parent_widget()->child_widgets()) {
  76. if (parent_child == &widget)
  77. return create_index(parent_child_index, 0, &widget);
  78. ++parent_child_index;
  79. }
  80. return {};
  81. }
  82. }