ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Layout.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <imgui.h>
11 
12 #include <algorithm>
13 #include <cmath>
14 #include <iostream>
15 
18 #include "visualization/gui/Util.h"
19 
20 namespace cloudViewer {
21 namespace visualization {
22 namespace gui {
23 
24 namespace {
25 
26 std::vector<int> CalcMajor(const LayoutContext& context,
27  const Widget::Constraints& constraints,
28  Layout1D::Dir dir,
29  const std::vector<std::shared_ptr<Widget>>& children,
30  int* minor = nullptr) {
31  std::vector<Size> preferred_sizes;
32  preferred_sizes.reserve(children.size());
33  for (auto& child : children) {
34  preferred_sizes.push_back(
35  child->CalcPreferredSize(context, constraints));
36  }
37 
38  // Preferred size in the minor direction is the maximum preferred size,
39  // not including the items that want to be as big as possible (unless they
40  // are the only items).
41  int other = 0;
42  int num_other_maxgrow_items = 0;
43  std::vector<int> major;
44  major.reserve(preferred_sizes.size());
45  if (dir == Layout1D::VERT) {
46  for (auto& preferred : preferred_sizes) {
47  major.push_back(preferred.height);
48  if (preferred.width >= Widget::DIM_GROW) {
49  num_other_maxgrow_items += 1;
50  } else {
51  other = std::max(other, preferred.width);
52  }
53  }
54  } else {
55  for (auto& preferred : preferred_sizes) {
56  major.push_back(preferred.width);
57  if (preferred.height >= Widget::DIM_GROW) {
58  num_other_maxgrow_items += 1;
59  } else {
60  other = std::max(other, preferred.height);
61  }
62  }
63  }
64 
65  if (other == 0 && num_other_maxgrow_items > 0) {
66  other = Widget::DIM_GROW;
67  }
68 
69  if (minor) {
70  *minor = other;
71  }
72  return major;
73 }
74 
75 std::vector<std::vector<std::shared_ptr<Widget>>> CalcColumns(
76  int num_cols, const std::vector<std::shared_ptr<Widget>>& children) {
77  std::vector<std::vector<std::shared_ptr<Widget>>> columns(num_cols);
78  int col = 0;
79  for (auto& child : children) {
80  columns[col++].push_back(child);
81  if (col >= num_cols) {
82  col = 0;
83  }
84  }
85  return columns;
86 }
87 
88 std::vector<Size> CalcColumnSizes(
89  const std::vector<std::vector<std::shared_ptr<Widget>>>& columns,
90  const LayoutContext& context,
91  const Widget::Constraints& constraints) {
92  std::vector<Size> sizes;
93  sizes.reserve(columns.size());
94 
95  for (auto& col : columns) {
96  int w = 0, h = 0;
97  for (auto& widget : col) {
98  auto preferred = widget->CalcPreferredSize(context, constraints);
99  w = std::max(w, preferred.width);
100  h += preferred.height;
101  }
102  sizes.push_back(Size(w, h));
103  }
104 
105  return sizes;
106 }
107 
108 } // namespace
109 
110 // ----------------------------------------------------------------------------
111 Margins::Margins() : left(0), top(0), right(0), bottom(0) {}
112 Margins::Margins(int px) : left(px), top(px), right(px), bottom(px) {}
113 Margins::Margins(int horiz_px, int vert_px)
114  : left(horiz_px), top(vert_px), right(horiz_px), bottom(vert_px) {}
115 Margins::Margins(int left_px, int top_px, int right_px, int bottom_px)
116  : left(left_px), top(top_px), right(right_px), bottom(bottom_px) {}
117 
118 int Margins::GetHoriz() const { return this->left + this->right; }
119 
120 int Margins::GetVert() const { return this->top + this->bottom; }
121 
122 // ----------------------------------------------------------------------------
125  int spacing_;
128 };
129 
131  const LayoutContext& context,
132  const Constraints& constraints,
133  int depth /*= 0*/) {
134  static const char spaces[21] = " ";
135  const char* indent = spaces + (20 - 3 * depth);
136  auto pref_total = layout->CalcPreferredSize(context, constraints);
137  std::cout << "[debug] " << indent << "Layout1D ("
138  << (layout->impl_->dir_ == Layout1D::VERT ? "VERT" : "HORIZ")
139  << "): pref: (" << pref_total.width << ", " << pref_total.height
140  << ")" << std::endl;
141  std::cout << "[debug] " << indent << "spacing: " << layout->impl_->spacing_
142  << ", margins: (l:" << layout->impl_->margins_.left
143  << ", t:" << layout->impl_->margins_.top
144  << ", r:" << layout->impl_->margins_.right
145  << ", b:" << layout->impl_->margins_.bottom << ")" << std::endl;
146  for (size_t i = 0; i < layout->GetChildren().size(); ++i) {
147  auto child = layout->GetChildren()[i];
148  auto pref = child->CalcPreferredSize(context, constraints);
149  std::cout << "[debug] " << indent << "i: " << i << " (" << pref.width
150  << ", " << pref.height << ")" << std::endl;
151  Layout1D* child_layout = dynamic_cast<Layout1D*>(child.get());
152  if (child_layout) {
153  debug_PrintPreferredSizes(child_layout, context, constraints,
154  depth + 1);
155  }
156  VGrid* vgrid = dynamic_cast<VGrid*>(child.get());
157  if (vgrid) {
158  const char* grid_indent = spaces + (20 - 3 * (depth + 1));
159  std::cout << "[debug] " << grid_indent
160  << "VGrid: spacing: " << vgrid->GetSpacing()
161  << ", margins: (l:" << vgrid->GetMargins().left
162  << ", t:" << vgrid->GetMargins().top
163  << ", r:" << vgrid->GetMargins().right
164  << ", b:" << vgrid->GetMargins().bottom << ")"
165  << std::endl;
166  for (size_t i = 0; i < vgrid->GetChildren().size(); ++i) {
167  auto e = vgrid->GetChildren()[i];
168  auto pref = e->CalcPreferredSize(context, constraints);
169  std::cout << "[debug] " << grid_indent << "i: " << i << " ("
170  << pref.width << ", " << pref.height << ")"
171  << std::endl;
172  }
173  }
174  }
175 }
176 
177 Layout1D::Fixed::Fixed(int size, Dir dir) : size_(size), dir_(dir) {}
178 
180  const Constraints& constraints) const {
181  if (dir_ == VERT) {
182  return {0, size_};
183  }
184 
185  return {size_, 0};
186 }
187 
188 Size Layout1D::Stretch::CalcPreferredSize(
189  const LayoutContext& context, const Constraints& constraints) const {
190  return Size(0, 0);
191 }
192 
194  int spacing,
195  const Margins& margins,
196  const std::vector<std::shared_ptr<Widget>>& children)
197  : Super(children), impl_(new Layout1D::Impl()) {
198  impl_->dir_ = dir;
199  impl_->spacing_ = spacing;
200  impl_->margins_ = margins;
201 }
202 
204 
205 int Layout1D::GetSpacing() const { return impl_->spacing_; }
206 const Margins& Layout1D::GetMargins() const { return impl_->margins_; }
207 Margins& Layout1D::GetMutableMargins() { return impl_->margins_; }
208 
209 void Layout1D::SetSpacing(int spacing) { impl_->spacing_ = spacing; }
210 void Layout1D::SetMargins(const Margins& margins) { impl_->margins_ = margins; }
211 
213  AddChild(std::make_shared<Fixed>(size, impl_->dir_));
214 }
215 
217  return impl_->minor_axis_size_;
218 }
219 
221  impl_->minor_axis_size_ = size;
222 }
223 
224 void Layout1D::AddStretch() { AddChild(std::make_shared<Stretch>()); }
225 
227  const Constraints& constraints) const {
228  int minor;
229  std::vector<int> major =
230  CalcMajor(context, constraints, impl_->dir_, GetChildren(), &minor);
231  if (impl_->minor_axis_size_ < Widget::DIM_GROW) {
232  minor = impl_->minor_axis_size_;
233  }
234 
235  int total_spacing = impl_->spacing_ * std::max(0, int(major.size()) - 1);
236  int major_size = 0;
237  for (auto& size : major) {
238  major_size += size;
239  }
240 
241  if (impl_->dir_ == VERT) {
242  return Size(minor + impl_->margins_.GetHoriz(),
243  major_size + impl_->margins_.GetVert() + total_spacing);
244  } else {
245  return Size(major_size + impl_->margins_.GetHoriz() + total_spacing,
246  minor + impl_->margins_.GetVert());
247  }
248 }
249 
251  auto frame = GetFrame();
252  Constraints constraints;
253  if (impl_->dir_ == VERT) {
254  constraints.width =
255  frame.width - impl_->margins_.left - impl_->margins_.right;
256  } else {
257  constraints.height =
258  frame.height - impl_->margins_.top - impl_->margins_.bottom;
259  }
260  auto& children = GetChildren();
261  std::vector<int> major =
262  CalcMajor(context, constraints, impl_->dir_, children, nullptr);
263  int total = 0, num_stretch = 0, num_grow = 0;
264  for (auto& mj : major) {
265  total += mj;
266  if (mj <= 0) {
267  num_stretch += 1;
268  }
269  if (mj >= Widget::DIM_GROW) {
270  num_grow += 1;
271  }
272  }
273  int frame_size;
274  if (impl_->dir_ == VERT) {
275  frame_size = frame.height - impl_->margins_.GetVert();
276  } else {
277  frame_size = frame.width - impl_->margins_.GetHoriz();
278  }
279  int total_spacing = impl_->spacing_ * std::max(0, int(major.size()) - 1);
280  auto total_extra = frame_size - total - total_spacing;
281  if (num_stretch > 0 && frame_size > total) {
282  auto stretch = total_extra / num_stretch;
283  auto leftover_stretch = total_extra - stretch * num_stretch;
284  for (size_t i = 0; i < major.size(); ++i) {
285  if (major[i] <= 0) {
286  major[i] = stretch;
287  if (leftover_stretch > 0) {
288  major[i] += 1;
289  leftover_stretch -= 1;
290  }
291  }
292  }
293  } else if (frame_size < total) {
294  int n_shrinkable = num_grow;
295  if (impl_->dir_ == VERT) {
296  for (auto child : GetChildren()) {
297  if (std::dynamic_pointer_cast<ScrollableVert>(child)) {
298  n_shrinkable++;
299  }
300  }
301  }
302  if (n_shrinkable > 0) {
303  auto total_excess = total - (frame_size - total_spacing);
304  auto excess = total_excess / n_shrinkable;
305  auto leftover = total_excess - excess * num_stretch;
306  for (size_t i = 0; i < major.size(); ++i) {
307  if (major[i] >= Widget::DIM_GROW ||
308  (impl_->dir_ == VERT &&
309  std::dynamic_pointer_cast<ScrollableVert>(
310  GetChildren()[i]) != nullptr)) {
311  major[i] -= excess;
312  if (leftover > 0) {
313  major[i] -= 1;
314  leftover -= 1;
315  }
316  }
317  }
318  }
319  }
320 
321  int x = frame.GetLeft() + impl_->margins_.left;
322  int y = frame.GetTop() + impl_->margins_.top;
323  if (impl_->dir_ == VERT) {
324  int minor = frame.width - impl_->margins_.GetHoriz();
325  for (size_t i = 0; i < children.size(); ++i) {
326  int h = std::max(children[i]->CalcMinimumSize(context).height,
327  major[i]);
328  children[i]->SetFrame(Rect(x, y, minor, h));
329  y += major[i] + impl_->spacing_;
330  }
331  } else {
332  int minor = frame.height - impl_->margins_.GetVert();
333  for (size_t i = 0; i < children.size(); ++i) {
334  children[i]->SetFrame(Rect(x, y, major[i], minor));
335  x += major[i] + impl_->spacing_;
336  }
337  }
338 
340 }
341 
342 // ----------------------------------------------------------------------------
343 std::shared_ptr<Layout1D::Fixed> Vert::MakeFixed(int size) {
344  return std::make_shared<Layout1D::Fixed>(size, VERT);
345 }
346 
347 std::shared_ptr<Layout1D::Stretch> Vert::MakeStretch() {
348  return std::make_shared<Layout1D::Stretch>();
349 }
350 
351 Vert::Vert() : Layout1D(VERT, 0, Margins(), {}) {}
352 
353 Vert::Vert(int spacing /*= 0*/, const Margins& margins /*= Margins()*/)
354  : Layout1D(VERT, spacing, margins, {}) {}
355 
356 Vert::Vert(int spacing,
357  const Margins& margins,
358  const std::vector<std::shared_ptr<Widget>>& children)
359  : Layout1D(VERT, spacing, margins, children) {}
360 
362 
365 
366 // ----------------------------------------------------------------------------
368  std::string id_;
369  std::string text_;
371  bool is_open_ = true;
372 };
373 
375  : CollapsableVert(text, 0, Margins()) {}
376 
378  int spacing,
379  const Margins& margins /*= Margins()*/)
380  : Vert(spacing, margins), impl_(new CollapsableVert::Impl()) {
381  SetText(text);
382 }
383 
385 
386 void CollapsableVert::SetIsOpen(bool is_open) { impl_->is_open_ = is_open; }
387 
388 bool CollapsableVert::GetIsOpen() { return impl_->is_open_; }
389 
390 void CollapsableVert::SetText(const char* text) {
391  static int g_next_id = 1;
392 
393  impl_->text_ = text;
394  impl_->id_ = impl_->text_ + "##collapsing_" + std::to_string(g_next_id++);
395 }
396 
397 std::string CollapsableVert::GetText() const { return impl_->text_; };
398 
399 FontId CollapsableVert::GetFontId() const { return impl_->font_id_; }
400 
401 void CollapsableVert::SetFontId(FontId font_id) { impl_->font_id_ = font_id; }
402 
404  const Constraints& constraints) const {
405  // Only push the font for the label
406  ImGui::PushFont((ImFont*)context.fonts.GetFont(impl_->font_id_));
407  auto* font = ImGui::GetFont();
408  auto padding = ImGui::GetStyle().FramePadding;
409  int text_height = int(
410  std::ceil(ImGui::GetTextLineHeightWithSpacing() + 2 * padding.y));
411  int text_width =
412  int(std::ceil(font->CalcTextSizeA(font->FontSize, FLT_MAX, FLT_MAX,
413  impl_->text_.c_str())
414  .x));
415  ImGui::PopFont(); // back to default font for layout sizing
416 
417  auto pref = Super::CalcPreferredSize(context, constraints);
418  if (!impl_->is_open_) {
419  pref.height = 0;
420  }
421 
422  auto& margins = GetMargins();
423  return Size(std::max(text_width, pref.width) + margins.GetHoriz(),
424  text_height + pref.height + margins.GetVert());
425 }
426 
428  ImGui::PushFont((ImFont*)context.fonts.GetFont(impl_->font_id_));
429  auto padding = ImGui::GetStyle().FramePadding;
430  int text_height = int(
431  std::ceil(ImGui::GetTextLineHeightWithSpacing() + 2 * padding.y));
432  auto& margins = GetMutableMargins();
433  auto orig_top = margins.top;
434  margins.top = orig_top + text_height;
435  ImGui::PopFont();
436 
438 
439  margins.top = orig_top;
440 }
441 
444  bool was_open = impl_->is_open_;
445 
446  auto& frame = GetFrame();
447  ImGui::SetCursorScreenPos(
448  ImVec2(float(frame.x), float(frame.y) - ImGui::GetScrollY()));
449  ImGui::PushItemWidth(float(frame.width));
450 
451  auto padding = ImGui::GetStyle().FramePadding;
452  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, padding.y));
453  ImGui::PushStyleColor(ImGuiCol_HeaderHovered,
454  colorToImgui(context.theme.button_hover_color));
455  ImGui::PushStyleColor(ImGuiCol_HeaderActive,
456  colorToImgui(context.theme.button_active_color));
457 
458  ImGui::SetNextItemOpen(impl_->is_open_);
459  ImGui::PushFont((ImFont*)context.fonts.GetFont(impl_->font_id_));
460  bool node_clicked = ImGui::TreeNode(impl_->id_.c_str());
461  ImGui::PopFont();
462  if (node_clicked) {
464  ImGui::TreePop();
465  impl_->is_open_ = true;
466  } else {
467  impl_->is_open_ = false;
468  }
469 
470  ImGui::PopStyleColor(2);
471  ImGui::PopStyleVar();
472  ImGui::PopItemWidth();
473 
474  if (impl_->is_open_ != was_open) {
475  return DrawResult::RELAYOUT;
476  }
477  return result;
478 }
479 
480 // ----------------------------------------------------------------------------
482  ImGuiID id_;
483 };
484 
486 
487 ScrollableVert::ScrollableVert(int spacing /*= 0*/,
488  const Margins& margins /*= Margins()*/)
489  : ScrollableVert(spacing, margins, {}) {}
490 
492  int spacing,
493  const Margins& margins,
494  const std::vector<std::shared_ptr<Widget>>& children)
495  : Vert(spacing, margins, children), impl_(new ScrollableVert::Impl) {
496  static int g_next_id = 1;
497  impl_->id_ = g_next_id++;
498 }
499 
501 
503  auto& frame = GetFrame();
504  ImGui::SetCursorScreenPos(
505  ImVec2(float(frame.x), float(frame.y) - ImGui::GetScrollY()));
506  ImGui::PushStyleColor(ImGuiCol_FrameBg,
507  ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
508  ImGui::PushStyleColor(ImGuiCol_Border,
509  colorToImgui(Color(0.0f, 0.0f, 0.0f, 0.0f)));
510  ImGui::PushStyleColor(ImGuiCol_BorderShadow,
511  colorToImgui(Color(0.0f, 0.0f, 0.0f, 0.0f)));
512 
513  ImGui::BeginChildFrame(impl_->id_, ImVec2(frame.width, frame.height));
514  auto result = Super::Draw(context);
515  ImGui::EndChildFrame();
516 
517  ImGui::PopStyleColor(3);
518 
519  return result;
520 }
521 
522 // ----------------------------------------------------------------------------
523 std::shared_ptr<Layout1D::Fixed> Horiz::MakeFixed(int size) {
524  return std::make_shared<Layout1D::Fixed>(size, HORIZ);
525 }
526 
527 std::shared_ptr<Layout1D::Stretch> Horiz::MakeStretch() {
528  return std::make_shared<Layout1D::Stretch>();
529 }
530 
531 std::shared_ptr<Horiz> Horiz::MakeCentered(std::shared_ptr<Widget> w) {
532  return std::make_shared<Horiz>(
533  0, Margins(),
534  std::vector<std::shared_ptr<Widget>>(
536 }
537 
538 Horiz::Horiz() : Layout1D(HORIZ, 0, Margins(), {}) {}
539 
540 Horiz::Horiz(int spacing /*= 0*/, const Margins& margins /*= Margins()*/)
541  : Layout1D(HORIZ, spacing, margins, {}) {}
542 
543 Horiz::Horiz(int spacing,
544  const Margins& margins,
545  const std::vector<std::shared_ptr<Widget>>& children)
546  : Layout1D(HORIZ, spacing, margins, children) {}
547 
549 
552 
553 // ----------------------------------------------------------------------------
554 struct VGrid::Impl {
556  int spacing_;
559 };
560 
561 VGrid::VGrid(int num_cols,
562  int spacing /*= 0*/,
563  const Margins& margins /*= Margins()*/)
564  : impl_(new VGrid::Impl()) {
565  impl_->num_cols_ = num_cols;
566  impl_->spacing_ = spacing;
567  impl_->margins_ = margins;
568 }
569 
571 
572 int VGrid::GetSpacing() const { return impl_->spacing_; }
573 const Margins& VGrid::GetMargins() const { return impl_->margins_; }
574 
575 int VGrid::GetPreferredWidth() const { return impl_->preferred_width_; }
576 void VGrid::SetPreferredWidth(int w) { impl_->preferred_width_ = w; }
577 
579  const Constraints& constraints) const {
580  auto columns = CalcColumns(impl_->num_cols_, GetChildren());
581  auto column_sizes = CalcColumnSizes(columns, context, constraints);
582 
583  int width = 0, height = 0;
584  for (size_t i = 0; i < column_sizes.size(); ++i) {
585  auto& sz = column_sizes[i];
586  width += sz.width;
587  auto v_spacing = (int(columns[i].size()) - 1) * impl_->spacing_;
588  height = std::max(height, sz.height) + v_spacing;
589  }
590  width += (int(column_sizes.size()) - 1) * impl_->spacing_;
591  width = std::max(width, 0); // in case width or height has no items
592  height = std::max(height, 0);
593 
594  if (impl_->preferred_width_ < Widget::DIM_GROW) {
595  width = impl_->preferred_width_;
596  } else {
597  width = width + impl_->margins_.left + impl_->margins_.right;
598  }
599 
600  return Size(width, height + impl_->margins_.top + impl_->margins_.bottom);
601 }
602 
604  auto& frame = GetFrame();
605  const int layout_width =
606  frame.width - impl_->margins_.left - impl_->margins_.right;
607  Constraints constraints;
608  constraints.width = layout_width;
609 
610  auto columns = CalcColumns(impl_->num_cols_, GetChildren());
611  auto column_sizes = CalcColumnSizes(columns, context, constraints);
612 
613  // Shrink columns that are too big.
614  // TODO: right now this only handles DIM_GROW columns; extend to
615  // proportionally shrink columns that together add up to too much.
616  // Probably should figure out how to reuse for other layouts.
617  int grow_size = constraints.width;
618  int wanted_width = 0;
619  int total_not_growing_width = 0;
620  int num_growing = 0;
621  for (auto& sz : column_sizes) {
622  wanted_width += sz.width;
623  if (sz.width < grow_size) {
624  total_not_growing_width += sz.width;
625  } else {
626  num_growing += 1;
627  }
628  }
629  if (wanted_width > layout_width && num_growing > 0) {
630  int total_spacing = (int(columns.size()) - 1) * impl_->spacing_;
631  int growing_size =
632  (layout_width - total_spacing - total_not_growing_width) /
633  num_growing;
634  if (growing_size < 0) {
635  growing_size = layout_width / num_growing;
636  }
637  for (auto& sz : column_sizes) {
638  if (sz.width >= grow_size) {
639  sz.width = growing_size;
640  }
641  }
642  } else {
643  // Just adjust the columns for spacing.
644  int leftHalf = int(std::floor(float(impl_->spacing_) / 2.0));
645  int rightHalf = int(std::ceil(float(impl_->spacing_) / 2.0));
646  for (size_t i = 0; i < column_sizes.size() - 1; ++i) {
647  column_sizes[i].width -= leftHalf;
648  column_sizes[i + 1].width -= rightHalf;
649  }
650  }
651 
652  // Do the layout
653  int x = frame.GetLeft() + impl_->margins_.left;
654  for (size_t i = 0; i < columns.size(); ++i) {
655  Constraints constraints;
656  constraints.width = column_sizes[i].width;
657  int y = frame.GetTop() + impl_->margins_.top;
658  for (auto& w : columns[i]) {
659  auto preferred = w->CalcPreferredSize(context, constraints);
660  w->SetFrame(Rect(x, y, column_sizes[i].width, preferred.height));
661  y += preferred.height + impl_->spacing_;
662  }
663  x += column_sizes[i].width + impl_->spacing_;
664  }
665 
667 }
668 
669 } // namespace gui
670 } // namespace visualization
671 } // namespace cloudViewer
Rect frame
int width
int size
int height
int64_t size_
Definition: FilePLY.cpp:37
core::Tensor result
Definition: VtkUtils.cpp:76
static constexpr FontId DEFAULT_FONT_ID
Identifier for font used by default for all UI elements.
Definition: Application.h:57
void Layout(const LayoutContext &context) override
Definition: Layout.cpp:427
bool GetIsOpen()
Returns true if open and false if collapsed.
Definition: Layout.cpp:388
Widget::DrawResult Draw(const DrawContext &context) override
Definition: Layout.cpp:442
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
Definition: Layout.cpp:403
static std::shared_ptr< Layout1D::Fixed > MakeFixed(int size)
Definition: Layout.cpp:523
static std::shared_ptr< Layout1D::Stretch > MakeStretch()
Definition: Layout.cpp:527
static std::shared_ptr< Horiz > MakeCentered(std::shared_ptr< Widget > w)
Definition: Layout.cpp:531
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
Definition: Layout.cpp:179
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
Definition: Layout.cpp:226
void AddFixed(int size)
Adds a fixed number of pixels after the previously added widget.
Definition: Layout.cpp:212
Layout1D(Dir dir, int spacing, const Margins &margins, const std::vector< std::shared_ptr< Widget >> &children)
Definition: Layout.cpp:193
static void debug_PrintPreferredSizes(Layout1D *layout, const LayoutContext &context, const Constraints &constraints, int depth=0)
Definition: Layout.cpp:130
const Margins & GetMargins() const
Definition: Layout.cpp:206
void SetMargins(const Margins &margins)
Definition: Layout.cpp:210
void Layout(const LayoutContext &context) override
Definition: Layout.cpp:250
This a vertical layout that scrolls if it is smaller than its contents.
Definition: Layout.h:169
Widget::DrawResult Draw(const DrawContext &context) override
Definition: Layout.cpp:502
void Layout(const LayoutContext &context) override
Definition: Layout.cpp:603
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
Definition: Layout.cpp:578
const Margins & GetMargins() const
Definition: Layout.cpp:573
VGrid(int num_cols, int spacing=0, const Margins &margins=Margins())
Definition: Layout.cpp:561
Lays out widgets vertically.
Definition: Layout.h:112
static std::shared_ptr< Layout1D::Stretch > MakeStretch()
Definition: Layout.cpp:347
static std::shared_ptr< Layout1D::Fixed > MakeFixed(int size)
Definition: Layout.cpp:343
virtual DrawResult Draw(const DrawContext &context)
Definition: Widget.cpp:92
virtual const std::vector< std::shared_ptr< Widget > > GetChildren() const
Definition: Widget.cpp:47
virtual void Layout(const LayoutContext &context)
Definition: Widget.cpp:86
virtual const Rect & GetFrame() const
Returns the frame size in pixels.
Definition: Widget.cpp:51
virtual void AddChild(std::shared_ptr< Widget > child)
Definition: Widget.cpp:43
static constexpr int DIM_GROW
Definition: Widget.h:83
virtual Size CalcMinimumSize(const LayoutContext &context) const
Definition: Widget.cpp:82
int max(int a, int b)
Definition: cutil_math.h:48
ImGuiContext * context
Definition: Window.cpp:76
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
MiniVec< float, N > floor(const MiniVec< float, N > &a)
Definition: MiniVec.h:75
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Definition: MiniVec.h:89
ImVec4 colorToImgui(const Color &color)
Definition: Util.cpp:20
Generic file read and write utility for python interface.
std::string to_string(const T &n)
Definition: Common.h:20
int GetVert() const
Convenience function that returns top + bottom.
Definition: Layout.cpp:120
int GetHoriz() const
Convenience function that returns left + right.
Definition: Layout.cpp:118