Updated ImGui.

This commit is contained in:
Branimir Karadžić 2017-09-06 19:04:41 -07:00
parent b88e566b80
commit 85d55806d6
4 changed files with 86 additions and 50 deletions

View File

@ -1986,7 +1986,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop
{
ImGuiContext& g = *GImGui;
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus;
const bool allow_keyboard_focus = (window->DC.ItemFlags & ImGuiItemFlags_AllowKeyboardFocus) != 0;
window->FocusIdxAllCounter++;
if (allow_keyboard_focus)
window->FocusIdxTabCounter++;
@ -2291,14 +2291,14 @@ void ImGui::NewFrame()
mouse_earliest_button_down = i;
}
bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
if (g.CaptureMouseNextFrame != -1)
g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0);
if (g.WantCaptureMouseNextFrame != -1)
g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
else
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty());
g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0);
g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId);
g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != -1) ? (g.WantCaptureKeyboardNextFrame != 0) : (g.ActiveId != 0);
g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0;
g.MouseCursor = ImGuiMouseCursor_Arrow;
g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = -1;
g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1;
g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
@ -3311,12 +3311,12 @@ void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type)
void ImGui::CaptureKeyboardFromApp(bool capture)
{
GImGui->CaptureKeyboardNextFrame = capture ? 1 : 0;
GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0;
}
void ImGui::CaptureMouseFromApp(bool capture)
{
GImGui->CaptureMouseNextFrame = capture ? 1 : 0;
GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0;
}
bool ImGui::IsItemHovered()
@ -4375,13 +4375,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f;
window->DC.ChildWindows.resize(0);
window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.ItemFlags = ImGuiItemFlags_Default_;
window->DC.ItemWidth = window->ItemWidthDefault;
window->DC.TextWrapPos = -1.0f; // disabled
window->DC.AllowKeyboardFocus = true;
window->DC.ButtonRepeat = false;
window->DC.ItemFlagsStack.resize(0);
window->DC.ItemWidthStack.resize(0);
window->DC.AllowKeyboardFocusStack.resize(0);
window->DC.ButtonRepeatStack.resize(0);
window->DC.TextWrapPosStack.resize(0);
window->DC.ColumnsCurrent = 0;
window->DC.ColumnsCount = 1;
@ -4393,6 +4391,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->DC.GroupStack.resize(0);
window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user);
if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags))
{
window->DC.ItemFlags = parent_window->DC.ItemFlags;
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
}
if (window->AutoFitFramesX > 0)
window->AutoFitFramesX--;
if (window->AutoFitFramesY > 0)
@ -4726,32 +4730,41 @@ void ImGui::PopFont()
SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back());
}
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled)
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.AllowKeyboardFocus = allow_keyboard_focus;
window->DC.AllowKeyboardFocusStack.push_back(allow_keyboard_focus);
if (enabled)
window->DC.ItemFlags |= option;
else
window->DC.ItemFlags &= ~option;
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
}
void ImGui::PopItemFlag()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ItemFlagsStack.pop_back();
window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back();
}
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
{
PushItemFlag(ImGuiItemFlags_AllowKeyboardFocus, allow_keyboard_focus);
}
void ImGui::PopAllowKeyboardFocus()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.AllowKeyboardFocusStack.pop_back();
window->DC.AllowKeyboardFocus = window->DC.AllowKeyboardFocusStack.empty() ? true : window->DC.AllowKeyboardFocusStack.back();
PopItemFlag();
}
void ImGui::PushButtonRepeat(bool repeat)
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ButtonRepeat = repeat;
window->DC.ButtonRepeatStack.push_back(repeat);
PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat);
}
void ImGui::PopButtonRepeat()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ButtonRepeatStack.pop_back();
window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back();
PopItemFlag();
}
void ImGui::PushTextWrapPos(float wrap_pos_x)
@ -5728,7 +5741,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
if (!ItemAdd(bb, &id))
return false;
if (window->DC.ButtonRepeat) flags |= ImGuiButtonFlags_Repeat;
if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
@ -6484,6 +6497,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label
ImGuiWindow* window = GetCurrentWindow();
// Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen)
// On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id
SetActiveID(g.ScalarAsInputTextId, window);
SetHoveredID(0);
FocusableItemUnregister(window);
@ -6729,7 +6743,6 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
{
SetActiveID(id, window);
FocusWindow(window);
if (tab_focus_requested || g.IO.KeyCtrl)
{
start_text_input = true;
@ -7026,11 +7039,10 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
// Tabbing or CTRL-clicking on Drag turns it into an input box
bool start_text_input = false;
const bool tab_focus_requested = FocusableItemRegister(window, id);
if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0])))
if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0])))
{
SetActiveID(id, window);
FocusWindow(window);
if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0])
{
start_text_input = true;
@ -7913,6 +7925,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
// Down the line we should have a cleaner library-wide concept of Selected vs Active.
g.ActiveIdAllowOverlap = !io.MouseDown[0];
g.WantTextInputNextFrame = 1;
// Edit in progress
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX;
@ -8605,25 +8618,31 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup
if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
bool popup_toggled = false;
if (hovered)
{
SetHoveredID(id);
if (g.IO.MouseClicked[0])
{
ClearActiveID();
if (IsPopupOpen(id))
{
ClosePopup(id);
}
else
{
FocusWindow(window);
OpenPopup(label);
}
popup_toggled = true;
}
}
if (popup_toggled)
{
if (popup_open)
{
ClosePopup(id);
}
else
{
FocusWindow(window);
OpenPopupEx(id, false);
}
popup_open = !popup_open;
}
if (!IsPopupOpen(id))
if (!popup_open)
return false;
float popup_y1 = frame_bb.Max.y;
@ -9060,7 +9079,10 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
want_open = menu_is_open = false;
}
else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others
{
want_open = true;
}
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
want_close = true;
if (want_close && IsPopupOpen(id))

View File

@ -204,9 +204,9 @@ namespace ImGui
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position
IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
IMGUI_API void PopTextWrapPos();
IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
IMGUI_API void PopAllowKeyboardFocus();
IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (uses io.KeyRepeatDelay/io.KeyRepeatRate for now). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.
IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.
IMGUI_API void PopButtonRepeat();
// Cursor / Layout

View File

@ -2118,7 +2118,8 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
static void ShowExampleAppFixedOverlay(bool* p_open)
{
ImGui::SetNextWindowPos(ImVec2(10,10));
if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
{
ImGui::End();
return;
@ -2127,6 +2128,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open)
ImGui::Separator();
ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
ImGui::End();
ImGui::PopStyleColor();
}
// Demonstrate using "##" and "###" in identifiers to manipulate ID generation.

View File

@ -48,6 +48,7 @@ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_
typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_
typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_
typedef int ImGuiItemFlags; // enum ImGuiItemFlags_
//-------------------------------------------------------------------------
// STB libraries
@ -486,8 +487,9 @@ struct ImGuiContext
float FramerateSecPerFrame[120]; // calculate estimate of framerate for user
int FramerateSecPerFrameIdx;
float FramerateSecPerFrameAccum;
int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags
int CaptureKeyboardNextFrame;
int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags
int WantCaptureKeyboardNextFrame;
int WantTextInputNextFrame;
char TempBuffer[1024*3+1]; // temporary text buffer
ImGuiContext()
@ -558,11 +560,22 @@ struct ImGuiContext
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = 0;
FramerateSecPerFrameAccum = 0.0f;
CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1;
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
memset(TempBuffer, 0, sizeof(TempBuffer));
}
};
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
enum ImGuiItemFlags_
{
ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
//ImGuiItemFlags_Disabled = 1 << 2, // false // All widgets appears are disabled
//ImGuiItemFlags_AllowNavDefaultFocus = 1 << 3, // true
//ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window
ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus
};
// Transient per-window data, reset at the beginning of the frame
// FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered.
struct IMGUI_API ImGuiDrawContext
@ -588,14 +601,12 @@ struct IMGUI_API ImGuiDrawContext
ImGuiLayoutType LayoutType;
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default]
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true]
bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false]
ImVector<ImGuiItemFlags>ItemFlagsStack;
ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack;
ImVector<bool> AllowKeyboardFocusStack;
ImVector<bool> ButtonRepeatStack;
ImVector<ImGuiGroupData>GroupStack;
int StackSizesBackup[6]; // Store size of various stacks for asserting
@ -629,8 +640,7 @@ struct IMGUI_API ImGuiDrawContext
StateStorage = NULL;
LayoutType = ImGuiLayoutType_Vertical;
ItemWidth = 0.0f;
ButtonRepeat = false;
AllowKeyboardFocus = true;
ItemFlags = ImGuiItemFlags_Default_;
TextWrapPos = -1.0f;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
@ -760,6 +770,8 @@ namespace ImGui
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing);
IMGUI_API bool IsPopupOpen(ImGuiID id);