ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
TextEdit.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 <cmath>
13 #include <string>
14 
16 #include "visualization/gui/Util.h"
17 
18 namespace cloudViewer {
19 namespace visualization {
20 namespace gui {
21 
22 namespace {
23 static int g_next_text_edit_id = 1;
24 
25 // See 3rdparty/imgui/misc/imgui_stdlib.cpp
26 int InputTextCallback(ImGuiInputTextCallbackData *data) {
27  if (data && data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
28  std::string *s = reinterpret_cast<std::string *>(data->UserData);
29  s->resize(data->BufTextLen);
30  data->Buf = const_cast<char *>(s->c_str());
31  }
32  return 0;
33 }
34 
35 } // namespace
36 
38  std::string id_;
39  std::string text_;
40  std::string placeholder_;
41  std::function<void(const char *)> on_text_changed_;
42  std::function<void(const char *)> on_value_changed_;
43 };
44 
45 TextEdit::TextEdit() : impl_(new TextEdit::Impl()) {
46  impl_->id_ = "##textedit_" + std::to_string(g_next_text_edit_id++);
47  impl_->text_.reserve(1);
48 }
49 
51 
52 const char *TextEdit::GetText() const { return impl_->text_.c_str(); }
53 
54 void TextEdit::SetText(const char *text) { impl_->text_ = text; }
55 
56 const char *TextEdit::GetPlaceholderText() const {
57  return impl_->placeholder_.c_str();
58 }
59 
60 void TextEdit::SetPlaceholderText(const char *text) {
61  impl_->placeholder_ = text;
62 }
63 
65  std::function<void(const char *)> on_text_changed) {
66  impl_->on_text_changed_ = on_text_changed;
67 }
68 
70  std::function<void(const char *)> on_value_changed) {
71  impl_->on_value_changed_ = on_value_changed;
72 }
73 
74 bool TextEdit::ValidateNewText(const char *text) { return true; }
75 
77  const Constraints &constraints) const {
78  auto em = std::ceil(ImGui::GetTextLineHeight());
79  auto padding = ImGui::GetStyle().FramePadding;
80  return Size(constraints.width, int(std::ceil(em + 2.0f * padding.y)));
81 }
82 
84  auto &frame = GetFrame();
85  ImGui::SetCursorScreenPos(
86  ImVec2(float(frame.x), float(frame.y) + ImGui::GetScrollY()));
87 
88  ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding,
89  0.0); // macOS doesn't round text editing
90 
91  ImGui::PushStyleColor(
92  ImGuiCol_FrameBg,
93  colorToImgui(context.theme.text_edit_background_color));
94  ImGui::PushStyleColor(
95  ImGuiCol_FrameBgHovered,
96  colorToImgui(context.theme.text_edit_background_color));
97  ImGui::PushStyleColor(
98  ImGuiCol_FrameBgActive,
99  colorToImgui(context.theme.text_edit_background_color));
100 
101  int text_flags = ImGuiInputTextFlags_CallbackResize;
102  if (!IsEnabled()) {
103  text_flags = ImGuiInputTextFlags_ReadOnly;
104  }
107  ImGui::PushItemWidth(float(GetFrame().width));
108  if (ImGui::InputTextWithHint(impl_->id_.c_str(),
109  impl_->placeholder_.c_str(),
110  const_cast<char *>(impl_->text_.c_str()),
111  impl_->text_.capacity(), text_flags,
112  InputTextCallback, &impl_->text_)) {
113  if (impl_->on_text_changed_) {
114  impl_->on_text_changed_(impl_->text_.c_str());
115  }
117  }
118  ImGui::PopItemWidth();
121 
122  ImGui::PopStyleColor(3);
123  ImGui::PopStyleVar();
124 
125  if (ImGui::IsItemDeactivatedAfterEdit()) {
126  if (ValidateNewText(impl_->text_.c_str())) {
127  if (impl_->on_value_changed_) {
128  impl_->on_value_changed_(impl_->text_.c_str());
129  }
130  }
131  // ValidateNewText() may have updated text (even if returned true)
133  }
134 
135  return result;
136 }
137 
138 } // namespace gui
139 } // namespace visualization
140 } // namespace cloudViewer
Rect frame
int width
core::Tensor result
Definition: VtkUtils.cpp:76
const char * GetText() const
Returns the current text value displayed.
Definition: TextEdit.cpp:52
virtual bool ValidateNewText(const char *text)
Definition: TextEdit.cpp:74
void SetPlaceholderText(const char *text)
Sets the text to display if the text value is empty.
Definition: TextEdit.cpp:60
DrawResult Draw(const DrawContext &context) override
Definition: TextEdit.cpp:83
void SetOnValueChanged(std::function< void(const char *)> on_value_changed)
Definition: TextEdit.cpp:69
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
Definition: TextEdit.cpp:76
const char * GetPlaceholderText() const
Returns the text displayed if the text value is empty.
Definition: TextEdit.cpp:56
void SetOnTextChanged(std::function< void(const char *)> on_text_changed)
Definition: TextEdit.cpp:64
virtual bool IsEnabled() const
Definition: Widget.cpp:69
virtual const Rect & GetFrame() const
Returns the frame size in pixels.
Definition: Widget.cpp:51
ImGuiContext * context
Definition: Window.cpp:76
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
std::function< void(const char *)> on_value_changed_
Definition: TextEdit.cpp:42
std::function< void(const char *)> on_text_changed_
Definition: TextEdit.cpp:41