Merge branch 'master' into navigation + merge fix

# Conflicts:
#	imgui.cpp
This commit is contained in:
omar 2017-12-07 16:42:52 +01:00
commit e6215b6ca0
4 changed files with 43 additions and 20 deletions

View File

@ -694,7 +694,7 @@ static ImRect GetVisibleRect();
static void CloseInactivePopups(ImGuiWindow* ref_window); static void CloseInactivePopups(ImGuiWindow* ref_window);
static void ClosePopupToLevel(int remaining); static void ClosePopupToLevel(int remaining);
static ImGuiWindow* GetFrontMostModalRootWindow(); static ImGuiWindow* GetFrontMostModalRootWindow();
static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid);
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data);
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
@ -1890,7 +1890,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
AutoFitFramesX = AutoFitFramesY = -1; AutoFitFramesX = AutoFitFramesY = -1;
AutoFitOnlyGrows = false; AutoFitOnlyGrows = false;
AutoFitChildAxises = 0x00; AutoFitChildAxises = 0x00;
AutoPosLastDirection = -1; AutoPosLastDirection = ImGuiDir_None;
HiddenFrames = 0; HiddenFrames = 0;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
@ -2555,6 +2555,11 @@ int ImGui::GetFrameCount()
return GImGui->FrameCount; return GImGui->FrameCount;
} }
ImDrawList* ImGui::GetOverlayDrawList()
{
return &GImGui->OverlayDrawList;
}
// This needs to be called before we submit any widget (aka in or before Begin) // This needs to be called before we submit any widget (aka in or before Begin)
void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
{ {
@ -4918,28 +4923,39 @@ static void CheckStacksSize(ImGuiWindow* window, bool write)
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
} }
static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& r_inner) static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid)
{ {
const ImGuiStyle& style = GImGui->Style; const ImGuiStyle& style = GImGui->Style;
// Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.)
// r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it.
ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImVec2 safe_padding = style.DisplaySafeAreaPadding;
ImRect r_outer(GetVisibleRect()); ImRect r_outer(GetVisibleRect());
r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f));
ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size);
//GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
//GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction). const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++)
{ {
const int dir = (n == -1) ? *last_dir : n; const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
ImRect rect(dir == 0 ? r_inner.Max.x : r_outer.Min.x, dir == 1 ? r_inner.Max.y : r_outer.Min.y, dir == 3 ? r_inner.Min.x : r_outer.Max.x, dir == 2 ? r_inner.Min.y : r_outer.Max.y); float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
if (rect.GetWidth() < size.x || rect.GetHeight() < size.y) if (avail_w < size.x)
continue; continue;
float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);
if (avail_h < size.y)
continue;
ImVec2 pos;
pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;
*last_dir = dir; *last_dir = dir;
return ImVec2(dir == 0 ? r_inner.Max.x : dir == 3 ? r_inner.Min.x - size.x : base_pos_clamped.x, dir == 1 ? r_inner.Max.y : dir == 2 ? r_inner.Min.y - size.y : base_pos_clamped.y); return pos;
} }
// Fallback, try to keep within display // Fallback, try to keep within display
*last_dir = -1; *last_dir = ImGuiDir_None;
ImVec2 pos = base_pos; ImVec2 pos = base_pos;
pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
@ -5289,7 +5305,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (window_just_activated_by_user) if (window_just_activated_by_user)
{ {
// Popup first latch mouse position, will position itself when it appears next frame // Popup first latch mouse position, will position itself when it appears next frame
window->AutoPosLastDirection = -1; window->AutoPosLastDirection = ImGuiDir_None;
if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
window->PosFloat = g.CurrentPopupStack.back().PopupPosOnOpen; window->PosFloat = g.CurrentPopupStack.back().PopupPosOnOpen;
} }
@ -5431,9 +5447,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api)
{ {
ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos;
ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead? ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point?
window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
if (window->AutoPosLastDirection == -1) if (window->AutoPosLastDirection == ImGuiDir_None)
window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
} }
@ -5584,7 +5600,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
} }
} }
} }
PopID();
// Apply back modified position/size to window // Apply back modified position/size to window
if (size_target.x != FLT_MAX) if (size_target.x != FLT_MAX)

View File

@ -452,6 +452,7 @@ namespace ImGui
IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
IMGUI_API float GetTime(); IMGUI_API float GetTime();
IMGUI_API int GetFrameCount(); IMGUI_API int GetFrameCount();
IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text
IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API const char* GetStyleColorName(ImGuiCol idx);
IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
@ -780,7 +781,7 @@ enum ImGuiMouseCursor_
ImGuiMouseCursor_Move, // Unused ImGuiMouseCursor_Move, // Unused
ImGuiMouseCursor_ResizeNS, // Unused ImGuiMouseCursor_ResizeNS, // Unused
ImGuiMouseCursor_ResizeEW, // When hovering over a column ImGuiMouseCursor_ResizeEW, // When hovering over a column
ImGuiMouseCursor_ResizeNESW, // Unused ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window
ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window
ImGuiMouseCursor_Count_ ImGuiMouseCursor_Count_
}; };

View File

@ -1848,6 +1848,8 @@ void ImGui::ShowTestWindow(bool* p_open)
if (ImGui::TreeNode("Dragging")) if (ImGui::TreeNode("Dragging"))
{ {
ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
for (int button = 0; button < 3; button++)
ImGui::Text("IsMouseDragging(%d) = %d", button, ImGui::IsMouseDragging(button));
ImGui::Button("Drag Me"); ImGui::Button("Drag Me");
if (ImGui::IsItemActive()) if (ImGui::IsItemActive())
{ {
@ -1866,12 +1868,16 @@ void ImGui::ShowTestWindow(bool* p_open)
if (ImGui::TreeNode("Mouse cursors")) if (ImGui::TreeNode("Mouse cursors"))
{ {
const char* mouse_cursors_names[] = { "Arrow", "TextInput", "Move", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE" };
IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_Count_);
ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]);
ImGui::Text("Hover to see mouse cursors:"); ImGui::Text("Hover to see mouse cursors:");
ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it.");
for (int i = 0; i < ImGuiMouseCursor_Count_; i++) for (int i = 0; i < ImGuiMouseCursor_Count_; i++)
{ {
char label[32]; char label[32];
sprintf(label, "Mouse cursor %d", i); sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]);
ImGui::Bullet(); ImGui::Selectable(label, false); ImGui::Bullet(); ImGui::Selectable(label, false);
if (ImGui::IsItemHovered() || ImGui::IsItemFocused()) if (ImGui::IsItemHovered() || ImGui::IsItemFocused())
ImGui::SetMouseCursor(i); ImGui::SetMouseCursor(i);

View File

@ -260,7 +260,8 @@ enum ImGuiDir
ImGuiDir_Left = 0, ImGuiDir_Left = 0,
ImGuiDir_Right = 1, ImGuiDir_Right = 1,
ImGuiDir_Up = 2, ImGuiDir_Up = 2,
ImGuiDir_Down = 3 ImGuiDir_Down = 3,
ImGuiDir_Count_
}; };
enum ImGuiNavHighlightFlags_ enum ImGuiNavHighlightFlags_
@ -821,7 +822,7 @@ struct IMGUI_API ImGuiWindow
int AutoFitFramesX, AutoFitFramesY; int AutoFitFramesX, AutoFitFramesY;
bool AutoFitOnlyGrows; bool AutoFitOnlyGrows;
int AutoFitChildAxises; int AutoFitChildAxises;
int AutoPosLastDirection; ImGuiDir AutoPosLastDirection;
int HiddenFrames; int HiddenFrames;
ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call.
ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call.