RigsofRods
Soft-body Physics Simulation
GUIUtils.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2013-2020 Petr Ohlidal
4 
5  For more information, see http://www.rigsofrods.org/
6 
7  Rigs of Rods is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License version 3, as
9  published by the Free Software Foundation.
10 
11  Rigs of Rods is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "GUIUtils.h"
21 
22 #include "Actor.h"
23 
24 #include "imgui_internal.h" // ImTextCharFromUtf8
25 #include <regex>
26 #include <stdio.h> // sscanf
27 
28 static const std::regex TEXT_COLOR_REGEX = std::regex(R"(#[a-fA-F\d]{6})");
29 static const int TEXT_COLOR_MAX_LEN = 5000;
30 
31 // --------------------------------
32 // ImTextFeeder
33 
34 void RoR::ImTextFeeder::AddInline(ImU32 color, ImVec2 text_size, const char* text_begin, const char* text_end)
35 {
36  drawlist->AddText(this->cursor, color, text_begin, text_end);
37  this->cursor.x += text_size.x;
38  this->size.x = std::max(this->cursor.x - this->origin.x, this->size.x);
39  this->size.y = std::max(this->size.y, text_size.y);
40 }
41 
42 void RoR::ImTextFeeder::AddWrapped(ImU32 color, float wrap_width, const char* text_begin, const char* text_end)
43 {
44  ImVec2 size = ImGui::CalcTextSize(text_begin, text_end);
45  const float cur_width = this->cursor.x - this->origin.x;
46  if (wrap_width > 0.f && cur_width + size.x > wrap_width)
47  {
48  this->NextLine();
49  }
50 
51  // Trim blanks at the start of new line (not first line), like ImGui::TextWrapped() does.
52  bool recalc_size = false;
53  if (this->cursor.x == this->origin.x && this->cursor.y != this->origin.y)
54  {
55  while ((*text_begin == ' ' || *text_begin == '\t'))
56  {
57  ++text_begin;
58  recalc_size = true;
59  if (text_begin == text_end)
60  return; // Nothing more to draw
61  }
62  }
63 
64  if (recalc_size)
65  size = ImGui::CalcTextSize(text_begin, text_end);
66 
67  this->AddInline(color, size, text_begin, text_end);
68 }
69 
70 void RoR::ImTextFeeder::AddMultiline(ImU32 color, float wrap_width, const char* text_begin, const char* text_end)
71 {
72  const char* text_pos = text_begin;
73  const char* tok_begin = nullptr;
74  while (text_pos != text_end)
75  {
76  // Decode and advance one character
77  unsigned int c = (unsigned int)*text_pos;
78  int bytes_advance = 1;
79  if (c >= 0x80)
80  bytes_advance = ImTextCharFromUtf8(&c, text_pos, text_end);
81 
82  if (c == '\r')
83  {} // Ignore carriage return
84  else if (c == '\n')
85  {
86  if (tok_begin != nullptr)
87  {
88  this->AddWrapped(color, wrap_width, tok_begin, text_pos); // Print the token
89  }
90  tok_begin = nullptr;
91  this->NextLine();
92  }
93  else if (c == ' ' || c == '\t')
94  {
95  if (tok_begin != nullptr)
96  {
97  this->AddWrapped(color, wrap_width, tok_begin, text_pos); // Print the token
98  tok_begin = nullptr;
99  }
100  this->AddWrapped(color, wrap_width, text_pos, text_pos + bytes_advance); // Print the blank
101  }
102  else
103  {
104  if (tok_begin == nullptr)
105  tok_begin = text_pos;
106  }
107  text_pos += bytes_advance;
108  }
109 
110  if (tok_begin != nullptr)
111  {
112  this->AddWrapped(color, wrap_width, tok_begin, text_end); // Print last token
113  }
114 }
115 
117 {
118  const float height = ImGui::GetTextLineHeight();
119  this->size.y += height;
120  this->cursor.x = this->origin.x;
121  this->cursor.y += height;
122 }
123 
124 // --------------------------------
125 // Global functions
126 
127 // Internal helper
128 inline void ColorToInts(ImVec4 v, int&r, int&g, int&b) { r=(int)(v.x*255); g=(int)(v.y*255); b=(int)(v.z*255); }
129 
130 // A nice spinner https://github.com/ocornut/imgui/issues/1901#issuecomment-444929973
131 void RoR::LoadingIndicatorCircle(const char* label, const float indicator_radius, const ImVec4& main_color, const ImVec4& backdrop_color, const int circle_count, const float speed)
132 {
133  ImGuiWindow* window = ImGui::GetCurrentWindow();
134  if (window->SkipItems)
135  {
136  return;
137  }
138 
139  ImGuiContext& g = *GImGui;
140  const ImGuiID id = window->GetID(label);
141 
142  const ImVec2 pos = window->DC.CursorPos;
143  const float circle_radius = indicator_radius / 10.0f;
144  const ImRect bb(pos, ImVec2(pos.x + indicator_radius * 2.0f, pos.y + indicator_radius * 2.0f));
145  ImGui::ItemSize(bb, ImGui::GetStyle().FramePadding.y);
146  if (!ImGui::ItemAdd(bb, id))
147  {
148  return;
149  }
150 
151  const float t = g.Time;
152  const auto degree_offset = 2.0f * IM_PI / circle_count;
153 
154  for (int i = 0; i < circle_count; ++i)
155  {
156  const auto x = indicator_radius * std::sin(degree_offset * i);
157  const auto y = indicator_radius * std::cos(degree_offset * i);
158  const auto growth = std::max(0.0f, std::sin(t * speed - i * degree_offset));
159  ImVec4 color;
160  color.x = main_color.x * growth + backdrop_color.x * (1.0f - growth);
161  color.y = main_color.y * growth + backdrop_color.y * (1.0f - growth);
162  color.z = main_color.z * growth + backdrop_color.z * (1.0f - growth);
163  color.w = 1.0f;
164 
165  window->DrawList->AddCircleFilled(ImVec2(pos.x + indicator_radius + x,
166  pos.y + indicator_radius - y),
167  circle_radius + growth * circle_radius,
168  ImGui::GetColorU32(color));
169 
170  }
171 }
172 
173 //source: https://github.com/ocornut/imgui/issues/1982#issuecomment-408834301
174 void RoR::DrawImageRotated(ImTextureID tex_id, ImVec2 center, ImVec2 size, float angle)
175 {
176  ImDrawList* draw_list = ImGui::GetWindowDrawList();
177 
178  float cos_a = cosf(angle);
179  float sin_a = sinf(angle);
180  ImVec2 pos[4] =
181  {
182  center + ImRotate(ImVec2(-size.x * 0.5f, -size.y * 0.5f), cos_a, sin_a),
183  center + ImRotate(ImVec2(+size.x * 0.5f, -size.y * 0.5f), cos_a, sin_a),
184  center + ImRotate(ImVec2(+size.x * 0.5f, +size.y * 0.5f), cos_a, sin_a),
185  center + ImRotate(ImVec2(-size.x * 0.5f, +size.y * 0.5f), cos_a, sin_a)
186  };
187  ImVec2 uvs[4] =
188  {
189  ImVec2(0.0f, 0.0f),
190  ImVec2(1.0f, 0.0f),
191  ImVec2(1.0f, 1.0f),
192  ImVec2(0.0f, 1.0f)
193  };
194 
195  draw_list->AddImageQuad(tex_id, pos[0], pos[1], pos[2], pos[3], uvs[0], uvs[1], uvs[2], uvs[3], IM_COL32_WHITE);
196 }
197 
198 std::string RoR::StripColorMarksFromText(std::string const& text)
199 {
200  return std::regex_replace(text, TEXT_COLOR_REGEX, "");
201 }
202 
203 ImVec2 RoR::DrawColorMarkedText(ImDrawList* drawlist, ImVec2 text_cursor, ImVec4 default_color, float override_alpha, float wrap_width, std::string const& line)
204 {
205  ImTextFeeder feeder(drawlist, text_cursor);
206  int r,g,b, dark_r,dark_g,dark_b;
207  ColorToInts(default_color, r,g,b);
208  ColorToInts(App::GetGuiManager()->GetTheme().color_mark_max_darkness, dark_r, dark_g, dark_b);
209  std::smatch color_match;
210  std::string::const_iterator seg_start = line.begin();
211  while (std::regex_search(seg_start, line.end(), color_match, TEXT_COLOR_REGEX)) // Find next marker
212  {
213  // Print segment before the color marker (if any)
214  std::string::const_iterator seg_end = color_match[0].first;
215  if (seg_start != seg_end)
216  {
217  feeder.AddMultiline(ImColor(r,g,b,(int)(override_alpha*255)), wrap_width, &*seg_start, &*seg_end);
218  }
219  // Prepare for printing segment after color marker
220  sscanf(color_match.str(0).c_str(), "#%2x%2x%2x", &r, &g, &b);
221  if (r==0 && g==0 && b==0)
222  {
223  ColorToInts(default_color, r,g,b);
224  }
225  else if (r < dark_r && g < dark_g && b < dark_b)
226  {
227  // If below darkness limit, invert the color to lighen it up.
228  r = 255-r;
229  g = 255-g;
230  b = 255-b;
231  }
232  seg_start = color_match[0].second;
233  }
234 
235  // Print final segment (if any)
236  if (seg_start != line.begin() + line.length())
237  {
238  const char* end_ptr = &line.c_str()[line.length()];
239  feeder.AddMultiline(ImColor(r,g,b,(int)(override_alpha*255)), wrap_width, &*seg_start, end_ptr);
240  }
241 
242  return feeder.size;
243 }
244 
245 void RoR::ImTextWrappedColorMarked(std::string const& text)
246 {
247  ImVec2 text_pos = ImGui::GetCursorScreenPos();
248  ImVec2 text_size = RoR::DrawColorMarkedText(ImGui::GetWindowDrawList(),
249  text_pos,
250  ImGui::GetStyle().Colors[ImGuiCol_Text],
251  /*override_alpha=*/1.f,
252  ImGui::GetWindowContentRegionWidth() - ImGui::GetCursorPosX(),
253  text);
254  // From `ImGui::TextEx()` ...
255  ImRect bb(text_pos, text_pos + text_size);
256  ImGui::ItemSize(text_size);
257  ImGui::ItemAdd(bb, 0);
258 }
259 
260 bool RoR::DrawGCheckbox(CVar* cvar, const char* label)
261 {
262  bool val = cvar->getBool();
263  if (ImGui::Checkbox(label, &val))
264  {
265  cvar->setVal(val);
266  return true;
267  }
268  return false;
269 }
270 
271 void RoR::DrawGIntCheck(CVar* cvar, const char* label)
272 {
273  bool val = (cvar->getInt() != 0);
274  if (ImGui::Checkbox(label, &val))
275  {
276  cvar->setVal(val ? 1 : 0);
277  }
278 }
279 
280 void RoR::DrawGIntBox(CVar* cvar, const char* label)
281 {
282  int val = cvar->getInt();
283  if (ImGui::InputInt(label, &val, 1, 100, ImGuiInputTextFlags_EnterReturnsTrue))
284  {
285  cvar->setVal(val);
286  }
287 }
288 
289 void RoR::DrawGIntSlider(CVar* cvar, const char* label, int v_min, int v_max)
290 {
291  int val = cvar->getInt();
292 
293  if (ImGui::SliderInt(label, &val, v_min, v_max))
294  {
295  cvar->setVal(val);
296  }
297 }
298 
299 void RoR::DrawGFloatSlider(CVar* cvar, const char* label, float v_min, float v_max)
300 {
301  float val = cvar->getFloat();
302 
303  if (ImGui::SliderFloat(label, &val, v_min, v_max, "%.2f"))
304  {
305  cvar->setVal(val);
306  }
307 }
308 
309 void RoR::DrawGFloatBox(CVar* cvar, const char* label)
310 {
311  float fval = cvar->getFloat();
312  if (ImGui::InputFloat(label, &fval, 0.f, 0.f, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue))
313  {
314  cvar->setVal(fval);
315  }
316 }
317 
318 void RoR::DrawGTextEdit(CVar* cvar, const char* label, Str<1000>& buf)
319 {
320  if (ImGui::InputText(label, buf.GetBuffer(), buf.GetCapacity(), ImGuiInputTextFlags_EnterReturnsTrue))
321  {
322  cvar->setStr(buf.GetBuffer());
323  }
324  if (ImGui::IsItemActive())
325  {
326  ImGui::TextDisabled("(hit Enter key to submit)");
327  }
328  else
329  {
330  buf.Assign(cvar->getStr().c_str());
331  }
332 }
333 
334 void RoR::DrawGCombo(CVar* cvar, const char* label, const char* values)
335 {
336  int selection = cvar->getInt();
337  if (ImGui::Combo(label, &selection, values))
338  {
339  cvar->setVal(selection);
340  }
341 }
342 
343 Ogre::TexturePtr RoR::FetchIcon(const char* name)
344 {
345  try
346  {
347  return Ogre::static_pointer_cast<Ogre::Texture>(
348  Ogre::TextureManager::getSingleton().createOrRetrieve(name, "FlagsRG").first);
349  }
350  catch (...) {}
351 
352  return Ogre::TexturePtr(); // null
353 }
354 
356 {
357  ImVec2 screen_size = ImGui::GetIO().DisplaySize;
358 
359  // Dummy fullscreen window to draw to
360  int window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar| ImGuiWindowFlags_NoInputs
361  | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus;
362  ImGui::SetNextWindowPos(ImVec2(0,0));
363  ImGui::SetNextWindowSize(screen_size);
364  ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0,0,0,0)); // Fully transparent background!
365  ImGui::Begin("RoR_TransparentFullscreenWindow", NULL, window_flags);
366  ImDrawList* drawlist = ImGui::GetWindowDrawList();
367  ImGui::End();
368  ImGui::PopStyleColor(1); // WindowBg
369 
370  return drawlist;
371 }
372 
373 void RoR::ImAddItemToComboboxString(std::string& target, std::string const& item)
374 {
375  // Items must be separated by single NUL character ('\0').
376  // -------------------------------------------------------
377 
378  if (target == "")
379  {
380  target += item;
381  }
382  else
383  {
384  // Get current size (not counting trailing NUL)
385  size_t prev_size = target.size();
386 
387  // Make space for 1 separating NUL
388  target.resize(prev_size + 1, '\0');
389 
390  // Insert new item after the separator
391  target.insert(target.begin() + prev_size + 1, item.begin(), item.end());
392  }
393 }
394 
395 void RoR::ImTerminateComboboxString(std::string& target)
396 {
397  // Items must be separated by double NUL character ("\0\0").
398  // ---------------------------------------------------------
399 
400  // Get current size (not counting trailing NUL)
401  size_t prev_size = target.size();
402 
403  // Make space for 2 trailing with NULs
404  target.resize(prev_size + 2, '\0');
405 }
406 
408 {
409  ImVec4 col = ImGui::GetStyle().Colors[ImGuiCol_Text];
410  if (App::GetInputEngine()->getEventValue(input_event))
411  {
413  }
414  std::string text = App::GetInputEngine()->getKeyForCommand(input_event);
415  const ImVec2 PAD = ImVec2(2.f, 0.f);
416  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, PAD);
417  ImGui::BeginChildFrame(ImGuiID(input_event), ImGui::CalcTextSize(text.c_str()) + PAD*2);
418  ImGui::TextColored(col, "%s", text.c_str());
419  ImGui::EndChildFrame();
420  ImGui::PopStyleVar(); // FramePadding
421 
422 }
423 
424 void RoR::ImDrawModifierKeyHighlighted(OIS::KeyCode key)
425 {
426  ImVec4 col = ImGui::GetStyle().Colors[ImGuiCol_Text];
427  if (App::GetInputEngine()->isKeyDown(key))
428  {
430  }
431  std::string text = App::GetInputEngine()->getModifierKeyName(key);
432  const ImVec2 PAD = ImVec2(2.f, 0.f);
433  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, PAD);
434  ImGui::BeginChildFrame(ImGuiID(key), ImGui::CalcTextSize(text.c_str()) + PAD*2);
435  ImGui::TextColored(col, "%s", text.c_str());
436  ImGui::EndChildFrame();
437  ImGui::PopStyleVar(); // FramePadding
438 }
439 
440 bool RoR::ImButtonHoldToConfirm(const std::string& btn_idstr, const bool smallbutton, const float time_limit)
441 {
442  if (smallbutton)
443  ImGui::SmallButton(btn_idstr.c_str());
444  else
445  ImGui::Button(btn_idstr.c_str());
446 
447  // When recording the active button, take full ID stack into account
448  static const ImGuiID IMGUIID_INVALID = 0u;
449  static ImGuiID active_id = IMGUIID_INVALID;
450  static float active_time_left = 0.f;
451  const ImGuiID btn_id = ImGui::GetCurrentWindow()->GetID(btn_idstr.c_str());
452 
453  if (ImGui::IsItemActive())
454  {
455  if (active_id != btn_id)
456  {
457  active_id = btn_id;
458  active_time_left = time_limit;
459  }
460  else
461  {
462  active_time_left -= ImGui::GetIO().DeltaTime;
463  if (active_time_left <= 0.f)
464  {
465  active_id = IMGUIID_INVALID;
466  return true;
467  }
468  }
469 
470  ImGui::BeginTooltip();
471  std::string text = _L("Hold to confirm");
472  ImGui::TextDisabled(text.c_str());
473  ImGui::ProgressBar(active_time_left/time_limit, ImVec2(ImGui::CalcTextSize(text.c_str()).x, 8.f), "");
474  ImGui::EndTooltip();
475  }
476  else if (btn_id == active_id)
477  {
478  active_id = IMGUIID_INVALID;
479  }
480 
481  return false;
482 }
TEXT_COLOR_MAX_LEN
static const int TEXT_COLOR_MAX_LEN
Definition: GUIUtils.cpp:29
y
float y
Definition: (ValueTypes) quaternion.h:6
RoR::ImTextWrappedColorMarked
void ImTextWrappedColorMarked(std::string const &text)
Prints multiline text with '#rrggbb' color markers. Behaves like ImGui::Text* functions.
Definition: GUIUtils.cpp:245
RoR::ImAddItemToComboboxString
void ImAddItemToComboboxString(std::string &target, std::string const &item)
Definition: GUIUtils.cpp:373
ColorToInts
void ColorToInts(ImVec4 v, int &r, int &g, int &b)
Definition: GUIUtils.cpp:128
RoR::StripColorMarksFromText
std::string StripColorMarksFromText(std::string const &text)
Definition: GUIUtils.cpp:198
RoR::DrawGFloatSlider
void DrawGFloatSlider(CVar *cvar, const char *label, float v_min, float v_max)
Definition: GUIUtils.cpp:299
RoR::FetchIcon
Ogre::TexturePtr FetchIcon(const char *name)
Definition: GUIUtils.cpp:343
RoR::Str::Assign
Str & Assign(const char *src)
Definition: Str.h:55
RoR::ImTextFeeder::cursor
ImVec2 cursor
Next draw position, screen space.
Definition: GUIUtils.h:40
RoR::ImTextFeeder::AddMultiline
void AddMultiline(ImU32 color, float wrap_width, const char *text, const char *text_end)
Wraps substrings separated by blanks. wrap_width=-1.f disables wrapping.
Definition: GUIUtils.cpp:70
RoR::Str::GetBuffer
char * GetBuffer()
Definition: Str.h:48
RoR::DrawGCombo
void DrawGCombo(CVar *cvar, const char *label, const char *values)
Definition: GUIUtils.cpp:334
RoR::App::GetGuiManager
GUIManager * GetGuiManager()
Definition: Application.cpp:268
RoR::DrawGTextEdit
void DrawGTextEdit(CVar *cvar, const char *label, Str< 1000 > &buf)
Definition: GUIUtils.cpp:318
RoR::DrawGIntBox
void DrawGIntBox(CVar *cvar, const char *label)
Definition: GUIUtils.cpp:280
RoR::ImTextFeeder::size
ImVec2 size
Accumulated text size.
Definition: GUIUtils.h:42
RoR::DrawColorMarkedText
ImVec2 DrawColorMarkedText(ImDrawList *drawlist, ImVec2 text_cursor, ImVec4 default_color, float override_alpha, float wrap_width, std::string const &line)
Draw multiline text with '#rrggbb' color markers. Returns total text size.
Definition: GUIUtils.cpp:203
GUIUtils.h
RoR::ImDrawModifierKeyHighlighted
void ImDrawModifierKeyHighlighted(OIS::KeyCode key)
Definition: GUIUtils.cpp:424
RoR::Str::GetCapacity
size_t GetCapacity() const
Definition: Str.h:49
RoR::CVar::getBool
bool getBool() const
Definition: CVar.h:98
RoR::ImTextFeeder::AddInline
void AddInline(ImU32 color, ImVec2 text_size, const char *text, const char *text_end)
No wrapping or trimming.
Definition: GUIUtils.cpp:34
RoR::InputEngine::getKeyForCommand
Ogre::String getKeyForCommand(int eventID)
Definition: InputEngine.cpp:2181
RoR::DrawGFloatBox
void DrawGFloatBox(CVar *cvar, const char *label)
Definition: GUIUtils.cpp:309
RoR::ImTextFeeder::NextLine
void NextLine()
Definition: GUIUtils.cpp:116
RoR::DrawGIntSlider
void DrawGIntSlider(CVar *cvar, const char *label, int v_min, int v_max)
Definition: GUIUtils.cpp:289
RoR::ImTextFeeder
Helper for drawing multiline wrapped & colored text.
Definition: GUIUtils.h:27
Actor.h
RoR::GUIManager::GetTheme
GuiTheme & GetTheme()
Definition: GUIManager.h:158
RoR::CVar::getStr
std::string const & getStr() const
Definition: CVar.h:95
RoR::Str< 1000 >
RoR::GetImDummyFullscreenWindow
ImDrawList * GetImDummyFullscreenWindow()
Definition: GUIUtils.cpp:355
RoR::ImButtonHoldToConfirm
bool ImButtonHoldToConfirm(const std::string &btn_idstr, const bool smallbutton, const float time_limit)
Definition: GUIUtils.cpp:440
RoR::DrawGIntCheck
void DrawGIntCheck(CVar *cvar, const char *label)
Definition: GUIUtils.cpp:271
RoR::CVar
Quake-style console variable, defined in RoR.cfg or crated via Console UI and scripts.
Definition: CVar.h:52
RoR::ImTextFeeder::AddWrapped
void AddWrapped(ImU32 color, float wrap_width, const char *text, const char *text_end)
Wraps entire input. Trims leading blanks on extra lines. wrap_width=-1.f disables wrapping.
Definition: GUIUtils.cpp:42
RoR::CVar::setVal
void setVal(T val)
Definition: CVar.h:72
_L
#define _L
Definition: ErrorUtils.cpp:34
RoR::GUIManager::GuiTheme::highlight_text_color
ImVec4 highlight_text_color
Definition: GUIManager.h:78
RoR::App::GetInputEngine
InputEngine * GetInputEngine()
Definition: Application.cpp:270
RoR::ImTerminateComboboxString
void ImTerminateComboboxString(std::string &target)
Definition: GUIUtils.cpp:395
RoR::InputEngine::getModifierKeyName
Ogre::String getModifierKeyName(OIS::KeyCode key)
Definition: InputEngine.cpp:2194
RoR::CVar::getFloat
float getFloat() const
Definition: CVar.h:96
RoR::DrawGCheckbox
bool DrawGCheckbox(CVar *cvar, const char *label)
Definition: GUIUtils.cpp:260
RoR::CVar::getInt
int getInt() const
Definition: CVar.h:97
RoR::ImDrawEventHighlighted
void ImDrawEventHighlighted(events input_event)
Definition: GUIUtils.cpp:407
TEXT_COLOR_REGEX
static const std::regex TEXT_COLOR_REGEX
Definition: GUIUtils.cpp:28
RoR::events
events
Definition: InputEngine.h:74
RoR::ImTextFeeder::drawlist
ImDrawList * drawlist
Definition: GUIUtils.h:39
RoR::LoadingIndicatorCircle
void LoadingIndicatorCircle(const char *label, const float indicator_radius, const ImVec4 &main_color, const ImVec4 &backdrop_color, const int circle_count, const float speed)
Draws animated loading spinner.
Definition: GUIUtils.cpp:131
x
float x
Definition: (ValueTypes) quaternion.h:5
RoR::DrawImageRotated
void DrawImageRotated(ImTextureID tex_id, ImVec2 center, ImVec2 size, float angle)
Add rotated textured quad to ImDrawList, source: https://github.com/ocornut/imgui/issues/1982#issueco...
Definition: GUIUtils.cpp:174
RoR::CVar::setStr
void setStr(std::string const &str)
Definition: CVar.h:83