mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-21 07:16:34 +00:00
Merge branch 'master' into docking
# Conflicts: # imgui.cpp
This commit is contained in:
commit
de1588928b
@ -109,6 +109,8 @@ Other Changes:
|
||||
- Nav: Fixed clicking on void (behind any windows) from not clearing the focused window.
|
||||
This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard
|
||||
flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880)
|
||||
- Window: Fixed clicking over an item which hovering has been disabled (e.g inhibited by a popup)
|
||||
from marking the window as moved.
|
||||
- DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both
|
||||
min and max value are on the same value. (#1441)
|
||||
- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more
|
||||
@ -116,6 +118,14 @@ Other Changes:
|
||||
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText
|
||||
call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare
|
||||
but it will be addressed later). (#3349)
|
||||
- InvisibleButton: Made public a small selection of ImGuiButtonFlags (previously in imgui_internal.h)
|
||||
and allowed to pass them to InvisibleButton(): ImGuiButtonFlags_MouseButtonLeft/Right/Middle.
|
||||
This is a small but rather important change because lots of multi-button behaviors could previously
|
||||
only be achieved using lower-level/internal API. Now also available via high-level InvisibleButton()
|
||||
with is a de-facto versatile building block to creating custom widgets with the public API.
|
||||
- Fonts: Fixed ImFontConfig::GlyphExtraSpacing and ImFontConfig::PixelSnapH settings being pulled
|
||||
from the merged/target font settings when merging fonts, instead of being pulled from the source
|
||||
font settings.
|
||||
- ImDrawList: Thick anti-aliased strokes (> 1.0f) with integer thickness now use a texture-based
|
||||
path, reducing the amount of vertices/indices and CPU/GPU usage. (#3245) [@Shironekoben]
|
||||
- This change will facilitate the wider use of thick borders in future style changes.
|
||||
@ -127,6 +137,8 @@ Other Changes:
|
||||
by modifying the 'style.CircleSegmentMaxError' value. [@ShironekoBen]
|
||||
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate
|
||||
an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen]
|
||||
- Demo: Improve "Custom Rendering"->"Canvas" demo with a grid, scrolling and context menu.
|
||||
Also showcase using InvisibleButton() will multiple mouse buttons flags.
|
||||
- Demo: Tweak "Child Windows" section.
|
||||
- Style Editor: Added preview of circle auto-tessellation when editing the corresponding value.
|
||||
- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h]
|
||||
|
@ -235,6 +235,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- popups: clicking outside (to close popup) and holding shouldn't drag window below.
|
||||
- popups: add variant using global identifier similar to Begin/End (#402)
|
||||
- popups: border options. richer api like BeginChild() perhaps? (#197)
|
||||
- popups: flags could be reworked to allow both mouse buttons as index (0..5 and as flags using higher-bit) allowing to or them.
|
||||
- popups/modals: although it is sometimes convenient that popups/modals lifetime is owned by imgui, we could also a bool-owned-by-user api as long as Begin() return value testing is enforced.
|
||||
|
||||
- tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction.
|
||||
|
30
imgui.cpp
30
imgui.cpp
@ -3119,10 +3119,13 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
||||
return false;
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max))
|
||||
return false;
|
||||
if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
||||
if (g.NavDisableMouseHover)
|
||||
return false;
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
|
||||
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (window->DC.ItemFlags & ImGuiItemFlags_Disabled))
|
||||
{
|
||||
g.HoveredIdDisabled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
|
||||
// hover test in widgets code. We could also decide to split this function is two.
|
||||
@ -3514,10 +3517,16 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
if (root_window != NULL && !is_closed_popup)
|
||||
{
|
||||
StartMouseMovingWindow(g.HoveredWindow);
|
||||
|
||||
// Cancel moving if clicked outside of title bar
|
||||
if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
|
||||
if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar) || root_window->DockIsActive)
|
||||
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
||||
g.MovingWindow = NULL;
|
||||
|
||||
// Cancel moving if clicked over an item which was disabled or inhibited by popups
|
||||
if (g.HoveredId == 0 && g.HoveredIdDisabled)
|
||||
g.MovingWindow = NULL;
|
||||
}
|
||||
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||
{
|
||||
@ -3767,11 +3776,10 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
FindHoveredWindow();
|
||||
IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MouseViewport);
|
||||
|
||||
// Modal windows prevents cursor from hovering behind them.
|
||||
// Modal windows prevents mouse from hovering behind them.
|
||||
ImGuiWindow* modal_window = GetTopMostPopupModal();
|
||||
if (modal_window)
|
||||
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
if (modal_window && g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// Disabled mouse?
|
||||
if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
|
||||
@ -3903,6 +3911,7 @@ void ImGui::NewFrame()
|
||||
g.HoveredIdPreviousFrame = g.HoveredId;
|
||||
g.HoveredId = 0;
|
||||
g.HoveredIdAllowOverlap = false;
|
||||
g.HoveredIdDisabled = false;
|
||||
|
||||
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
|
||||
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
|
||||
@ -4765,6 +4774,7 @@ bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||
return g.IO.MouseDoubleClicked[button];
|
||||
}
|
||||
|
||||
// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame.
|
||||
// [Internal] This doesn't test if the button is pressed
|
||||
bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
|
||||
{
|
||||
@ -8580,6 +8590,7 @@ void ImGui::EndPopup()
|
||||
g.WithinEndChild = false;
|
||||
}
|
||||
|
||||
// Open a popup if mouse is released over the item
|
||||
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
@ -9919,6 +9930,7 @@ void ImGui::NavUpdateWindowingOverlay()
|
||||
PopStyleVar();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DRAG AND DROP
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -10108,7 +10120,8 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
|
||||
return false;
|
||||
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.HoveredWindowUnderMovingWindow == NULL || window->RootWindow != g.HoveredWindowUnderMovingWindow->RootWindow)
|
||||
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
|
||||
if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow)
|
||||
return false;
|
||||
IM_ASSERT(id != 0);
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId))
|
||||
@ -10136,7 +10149,8 @@ bool ImGui::BeginDragDropTarget()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
if (g.HoveredWindowUnderMovingWindow == NULL || window->RootWindow != g.HoveredWindowUnderMovingWindow->RootWindow)
|
||||
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
|
||||
if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow)
|
||||
return false;
|
||||
|
||||
const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
|
||||
|
21
imgui.h
21
imgui.h
@ -160,6 +160,7 @@ typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: f
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build
|
||||
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
|
||||
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton()
|
||||
typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc.
|
||||
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
|
||||
typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo()
|
||||
@ -449,7 +450,7 @@ namespace ImGui
|
||||
// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.
|
||||
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button
|
||||
IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text
|
||||
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
||||
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
|
||||
IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape
|
||||
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
|
||||
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
|
||||
@ -458,7 +459,7 @@ namespace ImGui
|
||||
IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; }
|
||||
IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer
|
||||
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL);
|
||||
IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
|
||||
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
|
||||
|
||||
// Widgets: Combo Box
|
||||
// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.
|
||||
@ -921,6 +922,7 @@ enum ImGuiTreeNodeFlags_
|
||||
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
@ -1296,6 +1298,19 @@ enum ImGuiStyleVar_
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for InvisibleButton() [extended in imgui_internal.h]
|
||||
enum ImGuiButtonFlags_
|
||||
{
|
||||
ImGuiButtonFlags_None = 0,
|
||||
ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default)
|
||||
ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button
|
||||
ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button
|
||||
|
||||
// [Internal]
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
|
||||
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft
|
||||
};
|
||||
|
||||
// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()
|
||||
enum ImGuiColorEditFlags_
|
||||
{
|
||||
@ -2491,7 +2506,7 @@ struct ImFont
|
||||
IMGUI_API void BuildLookupTable();
|
||||
IMGUI_API void ClearOutputData();
|
||||
IMGUI_API void GrowIndex(int new_size);
|
||||
IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddGlyph(ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
|
||||
IMGUI_API void SetGlyphVisible(ImWchar c, bool visible);
|
||||
IMGUI_API void SetFallbackChar(ImWchar c);
|
||||
|
174
imgui_demo.cpp
174
imgui_demo.cpp
@ -4948,31 +4948,32 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// overloaded operators, etc. Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your
|
||||
// types and ImVec2/ImVec4. Dear ImGui defines overloaded operators but they are internal to imgui.cpp and not
|
||||
// exposed outside (to avoid messing with your types) In this example we are not using the maths operators!
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
if (ImGui::BeginTabBar("##TabBar"))
|
||||
{
|
||||
if (ImGui::BeginTabItem("Primitives"))
|
||||
{
|
||||
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
// Draw gradients
|
||||
// (note that those are currently exacerbating our sRGB/Linear issues)
|
||||
// Calling ImGui::GetColorU32() multiplies the given colors by the current Style Alpha, but you may pass the IM_COL32() directly as well..
|
||||
ImGui::Text("Gradients");
|
||||
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient1", gradient_size);
|
||||
}
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient2", gradient_size);
|
||||
}
|
||||
@ -4993,6 +4994,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40))
|
||||
circle_segments_override = true;
|
||||
ImGui::ColorEdit4("Color", &colf.x);
|
||||
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
const ImU32 col = ImColor(colf);
|
||||
const float spacing = 10.0f;
|
||||
@ -5000,94 +5002,134 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
|
||||
const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
|
||||
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
|
||||
float x = p.x + 4.0f, y = p.y + 4.0f;
|
||||
float x = p.x + 4.0f;
|
||||
float y = p.y + 4.0f;
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
// First line uses a thickness of 1.0f, second line uses the configurable thickness
|
||||
float th = (n == 0) ? 1.0f : thickness;
|
||||
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th); x += sz + spacing; // Triangle
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th); x += sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz*1.3f, y + sz*0.3f), ImVec2(x + sz - sz*1.3f, y + sz - sz*0.3f), ImVec2(x + sz, y + sz), col, th);
|
||||
x = p.x + 4;
|
||||
y += sz + spacing;
|
||||
}
|
||||
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments);x += sz + spacing; // Circle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing*2.0f; // Vertical line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
|
||||
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3));
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 8.8f, (sz + spacing) * 3.0f));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Canvas"))
|
||||
{
|
||||
static ImVector<ImVec2> points;
|
||||
struct ItemLine { ImVec2 p0, p1; ItemLine(const ImVec2& _p0, const ImVec2& _p1) { p0 = _p0; p1 = _p1; } };
|
||||
static ImVector<ItemLine> lines;
|
||||
static ImVec2 scrolling(0.0f, 0.0f);
|
||||
static bool show_grid = true;
|
||||
static bool adding_line = false;
|
||||
if (ImGui::Button("Clear")) points.clear();
|
||||
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
|
||||
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
|
||||
|
||||
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use
|
||||
// IsItemHovered(). But you can also draw directly and poll mouse/keyboard by yourself.
|
||||
// You can manipulate the cursor using GetCursorPos() and SetCursorPos().
|
||||
// If you only use the ImDrawList API, you can notify the owner window of its extends with SetCursorPos(max).
|
||||
ImVec2 canvas_p = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
ImGui::Checkbox("Show grid", &show_grid);
|
||||
ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.");
|
||||
|
||||
// Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling.
|
||||
// Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls.
|
||||
// To use a child window instead we could use, e.g:
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding
|
||||
// ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color
|
||||
// ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_NoMove);
|
||||
// ImGui::PopStyleColor();
|
||||
// ImGui::PopStyleVar();
|
||||
// [...]
|
||||
// ImGui::EndChild();
|
||||
|
||||
// Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive()
|
||||
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
|
||||
if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f;
|
||||
if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f;
|
||||
draw_list->AddRectFilledMultiColor(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
|
||||
draw_list->AddRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), IM_COL32(255, 255, 255, 255));
|
||||
ImVec2 canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
||||
|
||||
bool adding_preview = false;
|
||||
ImGui::InvisibleButton("canvas", canvas_sz);
|
||||
ImVec2 mouse_pos_global = ImGui::GetIO().MousePos;
|
||||
ImVec2 mouse_pos_canvas = ImVec2(mouse_pos_global.x - canvas_p.x, mouse_pos_global.y - canvas_p.y);
|
||||
// Draw border and background color
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(50, 50, 50, 255));
|
||||
draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255));
|
||||
|
||||
// This will catch our interactions
|
||||
ImGui::InvisibleButton("canvas", canvas_sz, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
|
||||
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
|
||||
const bool is_active = ImGui::IsItemActive(); // Held
|
||||
const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y); // Lock scrolled origin
|
||||
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
|
||||
|
||||
// Add first and second point
|
||||
if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
lines.push_back(ItemLine(mouse_pos_in_canvas, mouse_pos_in_canvas));
|
||||
adding_line = true;
|
||||
}
|
||||
if (adding_line)
|
||||
{
|
||||
adding_preview = true;
|
||||
points.push_back(mouse_pos_canvas);
|
||||
if (!ImGui::IsMouseDown(0))
|
||||
adding_line = adding_preview = false;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
if (!adding_line && ImGui::IsMouseClicked(0))
|
||||
{
|
||||
points.push_back(mouse_pos_canvas);
|
||||
adding_line = true;
|
||||
}
|
||||
if (ImGui::IsMouseClicked(1) && !points.empty())
|
||||
{
|
||||
adding_line = adding_preview = false;
|
||||
points.pop_back();
|
||||
points.pop_back();
|
||||
}
|
||||
lines.back().p1 = mouse_pos_in_canvas;
|
||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
|
||||
adding_line = false;
|
||||
}
|
||||
|
||||
// Draw all lines in the canvas (with a clipping rectangle so they don't stray out of it).
|
||||
draw_list->PushClipRect(canvas_p, ImVec2(canvas_p.x + canvas_sz.x, canvas_p.y + canvas_sz.y), true);
|
||||
for (int i = 0; i < points.Size - 1; i += 2)
|
||||
draw_list->AddLine(ImVec2(canvas_p.x + points[i].x, canvas_p.y + points[i].y), ImVec2(canvas_p.x + points[i + 1].x, canvas_p.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
// Pan (using zero mouse threshold)
|
||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, 0.0f))
|
||||
{
|
||||
scrolling.x += io.MouseDelta.x;
|
||||
scrolling.y += io.MouseDelta.y;
|
||||
}
|
||||
|
||||
// Context menu (under default mouse threshold)
|
||||
// We intentionally use the same button to demonstrate using mouse drag threshold. Some may feel panning should rely on same threshold.
|
||||
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
||||
if (drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
||||
ImGui::OpenPopupContextItem("context");
|
||||
if (ImGui::BeginPopup("context"))
|
||||
{
|
||||
if (adding_line)
|
||||
lines.pop_back();
|
||||
adding_line = false;
|
||||
if (ImGui::MenuItem("Remove one", NULL, false, lines.Size > 0)) { lines.pop_back(); }
|
||||
if (ImGui::MenuItem("Remove all", NULL, false, lines.Size > 0)) { lines.clear(); }
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Draw grid + all lines in the canvas
|
||||
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
|
||||
if (show_grid)
|
||||
{
|
||||
const float GRID_STEP = 64.0f;
|
||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40));
|
||||
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
|
||||
}
|
||||
for (int n = 0; n < lines.Size; n++)
|
||||
draw_list->AddLine(ImVec2(origin.x + lines[n].p0.x, origin.y + lines[n].p0.y), ImVec2(origin.x + lines[n].p1.x, origin.y + lines[n].p1.y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
draw_list->PopClipRect();
|
||||
if (adding_preview)
|
||||
points.pop_back();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
|
@ -2291,8 +2291,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels);
|
||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||
@ -2306,20 +2309,13 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||
{
|
||||
// Register glyph
|
||||
const int codepoint = src_tmp.GlyphsList[glyph_i];
|
||||
const stbtt_packedchar& pc = src_tmp.PackedChars[glyph_i];
|
||||
|
||||
const float char_advance_x_org = pc.xadvance;
|
||||
const float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
|
||||
float char_off_x = font_off_x;
|
||||
if (char_advance_x_org != char_advance_x_mod)
|
||||
char_off_x += cfg.PixelSnapH ? ImFloor((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
|
||||
|
||||
// Register glyph
|
||||
stbtt_aligned_quad q;
|
||||
float dummy_x = 0.0f, dummy_y = 0.0f;
|
||||
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &dummy_x, &dummy_y, &q, 0);
|
||||
dst_font->AddGlyph((ImWchar)codepoint, q.x0 + char_off_x, q.y0 + font_off_y, q.x1 + char_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, char_advance_x_mod);
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2474,10 +2470,11 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||
if (r->Font == NULL || r->GlyphID == 0)
|
||||
continue;
|
||||
|
||||
// Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH
|
||||
IM_ASSERT(r->Font->ContainerAtlas == atlas);
|
||||
ImVec2 uv0, uv1;
|
||||
atlas->CalcCustomRectUV(r, &uv0, &uv1);
|
||||
r->Font->AddGlyph((ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX);
|
||||
r->Font->AddGlyph(NULL, (ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX);
|
||||
}
|
||||
|
||||
// Build all fonts lookup tables
|
||||
@ -2887,8 +2884,29 @@ void ImFont::GrowIndex(int new_size)
|
||||
|
||||
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
|
||||
// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis).
|
||||
void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font.
|
||||
void ImFont::AddGlyph(ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x)
|
||||
{
|
||||
if (cfg != NULL)
|
||||
{
|
||||
// Clamp & recenter if needed
|
||||
const float advance_x_original = advance_x;
|
||||
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
|
||||
if (advance_x != advance_x_original)
|
||||
{
|
||||
float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
||||
x0 += char_off_x;
|
||||
x1 += char_off_x;
|
||||
}
|
||||
|
||||
// Snap to pixel
|
||||
if (cfg->PixelSnapH)
|
||||
advance_x = IM_ROUND(advance_x);
|
||||
|
||||
// Bake spacing
|
||||
advance_x += cfg->GlyphExtraSpacing.x;
|
||||
}
|
||||
|
||||
Glyphs.resize(Glyphs.Size + 1);
|
||||
ImFontGlyph& glyph = Glyphs.back();
|
||||
glyph.Codepoint = (unsigned int)codepoint;
|
||||
@ -2901,14 +2919,13 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1,
|
||||
glyph.V0 = v0;
|
||||
glyph.U1 = u1;
|
||||
glyph.V1 = v1;
|
||||
glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX
|
||||
|
||||
if (ConfigData->PixelSnapH)
|
||||
glyph.AdvanceX = IM_ROUND(glyph.AdvanceX);
|
||||
glyph.AdvanceX = advance_x;
|
||||
|
||||
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
|
||||
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
|
||||
float pad = ContainerAtlas->TexGlyphPadding + 0.99f;
|
||||
DirtyLookupTables = true;
|
||||
MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f);
|
||||
MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + pad) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + pad);
|
||||
}
|
||||
|
||||
void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
|
||||
|
@ -616,32 +616,25 @@ enum ImGuiItemStatusFlags_
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ImGuiButtonFlags_
|
||||
// Extend ImGuiButtonFlags_
|
||||
enum ImGuiButtonFlagsPrivate_
|
||||
{
|
||||
ImGuiButtonFlags_None = 0,
|
||||
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
|
||||
ImGuiButtonFlags_PressedOnClick = 1 << 1, // return true on click (mouse down event)
|
||||
ImGuiButtonFlags_PressedOnClickRelease = 1 << 2, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
|
||||
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 3, // return true on click + release even if the release event is not done while hovering the item
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 4, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 5, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 6, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 7, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowItemOverlap = 1 << 8, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
|
||||
ImGuiButtonFlags_DontClosePopups = 1 << 9, // disable automatically closing parent popup on press // [UNUSED]
|
||||
ImGuiButtonFlags_Disabled = 1 << 10, // disable interactions
|
||||
ImGuiButtonFlags_AlignTextBaseLine = 1 << 11, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
|
||||
ImGuiButtonFlags_NoKeyModifiers = 1 << 12, // disable mouse interaction if a key modifier is held
|
||||
ImGuiButtonFlags_NoHoldingActiveId = 1 << 13, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 14, // don't override navigation focus when activated
|
||||
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 15, // don't report as hovered when nav focus is on this item
|
||||
ImGuiButtonFlags_MouseButtonLeft = 1 << 16, // [Default] react on left mouse button
|
||||
ImGuiButtonFlags_MouseButtonRight = 1 << 17, // react on right mouse button
|
||||
ImGuiButtonFlags_MouseButtonMiddle = 1 << 18, // react on center mouse button
|
||||
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
|
||||
ImGuiButtonFlags_MouseButtonShift_ = 16,
|
||||
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft,
|
||||
ImGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event)
|
||||
ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
|
||||
ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
|
||||
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
|
||||
ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions
|
||||
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
|
||||
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
|
||||
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
|
||||
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated
|
||||
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
|
||||
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
|
||||
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease
|
||||
};
|
||||
@ -1310,8 +1303,9 @@ struct ImGuiContext
|
||||
|
||||
// Item/widgets state and tracking information
|
||||
ImGuiID HoveredId; // Hovered widget
|
||||
bool HoveredIdAllowOverlap;
|
||||
ImGuiID HoveredIdPreviousFrame;
|
||||
bool HoveredIdAllowOverlap;
|
||||
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
|
||||
float HoveredIdTimer; // Measure contiguous hovering time
|
||||
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
|
||||
ImGuiID ActiveId; // Active widget
|
||||
@ -1525,9 +1519,9 @@ struct ImGuiContext
|
||||
WheelingWindow = NULL;
|
||||
WheelingWindowTimer = 0.0f;
|
||||
|
||||
HoveredId = 0;
|
||||
HoveredId = HoveredIdPreviousFrame = 0;
|
||||
HoveredIdAllowOverlap = false;
|
||||
HoveredIdPreviousFrame = 0;
|
||||
HoveredIdDisabled = false;
|
||||
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
|
||||
ActiveId = 0;
|
||||
ActiveIdIsAlive = 0;
|
||||
|
@ -595,6 +595,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
}
|
||||
}
|
||||
|
||||
// Process while held
|
||||
bool held = false;
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
@ -615,6 +616,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
bool release_anywhere = (flags & ImGuiButtonFlags_PressedOnClickReleaseAnywhere) != 0;
|
||||
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_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)
|
||||
@ -627,6 +629,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
||||
{
|
||||
// When activated using Nav, we hold on the ActiveID until activation button is released
|
||||
if (g.NavActivateDownId != id)
|
||||
ClearActiveID();
|
||||
}
|
||||
@ -682,7 +685,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
||||
|
||||
bool ImGui::Button(const char* label, const ImVec2& size_arg)
|
||||
{
|
||||
return ButtonEx(label, size_arg, 0);
|
||||
return ButtonEx(label, size_arg, ImGuiButtonFlags_None);
|
||||
}
|
||||
|
||||
// Small buttons fits within text without additional vertical spacing.
|
||||
@ -698,7 +701,7 @@ bool ImGui::SmallButton(const char* label)
|
||||
|
||||
// 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)
|
||||
bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
|
||||
bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiButtonFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -715,7 +718,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg)
|
||||
return false;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
@ -544,8 +544,11 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
|
||||
ImFont* dst_font = cfg.DstFont;
|
||||
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
@ -576,14 +579,8 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
for (int y = info.Height; y > 0; y--, blit_dst += blit_dst_stride, blit_src += blit_src_stride)
|
||||
memcpy(blit_dst, blit_src, blit_src_stride);
|
||||
|
||||
float char_advance_x_org = info.AdvanceX;
|
||||
float char_advance_x_mod = ImClamp(char_advance_x_org, cfg.GlyphMinAdvanceX, cfg.GlyphMaxAdvanceX);
|
||||
float char_off_x = font_off_x;
|
||||
if (char_advance_x_org != char_advance_x_mod)
|
||||
char_off_x += cfg.PixelSnapH ? IM_FLOOR((char_advance_x_mod - char_advance_x_org) * 0.5f) : (char_advance_x_mod - char_advance_x_org) * 0.5f;
|
||||
|
||||
// Register glyph
|
||||
float x0 = info.OffsetX + char_off_x;
|
||||
float x0 = info.OffsetX + font_off_x;
|
||||
float y0 = info.OffsetY + font_off_y;
|
||||
float x1 = x0 + info.Width;
|
||||
float y1 = y0 + info.Height;
|
||||
@ -591,7 +588,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph((ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, char_advance_x_mod);
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
|
||||
}
|
||||
|
||||
src_tmp.Rects = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user