OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::SketchInlineEditor Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/CAD/SketchInlineEditor.hpp>

Collaboration diagram for Slic3r::GUI::SketchInlineEditor:

Classes

struct  Closed

Public Member Functions

 SketchInlineEditor ()=default
void open (const wxPoint &canvas_px, double value, const std::string &title, std::function< void(double)> on_commit, std::function< void()> on_cancel)
void close ()
void cancel ()
void commit ()
bool refuse (const std::string &why)
bool is_open () const
bool render (ImGuiWrapper &imgui, float scale)
void bring_to_front ()
bool is_mapped () const
bool has_focus () const
void dismiss ()

Public Attributes

std::function< void()> request_frame

Private Member Functions

void do_commit ()
void do_cancel ()

Private Attributes

std::function< void(double)> m_commit
std::function< void()> m_cancel
bool m_open {false}
bool m_focus_pending {false}
wxPoint m_anchor {0, 0}
std::string m_title
std::string m_err
char m_buf [64] {}
double m_prefill_value {0.0}
std::string m_prefill_text
bool m_active {false}
Closed m_last
bool m_in_commit {false}

Detailed Description


Class Documentation

◆ Slic3r::GUI::SketchInlineEditor::Closed

struct Slic3r::GUI::SketchInlineEditor::Closed
Collaboration diagram for Slic3r::GUI::SketchInlineEditor::Closed:
Class Members
wxPoint anchor
string buf
function< void()> cancel
function< void(double)> commit
string prefill_text
double prefill_value {0.0}
string title

Constructor & Destructor Documentation

◆ SketchInlineEditor()

Slic3r::GUI::SketchInlineEditor::SketchInlineEditor ( )
default

Member Function Documentation

◆ bring_to_front()

void Slic3r::GUI::SketchInlineEditor::bring_to_front ( )
249{
250 // Not gated on m_open: a commit closes the field after it was drawn, and that frame still
251 // shows it. A window that did not Begin this frame is not rendered, so lifting it is inert.
252 if (ImGuiWindow* w = ImGui::FindWindowByName(kWindowName))
253 ImGui::BringWindowToDisplayFront(w);
254}

◆ cancel()

void Slic3r::GUI::SketchInlineEditor::cancel ( )
114{
115 if (m_open) do_cancel();
116}
bool m_open
Definition SketchInlineEditor.hpp:90
void do_cancel()
Definition SketchInlineEditor.cpp:123

References do_cancel(), and m_open.

Here is the call graph for this function:

◆ close()

void Slic3r::GUI::SketchInlineEditor::close ( )
104{
105 m_open = false;
106 m_focus_pending = false;
107 m_active = false;
108 m_commit = nullptr;
109 m_cancel = nullptr;
110 m_err.clear();
111}
std::function< void(double)> m_commit
Definition SketchInlineEditor.hpp:88
bool m_active
Definition SketchInlineEditor.hpp:98
bool m_focus_pending
Definition SketchInlineEditor.hpp:91
std::string m_err
Definition SketchInlineEditor.hpp:94
std::function< void()> m_cancel
Definition SketchInlineEditor.hpp:89

References m_active, m_cancel, m_commit, m_err, m_focus_pending, and m_open.

Referenced by dismiss(), do_cancel(), and do_commit().

Here is the caller graph for this function:

◆ commit()

void Slic3r::GUI::SketchInlineEditor::commit ( )
119{
120 if (m_open) do_commit();
121}
void do_commit()
Definition SketchInlineEditor.cpp:149

References do_commit(), and m_open.

Here is the call graph for this function:

◆ dismiss()

void Slic3r::GUI::SketchInlineEditor::dismiss ( )
inline
82{ close(); }
void close()
Definition SketchInlineEditor.cpp:103

References close().

Here is the call graph for this function:

◆ do_cancel()

void Slic3r::GUI::SketchInlineEditor::do_cancel ( )
private
124{
125 ux_trace("cancel", m_title, "");
126 auto cb = m_cancel;
127 close();
128 if (cb) cb();
129}
std::string m_title
Definition SketchInlineEditor.hpp:93
void ux_trace(const char *event, const std::string &title, const std::string &detail)
Definition SketchInlineEditor.cpp:73

References close(), m_cancel, and m_title.

Referenced by cancel(), and render().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_commit()

void Slic3r::GUI::SketchInlineEditor::do_commit ( )
private
150{
151 double v = 0.0;
152 // An untouched field commits the value it opened with, not its rounded display: Enter on a
153 // 37.4567 line must not turn it into a 37.457 driving dimension.
154 if (m_prefill_text == m_buf)
155 v = m_prefill_value;
156 else if (!parse_value(m_buf, v)) {
157 // Refusing input in silence is indistinguishable from the app having frozen: the field
158 // just sits there and the user has no idea what it wants. Say so in the title line and
159 // keep editing.
160 ux_trace("refused", m_title, std::string("typed=") + m_buf);
161 m_err = (m_buf[0] == '\0') ? _u8L("Enter a number") : _u8L("Not a number");
162 m_focus_pending = true;
163 return;
164 }
165 ux_trace("commit", m_title, std::string("typed=") + m_buf + " value=" + fmt_value(v, 4));
166 auto cb = m_commit;
168 close();
169 // AFTER close(): the callback may open the next queued dimension (a rectangle queues Width
170 // then Height), and doing that into a field that still believes it is open would drop the
171 // second one's prefill on the floor.
172 m_in_commit = true;
173 if (cb) cb(v);
174 m_in_commit = false;
175 m_last = Closed{};
176}
char m_buf[64]
Definition SketchInlineEditor.hpp:95
std::string m_prefill_text
Definition SketchInlineEditor.hpp:97
bool m_in_commit
Definition SketchInlineEditor.hpp:106
wxPoint m_anchor
Definition SketchInlineEditor.hpp:92
Closed m_last
Definition SketchInlineEditor.hpp:105
double m_prefill_value
Definition SketchInlineEditor.hpp:96
Definition SketchInlineEditor.hpp:100
std::string fmt_value(double v, int digits=3)
Definition SketchInlineEditor.cpp:29
bool parse_value(const char *text, double &out)
Definition SketchInlineEditor.cpp:46
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, close(), m_anchor, m_buf, m_cancel, m_commit, m_err, m_focus_pending, m_in_commit, m_last, m_prefill_text, m_prefill_value, and m_title.

Referenced by commit(), and render().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_focus()

bool Slic3r::GUI::SketchInlineEditor::has_focus ( ) const
inline
81{ return m_open && (m_active || m_focus_pending); }

References m_active, m_focus_pending, and m_open.

◆ is_mapped()

bool Slic3r::GUI::SketchInlineEditor::is_mapped ( ) const
inline
78{ return m_open; }

References m_open.

◆ is_open()

bool Slic3r::GUI::SketchInlineEditor::is_open ( ) const
inline
55{ return m_open; }

References m_open.

◆ open()

void Slic3r::GUI::SketchInlineEditor::open ( const wxPoint & canvas_px,
double value,
const std::string & title,
std::function< void(double)> on_commit,
std::function< void()> on_cancel )
85{
86 m_anchor = canvas_px;
87 m_title = title;
88 m_err.clear();
89 m_commit = std::move(on_commit);
90 m_cancel = std::move(on_cancel);
91 const std::string v = fmt_value(value);
92 std::snprintf(m_buf, sizeof(m_buf), "%s", v.c_str());
93 m_prefill_value = value;
95 m_active = false;
96 m_open = true;
97 // ImGui takes keyboard focus for one frame on request; asking on the frame the field first
98 // appears is what makes typing land without a click. There is no window manager to consult.
99 m_focus_pending = true;
100 ux_trace("open", m_title, "prefill=" + v);
101}

References m_active, m_anchor, m_buf, m_cancel, m_commit, m_err, m_focus_pending, m_open, m_prefill_text, m_prefill_value, and m_title.

◆ refuse()

bool Slic3r::GUI::SketchInlineEditor::refuse ( const std::string & why)
132{
133 // Only meaningful while a commit callback runs and before it opened another field.
134 if (!m_in_commit || m_open) return false;
135 m_anchor = m_last.anchor;
136 m_title = m_last.title;
137 m_commit = m_last.commit;
138 m_cancel = m_last.cancel;
139 m_prefill_value = m_last.prefill_value;
140 m_prefill_text = m_last.prefill_text;
141 std::snprintf(m_buf, sizeof(m_buf), "%s", m_last.buf.c_str());
142 m_err = why;
143 m_open = true;
144 m_focus_pending = true;
145 ux_trace("refused", m_title, "reason=" + why);
146 return true;
147}

References m_anchor, m_buf, m_cancel, m_commit, m_err, m_focus_pending, m_in_commit, m_last, m_open, m_prefill_text, m_prefill_value, and m_title.

◆ render()

bool Slic3r::GUI::SketchInlineEditor::render ( ImGuiWrapper & imgui,
float scale )
179{
180 if (!m_open) return false;
181
183 imgui.set_next_window_pos((float) m_anchor.x, (float) m_anchor.y, ImGuiCond_Always, 0.5f, 0.5f);
184 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
185 // NoInputs is what every other sketch overlay sets and is exactly what this one must not:
186 // it is the only overlay in the tab that the user types into.
187 imgui.begin(std::string(kWindowName),
188 ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration
189 | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings);
190
191 if (!m_title.empty() || !m_err.empty()) {
192 if (m_err.empty()) {
193 imgui.text(m_title);
194 } else {
195 ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::to_ImVec4(ColorRGBA(0.91f, 0.42f, 0.42f, 1.0f)));
196 imgui.text(m_err);
197 ImGui::PopStyleColor();
198 }
199 }
200
201 if (m_focus_pending) {
202 ImGui::SetKeyboardFocusHere();
203 m_focus_pending = false;
204 }
205 ImGui::PushItemWidth(90.0f * scale);
206 // EnterReturnsTrue so Enter commits from inside the widget; AutoSelectAll so the prefill is
207 // replaced by the first digit typed, which is what "pre-selected" meant when this was a
208 // wxTextCtrl and is what makes typing a value a single gesture.
209 // No CharsDecimal: it lets only the LOCALE's decimal separator through, so in a C locale a
210 // comma could not be typed at all, and it admits '*' and '/' that the parser then refuses.
211 // parse_value() is the one judge of what is a number.
212 const bool entered = ImGui::InputText("##sketchvalue_in", m_buf, sizeof(m_buf),
213 ImGuiInputTextFlags_EnterReturnsTrue
214 | ImGuiInputTextFlags_AutoSelectAll);
215 m_active = ImGui::IsItemActive();
216 // Tab accepts the value like Enter does (and moves on to the next queued field, if any).
217 const bool tabbed = m_active && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab));
218 // MEASUREMENT, not a fix: one line per frame saying whether ImGui believes it owns the
219 // keyboard and whether our widget is the active one. "Typing does not arrive" has two very
220 // different causes — no FRAMES (this canvas repaints on demand only, so an idle canvas never
221 // processes ImGui's queued characters) versus frames that run while the input is not active —
222 // and they are indistinguishable from outside.
223 if (std::getenv("ORCA_CAD_UXTRACE")) {
224 const ImGuiIO& io = ImGui::GetIO();
225 std::fprintf(stderr, "[UX] frame title=%s want_text=%d want_kb=%d active=%d buf=%s\n",
226 m_title.c_str(), (int) io.WantTextInput, (int) io.WantCaptureKeyboard,
227 (int) ImGui::IsItemActive(), m_buf);
228 std::fflush(stderr);
229 }
230 ImGui::PopItemWidth();
231 imgui.end();
232 ImGui::PopStyleVar();
234
235 // Keep the frames coming while the field is up — see request_frame's note in the header.
236 if (m_open && request_frame)
238
239 // Act AFTER end(): do_commit can reopen the field for the next queued dimension, and that
240 // must not happen inside this frame's window.
241 if (entered || tabbed)
242 do_commit();
243 else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))
244 do_cancel();
245 return true;
246}
int scale(const int val)
Definition WipeTowerDialog.cpp:58
static void pop_common_window_style()
Definition ImGuiWrapper.cpp:2839
static ImVec4 to_ImVec4(const ColorRGB &color)
Definition ImGuiWrapper.cpp:1053
static void push_common_window_style(const float scale)
Definition ImGuiWrapper.cpp:2794
std::function< void()> request_frame
Definition SketchInlineEditor.hpp:76

References Slic3r::GUI::ImGuiWrapper::begin(), do_cancel(), do_commit(), Slic3r::GUI::ImGuiWrapper::end(), m_active, m_anchor, m_buf, m_err, m_focus_pending, m_open, m_title, Slic3r::GUI::ImGuiWrapper::pop_common_window_style(), Slic3r::GUI::ImGuiWrapper::push_common_window_style(), request_frame, scale(), Slic3r::GUI::ImGuiWrapper::set_next_window_pos(), Slic3r::GUI::ImGuiWrapper::text(), and Slic3r::GUI::ImGuiWrapper::to_ImVec4().

Here is the call graph for this function:

Member Data Documentation

◆ m_active

bool Slic3r::GUI::SketchInlineEditor::m_active {false}
private
98{false}; // the InputText was the active item last frame

Referenced by close(), has_focus(), open(), and render().

◆ m_anchor

wxPoint Slic3r::GUI::SketchInlineEditor::m_anchor {0, 0}
private
92{0, 0}; // canvas device px

Referenced by do_commit(), open(), refuse(), and render().

◆ m_buf

char Slic3r::GUI::SketchInlineEditor::m_buf[64] {}
private
95{}; // the edited text; ImGui::InputText writes into it

Referenced by do_commit(), open(), refuse(), and render().

◆ m_cancel

std::function<void()> Slic3r::GUI::SketchInlineEditor::m_cancel
private

Referenced by close(), do_cancel(), do_commit(), open(), and refuse().

◆ m_commit

std::function<void(double)> Slic3r::GUI::SketchInlineEditor::m_commit
private

Referenced by close(), do_commit(), open(), and refuse().

◆ m_err

std::string Slic3r::GUI::SketchInlineEditor::m_err
private

Referenced by close(), do_commit(), open(), refuse(), and render().

◆ m_focus_pending

bool Slic3r::GUI::SketchInlineEditor::m_focus_pending {false}
private
91{false}; // one frame of SetKeyboardFocusHere after opening

Referenced by close(), do_commit(), has_focus(), open(), refuse(), and render().

◆ m_in_commit

bool Slic3r::GUI::SketchInlineEditor::m_in_commit {false}
private
106{false};

Referenced by do_commit(), and refuse().

◆ m_last

Closed Slic3r::GUI::SketchInlineEditor::m_last
private

Referenced by do_commit(), and refuse().

◆ m_open

bool Slic3r::GUI::SketchInlineEditor::m_open {false}
private

◆ m_prefill_text

std::string Slic3r::GUI::SketchInlineEditor::m_prefill_text
private

Referenced by do_commit(), open(), and refuse().

◆ m_prefill_value

double Slic3r::GUI::SketchInlineEditor::m_prefill_value {0.0}
private
96{0.0}; // the exact value the field opened with...

Referenced by do_commit(), open(), and refuse().

◆ m_title

std::string Slic3r::GUI::SketchInlineEditor::m_title
private

◆ request_frame

std::function<void()> Slic3r::GUI::SketchInlineEditor::request_frame

Referenced by render().


The documentation for this class was generated from the following files: