ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ToggleSwitch.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 
13 #include "visualization/gui/Util.h"
14 
15 namespace cloudViewer {
16 namespace visualization {
17 namespace gui {
18 
19 namespace {
20 float CalcSwitchWidth(float height) { return height * 1.55f; }
21 
22 static int g_next_toggle_id = 1;
23 } // namespace
24 
26  std::string name_;
27  std::string id_;
28  bool is_on_ = false;
29  std::function<void(bool)> on_clicked_;
30 };
31 
32 ToggleSwitch::ToggleSwitch(const char* name) : impl_(new ToggleSwitch::Impl()) {
33  impl_->name_ = name;
34  impl_->id_ =
35  impl_->name_ + "##toggle_" + std::to_string(g_next_toggle_id++);
36 }
37 
39 
40 bool ToggleSwitch::GetIsOn() const { return impl_->is_on_; }
41 
42 void ToggleSwitch::SetOn(bool checked) { impl_->is_on_ = checked; }
43 
44 void ToggleSwitch::SetOnClicked(std::function<void(bool)> on_clicked) {
45  impl_->on_clicked_ = on_clicked;
46 }
47 
49  const Constraints& constraints) const {
50  auto em = ImGui::GetTextLineHeight();
51  auto padding = ImGui::GetStyle().FramePadding;
52  auto text_size = ImGui::GetFont()->CalcTextSizeA(
53  float(context.theme.font_size), constraints.width, 10000,
54  impl_->name_.c_str());
55  int height = int(std::ceil(em + 2.0f * padding.y));
56  auto switch_width = CalcSwitchWidth(height);
57  return Size(int(switch_width + std::ceil(text_size.x + 2.0f * padding.x)),
58  height);
59 }
60 
62  auto& theme = context.theme;
63  auto& frame = GetFrame();
64  ImGui::SetCursorScreenPos(
65  ImVec2(float(frame.x), float(frame.y) - ImGui::GetScrollY()));
67 
69  ImGui::PushItemWidth(float(GetFrame().width));
70 
71  bool changed = false;
72  ImVec2 p = ImGui::GetCursorScreenPos();
73  ImDrawList* draw_list = ImGui::GetWindowDrawList();
74 
75  float height = frame.height;
76  float width = CalcSwitchWidth(height);
77  float radius = height * 0.50f;
78 
79  ImGui::InvisibleButton(impl_->name_.c_str(), ImVec2(width, height));
80  DrawImGuiTooltip(); // button is separate obj, so needs its own call
81  ImU32 track_color;
82  ImU32 thumb_color = colorToImguiRGBA(theme.toggle_thumb_color);
83  if (impl_->is_on_) {
84  if (ImGui::IsItemHovered()) {
85  track_color =
86  colorToImguiRGBA(theme.toggle_background_hover_on_color);
87  } else {
88  track_color = colorToImguiRGBA(theme.toggle_background_on_color);
89  }
90  } else {
91  if (ImGui::IsItemHovered()) {
92  track_color =
93  colorToImguiRGBA(theme.toggle_background_hover_off_color);
94  } else {
95  track_color = colorToImguiRGBA(theme.toggle_background_off_color);
96  }
97  }
98 
99  if (ImGui::IsItemClicked()) {
100  impl_->is_on_ = !impl_->is_on_;
101  changed = true;
102  }
103  draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), track_color,
104  radius);
105  draw_list->AddRect(p, ImVec2(p.x + width, p.y + height),
106  colorToImguiRGBA(theme.border_color), radius);
107  float thumb_offset =
108  (impl_->is_on_ ? 1.0f : 0.0f) * (width - 2.0f * radius);
109  draw_list->AddCircleFilled(
110  ImVec2(p.x + radius + thumb_offset, p.y + radius), radius - 1.5f,
111  thumb_color);
112 
113  if (changed) {
114  if (impl_->on_clicked_) {
115  impl_->on_clicked_(impl_->is_on_);
116  }
118  }
119 
120  ImGui::SameLine();
121  ImGui::TextUnformatted(impl_->name_.c_str());
122  ImGui::PopItemWidth();
125 
126  return result;
127 }
128 
129 } // namespace gui
130 } // namespace visualization
131 } // namespace cloudViewer
Rect frame
int width
std::string name
int height
core::Tensor result
Definition: VtkUtils.cpp:76
DrawResult Draw(const DrawContext &context) override
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
void SetOnClicked(std::function< void(bool)> on_clicked)
virtual const Rect & GetFrame() const
Returns the frame size in pixels.
Definition: Widget.cpp:51
ImGuiContext * context
Definition: Window.cpp:76
const Theme * theme
Definition: Window.cpp:74
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Definition: MiniVec.h:89
uint32_t colorToImguiRGBA(const Color &color)
Definition: Util.cpp:25
Generic file read and write utility for python interface.
std::string to_string(const T &n)
Definition: Common.h:20