1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-16 00:54:19 +00:00

Merge branch 'master' into docking

This commit is contained in:
ocornut 2022-07-08 16:06:47 +02:00
commit 21fc57f2cf
33 changed files with 467 additions and 411 deletions

View file

@ -611,7 +611,15 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (g.NavActivateDownId == id)
{
bool nav_activated_by_code = (g.NavActivateId == id);
bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiNavReadMode_Repeat : ImGuiNavReadMode_Pressed);
bool nav_activated_by_inputs = (g.NavActivatePressedId == id);
if (!nav_activated_by_inputs && (flags & ImGuiButtonFlags_Repeat))
{
// Avoid pressing both keys from triggering double amount of repeat events
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
const ImGuiKeyData* key2 = GetKeyData(ImGuiKey_NavGamepadActivate);
const float t1 = ImMax(key1->DownDuration, key2->DownDuration);
nav_activated_by_inputs = CalcTypematicRepeatAmount(t1 - g.IO.DeltaTime, t1, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
}
if (nav_activated_by_code || nav_activated_by_inputs)
{
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
@ -1882,6 +1890,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
// - DataTypeFormatString()
// - DataTypeApplyOp()
// - DataTypeApplyOpFromText()
// - DataTypeCompare()
// - DataTypeClamp()
// - GetMinimumStepAtDecimalPrecision
// - RoundScalarWithFormat<>()
@ -2189,7 +2198,10 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
{
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis];
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
const float tweak_factor = tweak_slow ? 1.0f / 1.0f : tweak_fast ? 10.0f : 1.0f;
adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor;
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
}
adjust_delta *= v_speed;
@ -2287,6 +2299,7 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
ImGuiContext& g = *GImGui;
if (g.ActiveId == id)
{
// Those are the things we can do easily outside the DragBehaviorT<> template, saves code generation.
if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0])
ClearActiveID();
else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
@ -2795,25 +2808,26 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
g.SliderCurrentAccumDirty = false;
}
const ImVec2 input_delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_RepeatFast, 0.0f, 0.0f);
float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y;
float input_delta = (axis == ImGuiAxis_X) ? GetNavTweakPressedAmount(axis) : -GetNavTweakPressedAmount(axis);
if (input_delta != 0.0f)
{
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
if (decimal_precision > 0)
{
input_delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds
if (IsNavInputDown(ImGuiNavInput_TweakSlow))
if (tweak_slow)
input_delta /= 10.0f;
}
else
{
if ((v_range >= -100.0f && v_range <= 100.0f) || IsNavInputDown(ImGuiNavInput_TweakSlow))
if ((v_range >= -100.0f && v_range <= 100.0f) || tweak_slow)
input_delta = ((input_delta < 0.0f) ? -1.0f : +1.0f) / (float)v_range; // Gamepad/keyboard tweak speeds in integer steps
else
input_delta /= 100.0f;
}
if (IsNavInputDown(ImGuiNavInput_TweakFast))
if (tweak_fast)
input_delta *= 10.0f;
g.SliderCurrentAccum += input_delta;
@ -2901,6 +2915,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
// Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert.
IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.");
// Those are the things we can do easily outside the SliderBehaviorT<> template, saves code generation.
ImGuiContext& g = *GImGui;
if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly))
return false;
@ -3694,13 +3709,10 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (!is_separator(obj->TextW[idx - 1]) && is_separator(obj->TextW[idx])) : 1; }
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
#ifdef __APPLE__ // FIXME: Move setting to IO structure
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_MAC
#else
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_WIN
#endif
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { if (ImGui::GetIO().ConfigMacOSXBehaviors) return STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx); else return STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx); }
#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
{
@ -4149,11 +4161,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
FocusWindow(window);
// Declare our inputs
IM_ASSERT(ImGuiNavInput_COUNT < 32);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory))
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
SetActiveIdUsingKey(ImGuiKey_Escape);
SetActiveIdUsingKey(ImGuiKey_NavGamepadCancel);
SetActiveIdUsingKey(ImGuiKey_Home);
SetActiveIdUsingKey(ImGuiKey_End);
if (is_multiline)
@ -4291,7 +4303,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (state->SelectedAllMouseLock && !io.MouseDown[0])
state->SelectedAllMouseLock = false;
// We except backends to emit a Tab key but some also emit a Tab character which we ignore (#2467, #1336)
// We expect backends to emit a Tab key but some also emit a Tab character which we ignore (#2467, #1336)
// (For Tab and Enter: Win32/SFML/Allegro are sending both keys and chars, GLFW and SDL are only sending keys. For Space they all send all threes)
const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper);
if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressed(ImGuiKey_Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly)
@ -4344,11 +4356,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_paste = ((is_shortcut_key && IsKeyPressed(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_readonly;
const bool is_undo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Z)) && !is_readonly && is_undoable);
const bool is_redo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressed(ImGuiKey_Z))) && !is_readonly && is_undoable;
const bool is_select_all = is_shortcut_key && IsKeyPressed(ImGuiKey_A);
// 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 isn't very useful.
const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_KeypadEnter);
const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiNavReadMode_Pressed) && !IsKeyPressed(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed);
const bool is_cancel = IsKeyPressed(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiNavReadMode_Pressed);
const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true);
const bool is_gamepad_validate = IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false);
const bool is_cancel = IsKeyPressed(ImGuiKey_Escape, false) || IsKeyPressed(ImGuiKey_NavGamepadCancel, false);
if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
@ -4370,11 +4383,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
}
else if (is_enter_pressed)
else if (is_enter_pressed || is_gamepad_validate)
{
// Determine if we turn Enter into a \n character
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
{
validated = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline)
@ -4389,11 +4402,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->OnKeyPressed((int)c);
}
}
else if (is_validate_nav)
{
IM_ASSERT(!is_enter_pressed);
validated = clear_active_id = true;
}
else if (is_cancel)
{
clear_active_id = cancel_edit = true;
@ -4403,7 +4411,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_REDO);
state->ClearSelection();
}
else if (is_shortcut_key && IsKeyPressed(ImGuiKey_A))
else if (is_select_all)
{
state->SelectAll();
state->CursorFollow = true;