mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-04 03:58:47 +02:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_vulkan.cpp # imgui.cpp
This commit is contained in:
@ -564,7 +564,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
SetFocusID(id, window);
|
||||
FocusWindow(window);
|
||||
}
|
||||
if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[mouse_button_clicked]))
|
||||
if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseClickedCount[mouse_button_clicked] == 2))
|
||||
{
|
||||
pressed = true;
|
||||
if (flags & ImGuiButtonFlags_NoHoldingActiveId)
|
||||
@ -641,7 +641,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
if ((release_in || release_anywhere) && !g.DragDropActive)
|
||||
{
|
||||
// Report as pressed when releasing the mouse (this is the most common path)
|
||||
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownWasDoubleClick[mouse_button];
|
||||
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2;
|
||||
bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
|
||||
if (!is_double_click_release && !is_repeating_already)
|
||||
pressed = true;
|
||||
@ -2415,7 +2415,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
{
|
||||
const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
const bool clicked = (hovered && g.IO.MouseClicked[0]);
|
||||
const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
|
||||
const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2);
|
||||
if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
|
||||
{
|
||||
SetActiveID(id, window);
|
||||
@ -3685,17 +3685,18 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* ob
|
||||
}
|
||||
|
||||
// When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators.
|
||||
static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
|
||||
static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|' || c=='\n' || c=='\r'; }
|
||||
static int is_word_boundary_from_right(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 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; }
|
||||
#ifdef __APPLE__ // FIXME: Move setting to IO structure
|
||||
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_MOVEWORDRIGHT_IMPL(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; }
|
||||
#else
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(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; }
|
||||
#endif
|
||||
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; }
|
||||
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_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
|
||||
#ifdef __APPLE__ // FIXME: Move setting to IO structure
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_MAC
|
||||
#else
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_WIN
|
||||
#endif
|
||||
|
||||
static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
||||
{
|
||||
@ -3887,11 +3888,12 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
||||
// Generic named filters
|
||||
if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)))
|
||||
{
|
||||
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf.
|
||||
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.'.
|
||||
// The standard mandate that programs starts in the "C" locale where the decimal point is '.'.
|
||||
// We don't really intend to provide widespread support for it, but out of empathy for people stuck with using odd API, we support the bare minimum aka overriding the decimal point.
|
||||
// Change the default decimal_point with:
|
||||
// ImGui::GetCurrentContext()->PlatformLocaleDecimalPoint = *localeconv()->decimal_point;
|
||||
// Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions.
|
||||
ImGuiContext& g = *GImGui;
|
||||
const unsigned c_decimal_point = (unsigned int)g.PlatformLocaleDecimalPoint;
|
||||
|
||||
@ -4182,19 +4184,49 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f));
|
||||
|
||||
const bool is_osx = io.ConfigMacOSXBehaviors;
|
||||
if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0]))
|
||||
if (select_all)
|
||||
{
|
||||
state->SelectAll();
|
||||
state->SelectedAllMouseLock = true;
|
||||
}
|
||||
else if (hovered && is_osx && io.MouseDoubleClicked[0])
|
||||
else if (hovered && io.MouseClickedCount[0] >= 2 && !io.KeyShift)
|
||||
{
|
||||
// Double-click select a word only, OS X style (by simulating keystrokes)
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT);
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT);
|
||||
stb_textedit_click(state, &state->Stb, mouse_x, mouse_y);
|
||||
const int multiclick_count = (io.MouseClickedCount[0] - 2);
|
||||
if ((multiclick_count % 2) == 0)
|
||||
{
|
||||
// Double-click: Select word
|
||||
// We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant:
|
||||
// FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS)
|
||||
const bool is_bol = (state->Stb.cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor - 1) == '\n';
|
||||
if (STB_TEXT_HAS_SELECTION(&state->Stb) || !is_bol)
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT);
|
||||
//state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT);
|
||||
if (!STB_TEXT_HAS_SELECTION(&state->Stb))
|
||||
ImStb::stb_textedit_prep_selection_at_cursor(&state->Stb);
|
||||
state->Stb.cursor = ImStb::STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state->Stb.cursor);
|
||||
state->Stb.select_end = state->Stb.cursor;
|
||||
ImStb::stb_textedit_clamp(state, &state->Stb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Triple-click: Select line
|
||||
const bool is_eol = ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor) == '\n';
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART);
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT);
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT);
|
||||
if (!is_eol && is_multiline)
|
||||
{
|
||||
ImSwap(state->Stb.select_start, state->Stb.select_end);
|
||||
state->Stb.cursor = state->Stb.select_end;
|
||||
}
|
||||
state->CursorFollow = false;
|
||||
}
|
||||
state->CursorAnimReset();
|
||||
}
|
||||
else if (io.MouseClicked[0] && !state->SelectedAllMouseLock)
|
||||
{
|
||||
// FIXME: unselect on late click could be done release?
|
||||
if (hovered)
|
||||
{
|
||||
stb_textedit_click(state, &state->Stb, mouse_x, mouse_y);
|
||||
@ -5928,7 +5960,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
toggled = true;
|
||||
if (flags & ImGuiTreeNodeFlags_OpenOnArrow)
|
||||
toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job
|
||||
if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0])
|
||||
if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseClickedCount[0] == 2)
|
||||
toggled = true;
|
||||
}
|
||||
else if (pressed && g.DragDropHoldJustPressedId == id)
|
||||
@ -6235,7 +6267,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
{
|
||||
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
{
|
||||
SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos)); // (bb == NavRect)
|
||||
SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, WindowRectAbsToRel(window, bb)); // (bb == NavRect)
|
||||
g.NavDisableHighlight = true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user