7#include "absl/strings/str_cat.h"
8#include "absl/strings/str_format.h"
13#include "imgui/imgui.h"
14#include "imgui/imgui_internal.h"
17#include <TargetConditionals.h>
20#if defined(__APPLE__) && TARGET_OS_IOS == 1
36std::string
ColumnLabel(absl::string_view text, absl::string_view stable_id) {
37 return absl::StrCat(text,
"###", stable_id);
104 theme.compact_factor;
109#if defined(__APPLE__) && TARGET_OS_IOS == 1
111 insets.left = ios_insets.left;
112 insets.right = ios_insets.right;
113 insets.top = ios_insets.top;
114 insets.bottom = ios_insets.bottom;
125#if defined(__APPLE__) && TARGET_OS_IOS == 1
132 ImGuiIO& io = ImGui::GetIO();
133 return (io.ConfigFlags & ImGuiConfigFlags_IsTouchScreen) != 0;
145 const ImVec2& pos,
const ImVec2& size,
const ImVec2& rect_pos,
146 const ImVec2& rect_size,
float min_visible) {
149 if (rect_size.x <= 0.0f || rect_size.y <= 0.0f) {
153 const float max_visible_x = std::max(1.0f, size.x - 1.0f);
154 const float max_visible_y = std::max(1.0f, size.y - 1.0f);
155 float min_visible_x = std::min(min_visible, max_visible_x);
156 float min_visible_y = std::min(min_visible, max_visible_y);
159 min_visible_x = std::min(min_visible_x, rect_size.x * 0.5f);
160 min_visible_y = std::min(min_visible_y, rect_size.y * 0.5f);
162 const float min_x = rect_pos.x + min_visible_x - size.x;
163 const float max_x = rect_pos.x + rect_size.x - min_visible_x;
164 const float min_y = rect_pos.y + min_visible_y - size.y;
165 const float max_y = rect_pos.y + rect_size.y - min_visible_y;
167 result.pos.x = std::clamp(pos.x, min_x, max_x);
168 result.pos.y = std::clamp(pos.y, min_y, max_y);
169 result.clamped = (result.pos.x != pos.x) || (result.pos.y != pos.y);
175 if (padding < 0.0f) {
178 ImGui::BeginChild(label, ImVec2(0, 0),
true);
179 ImGui::Dummy(ImVec2(padding, padding));
182 ImGui::Dummy(ImVec2(0, padding));
194 ImGuiTableFlags flags,
195 const ImVec2& outer_size,
200 ImGui::PushStyleColor(ImGuiCol_TableHeaderBg,
202 ImGui::PushStyleColor(ImGuiCol_TableBorderStrong,
204 ImGui::PushStyleColor(ImGuiCol_TableBorderLight,
206 ImGui::PushStyleColor(ImGuiCol_TableRowBg,
208 ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt,
214 ImVec2 cell_padding = ImGui::GetStyle().CellPadding;
215 if (!(flags & ImGuiTableFlags_NoHostExtendY)) {
218 ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cell_padding);
220 if (!ImGui::BeginTable(str_id, columns, flags, outer_size, inner_width)) {
223 ImGui::PopStyleVar(kThemedTableVarCount);
224 ImGui::PopStyleColor(kThemedTableColorCount);
232 ImGui::PopStyleVar(kThemedTableVarCount);
233 ImGui::PopStyleColor(kThemedTableColorCount);
240 ImGui::PushStyleColor(ImGuiCol_ChildBg,
242 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
245 ImGui::BeginChild(label, *canvas_size,
true);
247 ImGui::BeginChild(label, ImVec2(0, 0),
true);
253 ImGui::PopStyleVar(1);
254 ImGui::PopStyleColor(1);
258 bool border, ImGuiWindowFlags flags) {
260 return ImGui::BeginChild(
id, size, border, flags);
266 ImGuiInputTextFlags flags) {
268 return ImGui::InputText(label, buf, buf_size, flags);
273 ImGuiInputTextFlags flags) {
275 return ImGui::InputInt(label, v, step, step_fast, flags);
279 float step_fast,
const char* format,
280 ImGuiInputTextFlags flags) {
282 return ImGui::InputFloat(label, v, step, step_fast, format, flags);
289 ImGui::AlignTextToFramePadding();
290 ImGui::Text(
"%s", label);
294 ImGui::SetNextItemWidth(input_width);
297 snprintf(buf,
sizeof(buf),
"%02X", *data);
299 bool changed = ImGui::InputText(
300 (
"##" + std::string(label)).c_str(), buf,
sizeof(buf),
301 ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_AutoSelectAll);
305 if (sscanf(buf,
"%X", &temp) == 1) {
306 *data =
static_cast<uint8_t
>(temp & 0xFF);
316 ImGui::AlignTextToFramePadding();
317 ImGui::Text(
"%s", label);
321 ImGui::SetNextItemWidth(input_width);
324 snprintf(buf,
sizeof(buf),
"%04X", *data);
326 bool changed = ImGui::InputText(
327 (
"##" + std::string(label)).c_str(), buf,
sizeof(buf),
328 ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_AutoSelectAll);
332 if (sscanf(buf,
"%X", &temp) == 1) {
333 *data =
static_cast<uint16_t
>(temp & 0xFFFF);
343 float compact_width =
345 ImGui::SetNextItemWidth(compact_width);
347 return ImGui::InputText(label, buf, buf_size,
348 ImGuiInputTextFlags_AutoSelectAll);
354 ImGui::PushStyleColor(ImGuiCol_ChildBg,
356 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
362 const float min_height =
367 label, ImVec2(0, height),
true,
368 ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
372 ImGuiContext* ctx = ImGui::GetCurrentContext();
373 const bool has_child_window =
374 ctx !=
nullptr && ctx->CurrentWindow !=
nullptr &&
375 ((ctx->CurrentWindow->Flags & ImGuiWindowFlags_ChildWindow) != 0);
379 if (has_child_window) {
383 if (ctx !=
nullptr && ctx->StyleVarStack.Size > 0) {
384 ImGui::PopStyleVar(1);
386 if (ctx !=
nullptr && ctx->ColorStack.Size > 0) {
387 ImGui::PopStyleColor(1);
395 ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
403 ImVec2 effective_size = size;
404 if (min_touch > 0.0f) {
405 effective_size.x = std::max(effective_size.x, min_touch);
406 effective_size.y = std::max(effective_size.y, min_touch);
408 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
410 bool result = ImGui::Button(label, effective_size);
411 ImGui::PopStyleVar(1);
417 std::function<
void()> widget_callback) {
418 ImGui::TableNextRow();
419 ImGui::TableSetColumnIndex(0);
420 ImGui::AlignTextToFramePadding();
421 ImGui::Text(
"%s", label);
422 ImGui::TableSetColumnIndex(1);
423 ImGui::SetNextItemWidth(-1);
430 ImGui::SeparatorText(label);
431 ImGui::PopStyleColor(1);
435 ImGui::TextDisabled(
"(?)");
436 if (ImGui::BeginItemTooltip()) {
437 ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
438 ImGui::TextUnformatted(desc);
439 ImGui::PopTextWrapPos();
static float GetHexInputWidth()
static WindowClampResult ClampWindowToRect(const ImVec2 &pos, const ImVec2 &size, const ImVec2 &rect_pos, const ImVec2 &rect_size, float min_visible=32.0f)
static float GetMinTouchTarget()
static float GetSliderWidth()
static void SectionHeader(const char *label)
static float GetPanelPadding()
static float GetTouchSafeWidgetHeight()
static void ToolbarSeparator()
static bool BeginContentChild(const char *id, const ImVec2 &min_size, bool border=false, ImGuiWindowFlags flags=0)
static void BeginToolbar(const char *label)
static float GetCompactInputWidth()
static float GetCanvasToolbarHeight()
static void EndPaddedPanel()
static void EndTableWithTheming()
static float GetComboWidth()
static void HelpMarker(const char *desc)
static float GetTableRowHeight()
static const Theme & GetTheme()
static float GetStandardInputWidth()
static SafeAreaInsets GetSafeAreaInsets()
static bool AutoSizedInputFloat(const char *label, float *v, float step=0.0f, float step_fast=0.0f, const char *format="%.3f", ImGuiInputTextFlags flags=0)
static bool AutoSizedInputInt(const char *label, int *v, int step=1, int step_fast=100, ImGuiInputTextFlags flags=0)
static bool InputToolbarField(const char *label, char *buf, size_t buf_size)
static void BeginCanvasPanel(const char *label, ImVec2 *canvas_size=nullptr)
static void PropertyRow(const char *label, std::function< void()> widget_callback)
static float GetBaseFontSize()
static float GetTopInset()
static float GetButtonPadding()
static float GetToolbarHeight()
static void BeginPaddedPanel(const char *label, float padding=-1.0f)
static bool ToolbarButton(const char *label, const ImVec2 &size=ImVec2(0, 0))
static bool InputHexRow(const char *label, uint8_t *data)
static float GetStandardWidgetHeight()
static float GetStandardSpacing()
static bool BeginTableWithTheming(const char *str_id, int columns, ImGuiTableFlags flags=0, const ImVec2 &outer_size=ImVec2(0, 0), float inner_width=0.0f)
static void EndCanvasPanel()
static bool AutoSizedInputField(const char *label, char *buf, size_t buf_size, ImGuiInputTextFlags flags=0)
static bool IsTouchDevice()
constexpr int kThemedTableVarCount
constexpr int kThemedTableColorCount
ImVec4 ConvertColorToImVec4(const Color &color)
std::string ColumnLabel(absl::string_view text, absl::string_view stable_id)
ImVec2 GetContentRegionAvailClamped(const ImVec2 &min_size)
Returns content region available size clamped to a minimum.
float input_width_multiplier