GBoxLayout.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <LibGUI/GBoxLayout.h>
  2. #include <LibGUI/GWidget.h>
  3. //#define GBOXLAYOUT_DEBUG
  4. #ifdef GBOXLAYOUT_DEBUG
  5. #include <stdio.h>
  6. #endif
  7. GBoxLayout::GBoxLayout(Orientation orientation)
  8. : m_orientation(orientation)
  9. {
  10. }
  11. GBoxLayout::~GBoxLayout()
  12. {
  13. }
  14. #if 0
  15. Size GLayout::compute_preferred_size() const
  16. {
  17. }
  18. static Size compute_preferred_size(GLayout::Entry& entry)
  19. {
  20. if (entry.layout)
  21. return entry.layout->compute_preferred_size();
  22. else {
  23. return entry.widget->preferred_size();
  24. }
  25. }
  26. #endif
  27. void GBoxLayout::run(GWidget& widget)
  28. {
  29. if (m_entries.is_empty())
  30. return;
  31. Size available_size = widget.size();
  32. int number_of_entries_with_fixed_size = 0;
  33. for (auto& entry : m_entries) {
  34. if (entry.widget && entry.widget->size_policy(orientation()) == SizePolicy::Fixed) {
  35. available_size -= entry.widget->preferred_size();
  36. ++number_of_entries_with_fixed_size;
  37. }
  38. }
  39. int number_of_entries_with_automatic_size = m_entries.size() - number_of_entries_with_fixed_size;
  40. #ifdef GBOXLAYOUT_DEBUG
  41. printf("GBoxLayout: available_size=%s, fixed=%d, fill=%d\n", available_size.to_string().characters(), number_of_entries_with_fixed_size, number_of_entries_with_automatic_size);
  42. #endif
  43. Size automatic_size;
  44. if (number_of_entries_with_automatic_size) {
  45. if (m_orientation == Orientation::Horizontal) {
  46. automatic_size.set_width(available_size.width() / number_of_entries_with_automatic_size);
  47. automatic_size.set_height(widget.height());
  48. } else {
  49. automatic_size.set_width(widget.width());
  50. automatic_size.set_height(available_size.height() / number_of_entries_with_automatic_size);
  51. }
  52. }
  53. #ifdef GBOXLAYOUT_DEBUG
  54. printf("GBoxLayout: automatic_size=%s\n", automatic_size.to_string().characters());
  55. #endif
  56. int current_x = margins().left();
  57. int current_y = margins().top();
  58. for (auto& entry : m_entries) {
  59. Rect rect(current_x, current_y, 0, 0);
  60. if (entry.layout) {
  61. // FIXME: Implement recursive layout.
  62. ASSERT_NOT_REACHED();
  63. }
  64. ASSERT(entry.widget);
  65. rect.set_size(automatic_size.width() - margins().left() - margins().right(), automatic_size.height() - margins().top() - margins().bottom());
  66. if (entry.widget->size_policy(Orientation::Vertical) == SizePolicy::Fixed)
  67. rect.set_height(entry.widget->preferred_size().height());
  68. if (entry.widget->size_policy(Orientation::Horizontal) == SizePolicy::Fixed)
  69. rect.set_width(entry.widget->preferred_size().width());
  70. if (orientation() == Orientation::Horizontal) {
  71. if (entry.widget->size_policy(Orientation::Vertical) == SizePolicy::Fill)
  72. rect.set_height(widget.height() - margins().top() - margins().bottom());
  73. rect.center_vertically_within(widget.rect());
  74. } else {
  75. if (entry.widget->size_policy(Orientation::Horizontal) == SizePolicy::Fill)
  76. rect.set_width(widget.width() - margins().left() - margins().right());
  77. rect.center_horizontally_within(widget.rect());
  78. }
  79. #ifdef GBOXLAYOUT_DEBUG
  80. printf("GBoxLayout: apply, %s{%p} <- %s\n", entry.widget->class_name(), entry.widget.ptr(), rect.to_string().characters());
  81. #endif
  82. entry.widget->set_relative_rect(rect);
  83. if (orientation() == Orientation::Horizontal)
  84. current_x += rect.width() + spacing();
  85. else
  86. current_y += rect.height() + spacing();
  87. }
  88. }