"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "imgui_widgets.cpp" between
imgui-1.86.tar.gz and imgui-1.87.tar.gz

About: Dear ImGui is a bloat-free Graphical User Interface for C++ with minimal dependencies.

imgui_widgets.cpp  (imgui-1.86):imgui_widgets.cpp  (imgui-1.87)
// dear imgui, v1.86 // dear imgui, v1.87
// (widgets code) // (widgets code)
/* /*
Index of this file: Index of this file:
// [SECTION] Forward Declarations // [SECTION] Forward Declarations
// [SECTION] Widgets: Text, etc. // [SECTION] Widgets: Text, etc.
// [SECTION] Widgets: Main (Button, Image, Checkbox, RadioButton, ProgressBar, B ullet, etc.) // [SECTION] Widgets: Main (Button, Image, Checkbox, RadioButton, ProgressBar, B ullet, etc.)
// [SECTION] Widgets: Low-level Layout helpers (Spacing, Dummy, NewLine, Separat or, etc.) // [SECTION] Widgets: Low-level Layout helpers (Spacing, Dummy, NewLine, Separat or, etc.)
skipping to change at line 734 skipping to change at line 734
g.Style.FramePadding.y = 0.0f; g.Style.FramePadding.y = 0.0f;
bool pressed = ButtonEx(label, ImVec2(0, 0), ImGuiButtonFlags_AlignTextBaseL ine); bool pressed = ButtonEx(label, ImVec2(0, 0), ImGuiButtonFlags_AlignTextBaseL ine);
g.Style.FramePadding.y = backup_padding_y; g.Style.FramePadding.y = backup_padding_y;
return pressed; return pressed;
} }
// Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. // Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack.
// Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id)
bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut tonFlags flags) bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut tonFlags flags)
{ {
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
return false; return false;
// Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size. // Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size.
IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f); IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f);
const ImGuiID id = window->GetID(str_id); const ImGuiID id = window->GetID(str_id);
ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
ItemSize(size); ItemSize(size);
if (!ItemAdd(bb, id)) if (!ItemAdd(bb, id))
return false; return false;
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags);
return pressed; return pressed;
} }
bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu ttonFlags flags) bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu ttonFlags flags)
{ {
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
return false; return false;
ImGuiContext& g = *GImGui;
const ImGuiID id = window->GetID(str_id); const ImGuiID id = window->GetID(str_id);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
const float default_size = GetFrameHeight(); const float default_size = GetFrameHeight();
ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f); ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f);
if (!ItemAdd(bb, id)) if (!ItemAdd(bb, id))
return false; return false;
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
flags |= ImGuiButtonFlags_Repeat; flags |= ImGuiButtonFlags_Repeat;
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
// Render // Render
const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
const ImU32 text_col = GetColorU32(ImGuiCol_Text); const ImU32 text_col = GetColorU32(ImGuiCol_Text);
RenderNavHighlight(bb, id); RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding); RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding);
RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSi ze) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir); RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSi ze) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir);
IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags);
return pressed; return pressed;
} }
bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir) bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir)
{ {
float sz = GetFrameHeight(); float sz = GetFrameHeight();
return ArrowButtonEx(str_id, dir, ImVec2(sz, sz), ImGuiButtonFlags_None); return ArrowButtonEx(str_id, dir, ImVec2(sz, sz), ImGuiButtonFlags_None);
} }
// Button to close a window // Button to close a window
skipping to change at line 1995 skipping to change at line 1998
if (op == '+') { *(double*)output = *(const double*)arg1 + *(const d ouble*)arg2; } if (op == '+') { *(double*)output = *(const double*)arg1 + *(const d ouble*)arg2; }
if (op == '-') { *(double*)output = *(const double*)arg1 - *(const d ouble*)arg2; } if (op == '-') { *(double*)output = *(const double*)arg1 - *(const d ouble*)arg2; }
return; return;
case ImGuiDataType_COUNT: break; case ImGuiDataType_COUNT: break;
} }
IM_ASSERT(0); IM_ASSERT(0);
} }
// User can input math operators (e.g. +100) to edit a numerical values. // User can input math operators (e.g. +100) to edit a numerical values.
// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. // NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b uf, ImGuiDataType data_type, void* p_data, const char* format) bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void * p_data, const char* format)
{ {
while (ImCharIsBlankA(*buf)) while (ImCharIsBlankA(*buf))
buf++; buf++;
// We don't support '-' op because it would conflict with inputing negative
value.
// Instead you can use +-100 to subtract from an existing value
char op = buf[0];
if (op == '+' || op == '*' || op == '/')
{
buf++;
while (ImCharIsBlankA(*buf))
buf++;
}
else
{
op = 0;
}
if (!buf[0]) if (!buf[0])
return false; return false;
// Copy the value in an opaque buffer so we can compare at the end of the fu nction if it changed at all. // Copy the value in an opaque buffer so we can compare at the end of the fu nction if it changed at all.
const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type);
ImGuiDataTypeTempStorage data_backup; ImGuiDataTypeTempStorage data_backup;
memcpy(&data_backup, p_data, type_info->Size); memcpy(&data_backup, p_data, type_info->Size);
if (format == NULL) if (format == NULL)
format = type_info->ScanFmt; format = type_info->ScanFmt;
// FIXME-LEGACY: The aim is to remove those operators and write a proper exp if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32 || data
ression evaluator at some point.. _type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64 || data_type == ImG
int arg1i = 0; uiDataType_Float || data_type == ImGuiDataType_Double)
if (data_type == ImGuiDataType_S32)
{
int* v = (int*)p_data;
int arg0i = *v;
float arg1f = 0.0f;
if (op && sscanf(initial_value_buf, format, &arg0i) < 1)
return false;
// Store operand in a float so we can use fractional value for multiplie
rs (*1.1), but constant always parsed as integer so we can fit big integers (e.g
. 2000000003) past float precision
if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (int)(arg0i +
arg1i); } // Add (use "+-" to subtract)
else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (int)(arg0i *
arg1f); } // Multiply
else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v
= (int)(arg0i / arg1f); } // Divide
else { if (sscanf(buf, format, &arg1i) == 1) *v = arg1i;
} // Assign constant
}
else if (data_type == ImGuiDataType_Float)
{
// For floats we have to ignore format with precision (e.g. "%.2f") beca
use sscanf doesn't take them in
format = "%f";
float* v = (float*)p_data;
float arg0f = *v, arg1f = 0.0f;
if (op && sscanf(initial_value_buf, format, &arg0f) < 1)
return false;
if (sscanf(buf, format, &arg1f) < 1)
return false;
if (op == '+') { *v = arg0f + arg1f; } // Add (u
se "+-" to subtract)
else if (op == '*') { *v = arg0f * arg1f; } // Multip
ly
else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide
else { *v = arg1f; } // Assign
constant
}
else if (data_type == ImGuiDataType_Double)
{
format = "%lf"; // scanf differentiate float/double unlike printf which
forces everything to double because of ellipsis
double* v = (double*)p_data;
double arg0f = *v, arg1f = 0.0;
if (op && sscanf(initial_value_buf, format, &arg0f) < 1)
return false;
if (sscanf(buf, format, &arg1f) < 1)
return false;
if (op == '+') { *v = arg0f + arg1f; } // Add (u
se "+-" to subtract)
else if (op == '*') { *v = arg0f * arg1f; } // Multip
ly
else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide
else { *v = arg1f; } // Assign
constant
}
else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 ||
data_type == ImGuiDataType_U64)
{ {
// All other types assign constant // For float/double we have to ignore format with precision (e.g. "%.2f"
// We don't bother handling support for legacy operators since they are ) because sscanf doesn't take them in, so force them into %f and %lf
a little too crappy. Instead we will later implement a proper expression evaluat if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Doubl
or in the future. e)
format = type_info->ScanFmt;
if (sscanf(buf, format, p_data) < 1) if (sscanf(buf, format, p_data) < 1)
return false; return false;
} }
else else
{ {
// Small types need a 32-bit buffer to receive the result from scanf() // Small types need a 32-bit buffer to receive the result from scanf()
int v32; int v32;
if (sscanf(buf, format, &v32) < 1) if (sscanf(buf, format, &v32) < 1)
return false; return false;
if (data_type == ImGuiDataType_S8) if (data_type == ImGuiDataType_S8)
skipping to change at line 3390 skipping to change at line 3336
g.TempInputId = g.ActiveId; g.TempInputId = g.ActiveId;
} }
return value_changed; return value_changed;
} }
// Note that Drag/Slider functions are only forwarding the min/max values clampi ng values if the ImGuiSliderFlags_AlwaysClamp flag is set! // Note that Drag/Slider functions are only forwarding the min/max values clampi ng values if the ImGuiSliderFlags_AlwaysClamp flag is set!
// This is intended: this way we allow CTRL+Click manual input to set a value ou t of bounds, for maximum flexibility. // This is intended: this way we allow CTRL+Click manual input to set a value ou t of bounds, for maximum flexibility.
// However this may not be ideal for all uses, as some user code may break on ou t of bound values. // However this may not be ideal for all uses, as some user code may break on ou t of bound values.
bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG uiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max) bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG uiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max)
{ {
ImGuiContext& g = *GImGui;
char fmt_buf[32]; char fmt_buf[32];
char data_buf[32]; char data_buf[32];
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf) ); format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf) );
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, fo rmat); DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, fo rmat);
ImStrTrimBlanks(data_buf); ImStrTrimBlanks(data_buf);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTe xtFlags_NoMarkEdited; ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTe xtFlags_NoMarkEdited;
flags |= ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Do uble) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); flags |= ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Do uble) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
bool value_changed = false; bool value_changed = false;
if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags)) if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags))
{ {
// Backup old value // Backup old value
size_t data_type_size = DataTypeGetInfo(data_type)->Size; size_t data_type_size = DataTypeGetInfo(data_type)->Size;
ImGuiDataTypeTempStorage data_backup; ImGuiDataTypeTempStorage data_backup;
memcpy(&data_backup, p_data, data_type_size); memcpy(&data_backup, p_data, data_type_size);
// Apply new value (or operations) then clamp // Apply new value (or operations) then clamp
DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, da ta_type, p_data, NULL); DataTypeApplyFromText(data_buf, data_type, p_data, NULL);
if (p_clamp_min || p_clamp_max) if (p_clamp_min || p_clamp_max)
{ {
if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp _min, p_clamp_max) > 0) if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp _min, p_clamp_max) > 0)
ImSwap(p_clamp_min, p_clamp_max); ImSwap(p_clamp_min, p_clamp_max);
DataTypeClamp(data_type, p_data, p_clamp_min, p_clamp_max); DataTypeClamp(data_type, p_data, p_clamp_min, p_clamp_max);
} }
// Only mark as edited if new value is different // Only mark as edited if new value is different
value_changed = memcmp(&data_backup, p_data, data_type_size) != 0; value_changed = memcmp(&data_backup, p_data, data_type_size) != 0;
if (value_changed) if (value_changed)
skipping to change at line 3456 skipping to change at line 3400
flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ours elves by comparing the actual data rather than the string. flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ours elves by comparing the actual data rather than the string.
if (p_step != NULL) if (p_step != NULL)
{ {
const float button_size = GetFrameHeight(); const float button_size = GetFrameHeight();
BeginGroup(); // The only purpose of the group here is to allow the call er to query item data e.g. IsItemActive() BeginGroup(); // The only purpose of the group here is to allow the call er to query item data e.g. IsItemActive()
PushID(label); PushID(label);
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.Item InnerSpacing.x) * 2)); SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.Item InnerSpacing.x) * 2));
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.Initia lTextA.Data, data_type, p_data, format); value_changed = DataTypeApplyFromText(buf, data_type, p_data, format );
// Step buttons // Step buttons
const ImVec2 backup_frame_padding = style.FramePadding; const ImVec2 backup_frame_padding = style.FramePadding;
style.FramePadding.x = style.FramePadding.y; style.FramePadding.x = style.FramePadding.y;
ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFla gs_DontClosePopups; ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFla gs_DontClosePopups;
if (flags & ImGuiInputTextFlags_ReadOnly) if (flags & ImGuiInputTextFlags_ReadOnly)
BeginDisabled(); BeginDisabled();
SameLine(0, style.ItemInnerSpacing.x); SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("-", ImVec2(button_size, button_size), button_flags)) if (ButtonEx("-", ImVec2(button_size, button_size), button_flags))
{ {
skipping to change at line 3493 skipping to change at line 3437
TextEx(label, label_end); TextEx(label, label_end);
} }
style.FramePadding = backup_frame_padding; style.FramePadding = backup_frame_padding;
PopID(); PopID();
EndGroup(); EndGroup();
} }
else else
{ {
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.Initia lTextA.Data, data_type, p_data, format); value_changed = DataTypeApplyFromText(buf, data_type, p_data, format );
} }
if (value_changed) if (value_changed)
MarkItemEdited(g.LastItemData.ID); MarkItemEdited(g.LastItemData.ID);
return value_changed; return value_changed;
} }
bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_dat a, int components, const void* p_step, const void* p_step_fast, const char* form at, ImGuiInputTextFlags flags) bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_dat a, int components, const void* p_step, const void* p_step_fast, const char* form at, ImGuiInputTextFlags flags)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
skipping to change at line 4120 skipping to change at line 4064
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
FocusWindow(window); FocusWindow(window);
// Declare our inputs // Declare our inputs
IM_ASSERT(ImGuiNavInput_COUNT < 32); IM_ASSERT(ImGuiNavInput_COUNT < 32);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right ); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right );
if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory))
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Dow n); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Dow n);
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Home) | ((ImU64)1 < SetActiveIdUsingKey(ImGuiKey_Home);
< ImGuiKey_End); SetActiveIdUsingKey(ImGuiKey_End);
if (is_multiline) if (is_multiline)
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU {
64)1 << ImGuiKey_PageDown); SetActiveIdUsingKey(ImGuiKey_PageUp);
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlag SetActiveIdUsingKey(ImGuiKey_PageDown);
s_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t charact }
er. if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlag
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Tab); s_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t characte
r.
{
SetActiveIdUsingKey(ImGuiKey_Tab);
}
} }
// We have an edge case if ActiveId was set through another widget (e.g. wid get being swapped), clear id immediately (don't wait until the end of the functi on) // We have an edge case if ActiveId was set through another widget (e.g. wid get being swapped), clear id immediately (don't wait until the end of the functi on)
if (g.ActiveId == id && state == NULL) if (g.ActiveId == id && state == NULL)
ClearActiveID(); ClearActiveID();
// Release focus when we click outside // Release focus when we click outside
if (g.ActiveId == id && io.MouseClicked[0] && !init_state && !init_make_acti ve) //-V560 if (g.ActiveId == id && io.MouseClicked[0] && !init_state && !init_make_acti ve) //-V560
clear_active_id = true; clear_active_id = true;
skipping to change at line 4254 skipping to change at line 4204
stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y); stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y);
state->CursorAnimReset(); state->CursorAnimReset();
state->CursorFollow = true; state->CursorFollow = true;
} }
if (state->SelectedAllMouseLock && !io.MouseDown[0]) if (state->SelectedAllMouseLock && !io.MouseDown[0])
state->SelectedAllMouseLock = false; state->SelectedAllMouseLock = false;
// It is ill-defined whether the backend needs to send a \t character wh en pressing the TAB keys. // It is ill-defined whether the backend needs to send a \t character wh en pressing the TAB keys.
// Win32 and GLFW naturally do it but not SDL. // Win32 and GLFW naturally do it but not SDL.
const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper);
if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGui Key_Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly) if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressed(ImGuiKey _Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly)
if (!io.InputQueueCharacters.contains('\t')) if (!io.InputQueueCharacters.contains('\t'))
{ {
unsigned int c = '\t'; // Insert TAB unsigned int c = '\t'; // Insert TAB
if (InputTextFilterCharacter(&c, flags, callback, callback_user_ data, ImGuiInputSource_Keyboard)) if (InputTextFilterCharacter(&c, flags, callback, callback_user_ data, ImGuiInputSource_Keyboard))
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
// Process regular text input (before we check for Return because using some IME will effectively send a Return?) // Process regular text input (before we check for Return because using some IME will effectively send a Return?)
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards ( e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards ( e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
if (io.InputQueueCharacters.Size > 0) if (io.InputQueueCharacters.Size > 0)
skipping to change at line 4301 skipping to change at line 4251
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
const bool is_osx = io.ConfigMacOSXBehaviors; const bool is_osx = io.ConfigMacOSXBehaviors;
const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyMod Flags_Super | ImGuiKeyModFlags_Shift)); const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyMod Flags_Super | ImGuiKeyModFlags_Shift));
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl & & !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead o f Home/End const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl & & !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead o f Home/End
const bool is_ctrl_key_only = (io.KeyMods == ImGuiKeyModFlags_Ctrl); const bool is_ctrl_key_only = (io.KeyMods == ImGuiKeyModFlags_Ctrl);
const bool is_shift_key_only = (io.KeyMods == ImGuiKeyModFlags_Shift); const bool is_shift_key_only = (io.KeyMods == ImGuiKeyModFlags_Shift);
const bool is_shortcut_key = g.IO.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl); const bool is_shortcut_key = g.IO.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl);
const bool is_cut = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_X)) const bool is_cut = ((is_shortcut_key && IsKeyPressed(ImGuiKey_X)) ||
|| (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && !is_readonly && ! (is_shift_key_only && IsKeyPressed(ImGuiKey_Delete))) && !is_readonly && !is_pas
is_password && (!is_multiline || state->HasSelection()); sword && (!is_multiline || state->HasSelection());
const bool is_copy = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_C)) const bool is_copy = ((is_shortcut_key && IsKeyPressed(ImGuiKey_C)) ||
|| (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && ( (is_ctrl_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_password && (!is_mu
!is_multiline || state->HasSelection()); ltiline || state->HasSelection());
const bool is_paste = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_V)) const bool is_paste = ((is_shortcut_key && IsKeyPressed(ImGuiKey_V)) ||
|| (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_readonly; (is_shift_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_readonly;
const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) const bool is_undo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Z)) &&
&& !is_readonly && is_undoable); !is_readonly && is_undoable);
const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) const bool is_redo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Y)) ||
|| (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && !is_readonly && is (is_osx_shift_shortcut && IsKeyPressed(ImGuiKey_Z))) && !is_readonly && is_undoa
_undoable; ble;
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it i sn't very useful. // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it i sn't very useful.
const bool is_validate_enter = IsKeyPressedMap(ImGuiKey_Enter) || IsKeyP const bool is_validate_enter = IsKeyPressed(ImGuiKey_Enter) || IsKeyPres
ressedMap(ImGuiKey_KeyPadEnter); sed(ImGuiKey_KeypadEnter);
const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImG const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImG
uiInputReadMode_Pressed) && !IsKeyPressedMap(ImGuiKey_Space)) || IsNavInputTest( uiInputReadMode_Pressed) && !IsKeyPressed(ImGuiKey_Space)) || IsNavInputTest(ImG
ImGuiNavInput_Input, ImGuiInputReadMode_Pressed); uiNavInput_Input, ImGuiInputReadMode_Pressed);
const bool is_cancel = IsKeyPressedMap(ImGuiKey_Escape) || IsNavInputT const bool is_cancel = IsKeyPressed(ImGuiKey_Escape) || IsNavInputTest
est(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed); (ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed);
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state- if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->On
>OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key KeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_do
_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } wn ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state- else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->On
>OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_d KeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down
own ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.Ke
.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f yCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f));
)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB
STB_TEXTEDIT_K_UP) | k_mask); } _TEXTEDIT_K_UP) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io else if (IsKeyPressed(ImGuiKey_DownArrow) && is_multiline) { if (io.Ke
.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetS yCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScro
crollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_T llMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXT
EXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } END : STB_TEXTEDIT_K_DOWN) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state- else if (IsKeyPressed(ImGuiKey_PageUp) && is_multiline) { state->On
>OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g. KeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.Fon
FontSize; } tSize; }
else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state- else if (IsKeyPressed(ImGuiKey_PageDown) && is_multiline) { state->On
>OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * KeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.F
g.FontSize; } ontSize; }
else if (IsKeyPressedMap(ImGuiKey_Home)) { state- else if (IsKeyPressed(ImGuiKey_Home)) { state->On
>OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LI KeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINES
NESTART | k_mask); } TART | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_End)) { state- else if (IsKeyPressed(ImGuiKey_End)) { state->On
>OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINE KeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND
END | k_mask); } | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly && !is_cut) { else if (IsKeyPressed(ImGuiKey_Delete) && !is_readonly && !is_cut) { sta
state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } te->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Backspace) && !is_readonly) else if (IsKeyPressed(ImGuiKey_Backspace) && !is_readonly)
{ {
if (!state->HasSelection()) if (!state->HasSelection())
{ {
if (is_wordmove_key_down) if (is_wordmove_key_down)
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K _SHIFT); state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K _SHIFT);
else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl)
state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_ K_SHIFT); state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_ K_SHIFT);
} }
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
} }
skipping to change at line 4360 skipping to change at line 4310
} }
else if (is_cancel) else if (is_cancel)
{ {
clear_active_id = cancel_edit = true; clear_active_id = cancel_edit = true;
} }
else if (is_undo || is_redo) else if (is_undo || is_redo)
{ {
state->OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_R EDO); state->OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_R EDO);
state->ClearSelection(); state->ClearSelection();
} }
else if (is_shortcut_key && IsKeyPressedMap(ImGuiKey_A)) else if (is_shortcut_key && IsKeyPressed(ImGuiKey_A))
{ {
state->SelectAll(); state->SelectAll();
state->CursorFollow = true; state->CursorFollow = true;
} }
else if (is_cut || is_copy) else if (is_cut || is_copy)
{ {
// Cut, Copy // Cut, Copy
if (io.SetClipboardTextFn) if (io.SetClipboardTextFn)
{ {
const int ib = state->HasSelection() ? ImMin(state->Stb.select_s tart, state->Stb.select_end) : 0; const int ib = state->HasSelection() ? ImMin(state->Stb.select_s tart, state->Stb.select_end) : 0;
skipping to change at line 4466 skipping to change at line 4416
ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->Tex tW.Data, NULL); ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->Tex tW.Data, NULL);
} }
// User callback // User callback
if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTex tFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_ CallbackAlways)) != 0) if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTex tFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_ CallbackAlways)) != 0)
{ {
IM_ASSERT(callback != NULL); IM_ASSERT(callback != NULL);
// The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment.
ImGuiInputTextFlags event_flag = 0; ImGuiInputTextFlags event_flag = 0;
ImGuiKey event_key = ImGuiKey_COUNT; ImGuiKey event_key = ImGuiKey_None;
if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsK if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsK
eyPressedMap(ImGuiKey_Tab)) eyPressed(ImGuiKey_Tab))
{ {
event_flag = ImGuiInputTextFlags_CallbackCompletion; event_flag = ImGuiInputTextFlags_CallbackCompletion;
event_key = ImGuiKey_Tab; event_key = ImGuiKey_Tab;
} }
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && I sKeyPressedMap(ImGuiKey_UpArrow)) else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && I sKeyPressed(ImGuiKey_UpArrow))
{ {
event_flag = ImGuiInputTextFlags_CallbackHistory; event_flag = ImGuiInputTextFlags_CallbackHistory;
event_key = ImGuiKey_UpArrow; event_key = ImGuiKey_UpArrow;
} }
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && I sKeyPressedMap(ImGuiKey_DownArrow)) else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && I sKeyPressed(ImGuiKey_DownArrow))
{ {
event_flag = ImGuiInputTextFlags_CallbackHistory; event_flag = ImGuiInputTextFlags_CallbackHistory;
event_key = ImGuiKey_DownArrow; event_key = ImGuiKey_DownArrow;
} }
else if ((flags & ImGuiInputTextFlags_CallbackEdit) && state->Ed ited) else if ((flags & ImGuiInputTextFlags_CallbackEdit) && state->Ed ited)
{ {
event_flag = ImGuiInputTextFlags_CallbackEdit; event_flag = ImGuiInputTextFlags_CallbackEdit;
} }
else if (flags & ImGuiInputTextFlags_CallbackAlways) else if (flags & ImGuiInputTextFlags_CallbackAlways)
{ {
skipping to change at line 4763 skipping to change at line 4713
{ {
state->CursorAnim += io.DeltaTime; state->CursorAnim += io.DeltaTime;
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (stat e->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f; bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (stat e->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = ImFloor(draw_pos + cursor_offset - draw_s croll); ImVec2 cursor_screen_pos = ImFloor(draw_pos + cursor_offset - draw_s croll);
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_sc reen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_sc reen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
if (!is_readonly) if (!is_readonly)
g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_scr {
een_pos.y - g.FontSize); g.PlatformImeData.WantVisible = true;
g.PlatformImeData.InputPos = ImVec2(cursor_screen_pos.x - 1.0f,
cursor_screen_pos.y - g.FontSize);
g.PlatformImeData.InputLineHeight = g.FontSize;
}
} }
} }
else else
{ {
// Render text only (no selection, no cursor) // Render text only (no selection, no cursor)
if (is_multiline) if (is_multiline)
text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(bu f_display, &buf_display_end) * g.FontSize); // We don't need width text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(bu f_display, &buf_display_end) * g.FontSize); // We don't need width
else if (!is_displaying_hint && g.ActiveId == id) else if (!is_displaying_hint && g.ActiveId == id)
buf_display_end = buf_display + state->CurLenA; buf_display_end = buf_display + state->CurLenA;
else if (!is_displaying_hint) else if (!is_displaying_hint)
skipping to change at line 4976 skipping to change at line 4930
if (flags & ImGuiColorEditFlags_Float) if (flags & ImGuiColorEditFlags_Float)
{ {
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, h dr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, h dr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
value_changed_as_float |= value_changed; value_changed_as_float |= value_changed;
} }
else else
{ {
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight );
} }
} }
else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColo rEditFlags_NoInputs) == 0) else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColo rEditFlags_NoInputs) == 0)
{ {
// RGB Hexadecimal Input // RGB Hexadecimal Input
char buf[64]; char buf[64];
if (alpha) if (alpha)
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp( i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 25 5)); ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp( i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 25 5));
else else
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0] , 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255)); ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0] , 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
skipping to change at line 5004 skipping to change at line 4958
i[0] = i[1] = i[2] = 0; i[0] = i[1] = i[2] = 0;
i[3] = 0xFF; // alpha default to 255 is not parsed by scanf (e.g. in putting #FFFFFF omitting alpha) i[3] = 0xFF; // alpha default to 255 is not parsed by scanf (e.g. in putting #FFFFFF omitting alpha)
int r; int r;
if (alpha) if (alpha)
r = sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigne d int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) r = sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigne d int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned)
else else
r = sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned in t*)&i[1], (unsigned int*)&i[2]); r = sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned in t*)&i[1], (unsigned int*)&i[2]);
IM_UNUSED(r); // Fixes C6031: Return value ignored: 'sscanf'. IM_UNUSED(r); // Fixes C6031: Return value ignored: 'sscanf'.
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
} }
ImGuiWindow* picker_active_window = NULL; ImGuiWindow* picker_active_window = NULL;
if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) if (!(flags & ImGuiColorEditFlags_NoSmallPreview))
{ {
const float button_offset_x = ((flags & ImGuiColorEditFlags_NoInputs) || (style.ColorButtonPosition == ImGuiDir_Left)) ? 0.0f : w_inputs + style.ItemInn erSpacing.x; const float button_offset_x = ((flags & ImGuiColorEditFlags_NoInputs) || (style.ColorButtonPosition == ImGuiDir_Left)) ? 0.0f : w_inputs + style.ItemInn erSpacing.x;
window->DC.CursorPos = ImVec2(pos.x + button_offset_x, pos.y); window->DC.CursorPos = ImVec2(pos.x + button_offset_x, pos.y);
const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f);
if (ColorButton("##ColorButton", col_v4, flags)) if (ColorButton("##ColorButton", col_v4, flags))
{ {
if (!(flags & ImGuiColorEditFlags_NoPicker)) if (!(flags & ImGuiColorEditFlags_NoPicker))
{ {
// Store current color and open a picker // Store current color and open a picker
g.ColorPickerRef = col_v4; g.ColorPickerRef = col_v4;
OpenPopup("picker"); OpenPopup("picker");
SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(-1, style. ItemSpacing.y)); SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(0.0f, styl e.ItemSpacing.y));
} }
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
if (BeginPopup("picker")) if (BeginPopup("picker"))
{ {
picker_active_window = g.CurrentWindow; picker_active_window = g.CurrentWindow;
if (label != label_display_end) if (label != label_display_end)
{ {
TextEx(label, label_display_end); TextEx(label, label_display_end);
Spacing(); Spacing();
} }
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Da taTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_Alp haBar; ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Da taTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_Alp haBar;
skipping to change at line 5239 skipping to change at line 5193
if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_ pc, current_off_unrotated)) if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_ pc, current_off_unrotated))
current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated); current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated);
float uu, vv, ww; float uu, vv, ww;
ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_p c, current_off_unrotated, uu, vv, ww); ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_p c, current_off_unrotated, uu, vv, ww);
V = ImClamp(1.0f - vv, 0.0001f, 1.0f); V = ImClamp(1.0f - vv, 0.0001f, 1.0f);
S = ImClamp(uu / V, 0.0001f, 1.0f); S = ImClamp(uu / V, 0.0001f, 1.0f);
value_changed = value_changed_sv = true; value_changed = value_changed_sv = true;
} }
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
} }
else if (flags & ImGuiColorEditFlags_PickerHueBar) else if (flags & ImGuiColorEditFlags_PickerHueBar)
{ {
// SV rectangle logic // SV rectangle logic
InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size));
if (IsItemActive()) if (IsItemActive())
{ {
S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1) ); S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1) );
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_si ze - 1)); V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_si ze - 1));
// Greatly reduces hue jitter and reset to 0 when hue == 255 and col or is rapidly modified using SV square. // Greatly reduces hue jitter and reset to 0 when hue == 255 and col or is rapidly modified using SV square.
if (g.ColorEditLastColor == ColorConvertFloat4ToU32(ImVec4(col[0], c ol[1], col[2], 0))) if (g.ColorEditLastColor == ColorConvertFloat4ToU32(ImVec4(col[0], c ol[1], col[2], 0)))
H = g.ColorEditLastHue; H = g.ColorEditLastHue;
value_changed = value_changed_sv = true; value_changed = value_changed_sv = true;
} }
if (!(flags & ImGuiColorEditFlags_NoOptions)) if (!(flags & ImGuiColorEditFlags_NoOptions))
OpenPopupOnItemClick("context"); OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
// Hue bar logic // Hue bar logic
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); InvisibleButton("hue", ImVec2(bars_width, sv_picker_size));
if (IsItemActive()) if (IsItemActive())
{ {
H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1) ); H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1) );
value_changed = value_changed_h = true; value_changed = value_changed_h = true;
} }
} }
skipping to change at line 6937 skipping to change at line 6891
// The reference position stored in popup_pos will be used by Begin() to fin d a suitable position for the child menu, // The reference position stored in popup_pos will be used by Begin() to fin d a suitable position for the child menu,
// However the final position is going to be different! It is chosen by Find BestWindowPosForPopup(). // However the final position is going to be different! It is chosen by Find BestWindowPosForPopup().
// e.g. Menus tend to overlap each other horizontally to amplify relative Z- ordering. // e.g. Menus tend to overlap each other horizontally to amplify relative Z- ordering.
ImVec2 popup_pos, pos = window->DC.CursorPos; ImVec2 popup_pos, pos = window->DC.CursorPos;
PushID(label); PushID(label);
if (!enabled) if (!enabled)
BeginDisabled(); BeginDisabled();
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns; const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
bool pressed; bool pressed;
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHolding ActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePo pups;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{ {
// Menu inside an horizontal menu bar // Menu inside an horizontal menu bar
// Selectable extend their highlight by half ItemSpacing in each directi on. // Selectable extend their highlight by half ItemSpacing in each directi on.
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight()); popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0 f, style.ItemSpacing.y)); PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0 f, style.ItemSpacing.y));
float w = label_size.x; float w = label_size.x;
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->D C.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->D C.CursorPos.y + window->DC.CurrLineTextBaseOffset);
pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingAct iveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopup s, ImVec2(w, 0.0f)); pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, 0.0f) );
RenderText(text_pos, label); RenderText(text_pos, label);
PopStyleVar(); PopStyleVar();
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)) ; // -1 spacing to compensate the spacing added when Selectable() did a SameLine (). It would also work to call SameLine() ourselves after the PopStyleVar(). window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)) ; // -1 spacing to compensate the spacing added when Selectable() did a SameLine (). It would also work to call SameLine() ourselves after the PopStyleVar().
} }
else else
{ {
// Menu inside a regular/vertical menu // Menu inside a regular/vertical menu
// (In a typical menu window where all items are BeginMenu() or MenuItem () calls, extra_w will always be 0.0f. // (In a typical menu window where all items are BeginMenu() or MenuItem () calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spaci ng, yet only register minimum width into the layout system. // Only when they are other items sticking out we're going to add spaci ng, yet only register minimum width into the layout system.
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0 .0f, checkmark_w); // Feedback to next frame float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0 .0f, checkmark_w); // Feedback to next frame
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->D C.CursorPos.y + window->DC.CurrLineTextBaseOffset); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->D C.CursorPos.y + window->DC.CurrLineTextBaseOffset);
pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingAct iveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopup s | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectabl eFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
RenderText(text_pos, label); RenderText(text_pos, label);
if (icon_w > 0.0f) if (icon_w > 0.0f)
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right); RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
} }
if (!enabled) if (!enabled)
EndDisabled(); EndDisabled();
const bool hovered = (g.HoveredId == id) && enabled; const bool hovered = (g.HoveredId == id) && enabled;
if (menuset_is_open) if (menuset_is_open)
 End of changes. 33 change blocks. 
163 lines changed or deleted 101 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)