|
@@ -17,6 +17,7 @@
|
|
|
- PROGRAMMER GUIDE (read me!)
|
|
- PROGRAMMER GUIDE (read me!)
|
|
|
- API BREAKING CHANGES (read me when you update!)
|
|
- API BREAKING CHANGES (read me when you update!)
|
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ), TIPS
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ), TIPS
|
|
|
|
|
+ - How can I help?
|
|
|
- How do I update to a newer version of ImGui?
|
|
- How do I update to a newer version of ImGui?
|
|
|
- Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
|
|
- Can I have multiple widgets with the same label? Can I have widget without a label? (Yes)
|
|
|
- I integrated ImGui in my engine and the text or lines are blurry..
|
|
- I integrated ImGui in my engine and the text or lines are blurry..
|
|
@@ -148,6 +149,7 @@
|
|
|
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
|
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
|
|
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
|
|
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
|
|
|
|
|
|
|
|
|
|
+ - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you.
|
|
|
- 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis.
|
|
- 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis.
|
|
|
- 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete.
|
|
- 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete.
|
|
|
- 2015/08/29 (1.45) - with the addition of horizontal scrollbar we made various fixes to inconsistencies with dealing with cursor position.
|
|
- 2015/08/29 (1.45) - with the addition of horizontal scrollbar we made various fixes to inconsistencies with dealing with cursor position.
|
|
@@ -236,6 +238,10 @@
|
|
|
FREQUENTLY ASKED QUESTIONS (FAQ), TIPS
|
|
FREQUENTLY ASKED QUESTIONS (FAQ), TIPS
|
|
|
======================================
|
|
======================================
|
|
|
|
|
|
|
|
|
|
+ Q: How can I help?
|
|
|
|
|
+ A: - If you are experienced enough with ImGui and with C/C++, look at the todo list and see how you want/can help!
|
|
|
|
|
+ - Become a Patron/donate. Convince your company to become a Patron or provide serious funding for development time.
|
|
|
|
|
+
|
|
|
Q: How do I update to a newer version of ImGui?
|
|
Q: How do I update to a newer version of ImGui?
|
|
|
A: Overwrite the following files:
|
|
A: Overwrite the following files:
|
|
|
imgui.cpp
|
|
imgui.cpp
|
|
@@ -359,6 +365,7 @@
|
|
|
|
|
|
|
|
Q: How can I load multiple fonts?
|
|
Q: How can I load multiple fonts?
|
|
|
A: Use the font atlas to pack them into a single texture:
|
|
A: Use the font atlas to pack them into a single texture:
|
|
|
|
|
+ (Read extra_fonts/README.txt and the code in ImFontAtlas for more details.)
|
|
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
ImFont* font0 = io.Fonts->AddFontDefault();
|
|
ImFont* font0 = io.Fonts->AddFontDefault();
|
|
@@ -371,7 +378,7 @@
|
|
|
// Options
|
|
// Options
|
|
|
ImFontConfig config;
|
|
ImFontConfig config;
|
|
|
config.OversampleH = 3;
|
|
config.OversampleH = 3;
|
|
|
- config.OversampleV = 3;
|
|
|
|
|
|
|
+ config.OversampleV = 1;
|
|
|
config.GlyphExtraSpacing.x = 1.0f;
|
|
config.GlyphExtraSpacing.x = 1.0f;
|
|
|
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config);
|
|
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config);
|
|
|
|
|
|
|
@@ -383,8 +390,6 @@
|
|
|
io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges);
|
|
io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges);
|
|
|
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
|
|
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
|
|
|
|
|
|
|
|
- Read extra_fonts/README.txt or ImFontAtlas class for more details.
|
|
|
|
|
-
|
|
|
|
|
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
|
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
|
|
A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board.
|
|
A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board.
|
|
|
Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
|
|
Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
|
|
@@ -402,9 +407,10 @@
|
|
|
|
|
|
|
|
ISSUES & TODO-LIST
|
|
ISSUES & TODO-LIST
|
|
|
==================
|
|
==================
|
|
|
- Issue numbers (#) refer to github issues.
|
|
|
|
|
|
|
+ Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues
|
|
|
The list below consist mostly of notes of things to do before they are requested/discussed by users (at that point it usually happens on the github)
|
|
The list below consist mostly of notes of things to do before they are requested/discussed by users (at that point it usually happens on the github)
|
|
|
|
|
|
|
|
|
|
+ - doc: add a proper documentation+regression testing system (#435)
|
|
|
- window: maximum window size settings (per-axis). for large popups in particular user may not want the popup to fill all space.
|
|
- window: maximum window size settings (per-axis). for large popups in particular user may not want the popup to fill all space.
|
|
|
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
|
|
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
|
|
|
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis).
|
|
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis).
|
|
@@ -421,7 +427,7 @@
|
|
|
- window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
|
|
- window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
|
|
|
- draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command).
|
|
- draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command).
|
|
|
!- scrolling: allow immediately effective change of scroll if we haven't appended items yet
|
|
!- scrolling: allow immediately effective change of scroll if we haven't appended items yet
|
|
|
- - splitter: formalize the splitter idiom into an official api (we want to handle n-way split)
|
|
|
|
|
|
|
+ - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
|
|
|
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc.
|
|
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc.
|
|
|
- widgets: clean up widgets internal toward exposing everything.
|
|
- widgets: clean up widgets internal toward exposing everything.
|
|
|
- widgets: add disabled and read-only modes (#211)
|
|
- widgets: add disabled and read-only modes (#211)
|
|
@@ -444,13 +450,14 @@
|
|
|
- layout: horizontal flow until no space left (#404)
|
|
- layout: horizontal flow until no space left (#404)
|
|
|
- layout: more generic alignment state (left/right/centered) for single items?
|
|
- layout: more generic alignment state (left/right/centered) for single items?
|
|
|
- layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding.
|
|
- layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding.
|
|
|
|
|
+ - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
|
|
|
|
|
+ - columns: add a conditional parameter to SetColumnOffset() (#513, #125)
|
|
|
- columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125)
|
|
- columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125)
|
|
|
- - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#125)
|
|
|
|
|
- - columns: columns header to act as button (~sort op) and allow resize/reorder (#125)
|
|
|
|
|
- - columns: user specify columns size (#125)
|
|
|
|
|
|
|
+ - columns: columns header to act as button (~sort op) and allow resize/reorder (#513, #125)
|
|
|
|
|
+ - columns: user specify columns size (#513, #125)
|
|
|
- columns: flag to add horizontal separator above/below?
|
|
- columns: flag to add horizontal separator above/below?
|
|
|
- columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets)
|
|
- columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets)
|
|
|
- - combo: sparse combo boxes (via function call?)
|
|
|
|
|
|
|
+ - combo: sparse combo boxes (via function call?) / iterators
|
|
|
- combo: contents should extends to fit label if combo widget is small
|
|
- combo: contents should extends to fit label if combo widget is small
|
|
|
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
|
|
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
|
|
|
- listbox: multiple selection
|
|
- listbox: multiple selection
|
|
@@ -460,15 +467,16 @@
|
|
|
!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402)
|
|
!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402)
|
|
|
- popups: add variant using global identifier similar to Begin/End (#402)
|
|
- popups: add variant using global identifier similar to Begin/End (#402)
|
|
|
- popups: border options. richer api like BeginChild() perhaps? (#197)
|
|
- popups: border options. richer api like BeginChild() perhaps? (#197)
|
|
|
- - menus: local shortcuts, global shortcuts (#126)
|
|
|
|
|
|
|
+ - menus: local shortcuts, global shortcuts (#456, #126)
|
|
|
- menus: icons
|
|
- menus: icons
|
|
|
- menus: menubars: some sort of priority / effect of main menu-bar on desktop size?
|
|
- menus: menubars: some sort of priority / effect of main menu-bar on desktop size?
|
|
|
- statusbar: add a per-window status bar helper similar to what menubar does.
|
|
- statusbar: add a per-window status bar helper similar to what menubar does.
|
|
|
- - tabs
|
|
|
|
|
|
|
+ - tabs (#261, #351)
|
|
|
- separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
|
|
- separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
|
|
|
- - gauge: various forms of gauge/loading bars widgets
|
|
|
|
|
- color: the color helpers/typing is a mess and needs sorting out.
|
|
- color: the color helpers/typing is a mess and needs sorting out.
|
|
|
- - color: add a better color picker
|
|
|
|
|
|
|
+ - color: add a better color picker (#346)
|
|
|
|
|
+ - node/graph editor (#306)
|
|
|
|
|
+ - pie menus patterns (#434)
|
|
|
- plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals)
|
|
- plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals)
|
|
|
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
|
|
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
|
|
|
- plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value)
|
|
- plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value)
|
|
@@ -491,12 +499,14 @@
|
|
|
- textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (git issue #249)
|
|
- textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (git issue #249)
|
|
|
- settings: write more decent code to allow saving/loading new fields
|
|
- settings: write more decent code to allow saving/loading new fields
|
|
|
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file
|
|
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file
|
|
|
|
|
+ - style: add window shadows.
|
|
|
- style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding.
|
|
- style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding.
|
|
|
- style: color-box not always square?
|
|
- style: color-box not always square?
|
|
|
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
|
|
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
|
|
|
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
|
|
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
|
|
|
- style: global scale setting.
|
|
- style: global scale setting.
|
|
|
- text: simple markup language for color change?
|
|
- text: simple markup language for color change?
|
|
|
|
|
+ - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
|
|
|
- font: helper to add glyph redirect/replacements (e.g. redirect alternate apostrophe unicode code points to ascii one, etc.)
|
|
- font: helper to add glyph redirect/replacements (e.g. redirect alternate apostrophe unicode code points to ascii one, etc.)
|
|
|
- log: LogButtons() options for specifying depth and/or hiding depth slider
|
|
- log: LogButtons() options for specifying depth and/or hiding depth slider
|
|
|
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
|
|
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
|
|
@@ -506,14 +516,16 @@
|
|
|
- filters: handle wildcards (with implicit leading/trailing *), regexps
|
|
- filters: handle wildcards (with implicit leading/trailing *), regexps
|
|
|
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
|
|
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
|
|
|
!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
|
|
!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
|
|
|
- - keyboard: full keyboard navigation and focus.
|
|
|
|
|
|
|
+ - keyboard: full keyboard navigation and focus. (#323)
|
|
|
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
|
|
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
|
|
|
- input: rework IO system to be able to pass actual ordered/timestamped events.
|
|
- input: rework IO system to be able to pass actual ordered/timestamped events.
|
|
|
|
|
+ - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style).
|
|
|
- input: support track pad style scrolling & slider edit.
|
|
- input: support track pad style scrolling & slider edit.
|
|
|
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
|
|
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
|
|
|
- misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
|
|
- misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
|
|
|
- style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438)
|
|
- style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438)
|
|
|
- style editor: color child window height expressed in multiple of line height.
|
|
- style editor: color child window height expressed in multiple of line height.
|
|
|
|
|
+ - remote: make a system like RemoteImGui first-class citizen/project (#75)
|
|
|
- drawlist: user probably can't call Clear() because we expect a texture to be pushed in the stack.
|
|
- drawlist: user probably can't call Clear() because we expect a texture to be pushed in the stack.
|
|
|
- examples: directx9/directx11: save/restore device state more thoroughly.
|
|
- examples: directx9/directx11: save/restore device state more thoroughly.
|
|
|
- optimization: use another hash function than crc32, e.g. FNV1a
|
|
- optimization: use another hash function than crc32, e.g. FNV1a
|
|
@@ -528,13 +540,13 @@
|
|
|
|
|
|
|
|
#include "imgui.h"
|
|
#include "imgui.h"
|
|
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
|
|
|
|
+#define IMGUI_DEFINE_PLACEMENT_NEW
|
|
|
#include "imgui_internal.h"
|
|
#include "imgui_internal.h"
|
|
|
|
|
|
|
|
#include <ctype.h> // toupper, isprint
|
|
#include <ctype.h> // toupper, isprint
|
|
|
#include <math.h> // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf
|
|
#include <math.h> // sqrtf, fabsf, fmodf, powf, cosf, sinf, floorf, ceilf
|
|
|
#include <stdlib.h> // NULL, malloc, free, qsort, atoi
|
|
#include <stdlib.h> // NULL, malloc, free, qsort, atoi
|
|
|
#include <stdio.h> // vsnprintf, sscanf, printf
|
|
#include <stdio.h> // vsnprintf, sscanf, printf
|
|
|
-#include <new> // new (ptr)
|
|
|
|
|
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
|
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
|
|
#include <stddef.h> // intptr_t
|
|
#include <stddef.h> // intptr_t
|
|
|
#else
|
|
#else
|
|
@@ -611,7 +623,7 @@ static void ClosePopupToLevel(int remaining);
|
|
|
static void ClosePopup(ImGuiID id);
|
|
static void ClosePopup(ImGuiID id);
|
|
|
static bool IsPopupOpen(ImGuiID id);
|
|
static bool IsPopupOpen(ImGuiID id);
|
|
|
static ImGuiWindow* GetFrontMostModalRootWindow();
|
|
static ImGuiWindow* GetFrontMostModalRootWindow();
|
|
|
-static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiWindowFlags flags, int* last_dir, const ImRect& r_inner);
|
|
|
|
|
|
|
+static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* 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);
|
|
@@ -1535,6 +1547,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
|
|
ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
|
|
ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
|
|
|
ScrollbarX = ScrollbarY = false;
|
|
ScrollbarX = ScrollbarY = false;
|
|
|
ScrollbarSizes = ImVec2(0.0f, 0.0f);
|
|
ScrollbarSizes = ImVec2(0.0f, 0.0f);
|
|
|
|
|
+ BorderSize = 0.0f;
|
|
|
Active = WasActive = false;
|
|
Active = WasActive = false;
|
|
|
Accessed = false;
|
|
Accessed = false;
|
|
|
Collapsed = false;
|
|
Collapsed = false;
|
|
@@ -1553,7 +1566,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
|
|
FontWindowScale = 1.0f;
|
|
FontWindowScale = 1.0f;
|
|
|
|
|
|
|
|
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
|
|
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
|
|
|
- new(DrawList) ImDrawList();
|
|
|
|
|
|
|
+ IM_PLACEMENT_NEW(DrawList) ImDrawList();
|
|
|
DrawList->_OwnerName = Name;
|
|
DrawList->_OwnerName = Name;
|
|
|
RootWindow = NULL;
|
|
RootWindow = NULL;
|
|
|
RootNonPopupWindow = NULL;
|
|
RootNonPopupWindow = NULL;
|
|
@@ -1827,7 +1840,7 @@ size_t ImGui::GetInternalStateSize()
|
|
|
void ImGui::SetInternalState(void* state, bool construct)
|
|
void ImGui::SetInternalState(void* state, bool construct)
|
|
|
{
|
|
{
|
|
|
if (construct)
|
|
if (construct)
|
|
|
- new (state) ImGuiState();
|
|
|
|
|
|
|
+ IM_PLACEMENT_NEW(state) ImGuiState();
|
|
|
GImGui = (ImGuiState*)state;
|
|
GImGui = (ImGuiState*)state;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1872,7 +1885,7 @@ void ImGui::NewFrame()
|
|
|
{
|
|
{
|
|
|
// Initialize on first frame
|
|
// Initialize on first frame
|
|
|
g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer));
|
|
g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer));
|
|
|
- new(g.LogClipboard) ImGuiTextBuffer();
|
|
|
|
|
|
|
+ IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer();
|
|
|
|
|
|
|
|
IM_ASSERT(g.Settings.empty());
|
|
IM_ASSERT(g.Settings.empty());
|
|
|
LoadSettings();
|
|
LoadSettings();
|
|
@@ -2276,15 +2289,19 @@ static void AddDrawListToRenderList(ImVector<ImDrawList*>& out_render_list, ImDr
|
|
|
{
|
|
{
|
|
|
if (!draw_list->CmdBuffer.empty() && !draw_list->VtxBuffer.empty())
|
|
if (!draw_list->CmdBuffer.empty() && !draw_list->VtxBuffer.empty())
|
|
|
{
|
|
{
|
|
|
- if (draw_list->CmdBuffer.back().ElemCount == 0)
|
|
|
|
|
|
|
+ // Remove trailing command if unused
|
|
|
|
|
+ ImDrawCmd& last_cmd = draw_list->CmdBuffer.back();
|
|
|
|
|
+ if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL)
|
|
|
draw_list->CmdBuffer.pop_back();
|
|
draw_list->CmdBuffer.pop_back();
|
|
|
|
|
+
|
|
|
out_render_list.push_back(draw_list);
|
|
out_render_list.push_back(draw_list);
|
|
|
|
|
|
|
|
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices)
|
|
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices)
|
|
|
// If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly.
|
|
// If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly.
|
|
|
const unsigned long long int max_vtx_idx = (unsigned long long int)1L << (sizeof(ImDrawIdx)*8);
|
|
const unsigned long long int max_vtx_idx = (unsigned long long int)1L << (sizeof(ImDrawIdx)*8);
|
|
|
(void)max_vtx_idx;
|
|
(void)max_vtx_idx;
|
|
|
- IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= max_vtx_idx); // Too many vertices in same ImDrawList
|
|
|
|
|
|
|
+ IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
|
|
|
|
+ IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= max_vtx_idx); // Too many vertices in same ImDrawList. See comment above.
|
|
|
|
|
|
|
|
GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size;
|
|
GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size;
|
|
|
GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size;
|
|
GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size;
|
|
@@ -2488,17 +2505,8 @@ static const char* FindTextDisplayEnd(const char* text, const char* text_end)
|
|
|
if (!text_end)
|
|
if (!text_end)
|
|
|
text_end = (const char*)-1;
|
|
text_end = (const char*)-1;
|
|
|
|
|
|
|
|
- ImGuiState& g = *GImGui;
|
|
|
|
|
- if (g.DisableHideTextAfterDoubleHash > 0)
|
|
|
|
|
- {
|
|
|
|
|
- while (text_display_end < text_end && *text_display_end != '\0')
|
|
|
|
|
- text_display_end++;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
|
|
|
|
- text_display_end++;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
|
|
|
|
+ text_display_end++;
|
|
|
return text_display_end;
|
|
return text_display_end;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2736,6 +2744,8 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
|
|
|
|
|
|
|
|
ImFont* font = g.Font;
|
|
ImFont* font = g.Font;
|
|
|
const float font_size = g.FontSize;
|
|
const float font_size = g.FontSize;
|
|
|
|
|
+ if (text == text_display_end)
|
|
|
|
|
+ return ImVec2(0.0f, font_size);
|
|
|
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
|
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
|
|
|
|
|
|
|
// Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field)
|
|
// Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field)
|
|
@@ -3421,7 +3431,7 @@ 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, ImGuiWindowFlags flags, int* last_dir, const ImRect& r_inner)
|
|
|
|
|
|
|
+static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& r_inner)
|
|
|
{
|
|
{
|
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
|
|
|
|
|
@@ -3431,7 +3441,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
|
|
|
r_outer.Reduce(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.Reduce(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);
|
|
|
|
|
|
|
|
- for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Right, down, up, left. Favor last used direction.
|
|
|
|
|
|
|
+ for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction).
|
|
|
{
|
|
{
|
|
|
const int dir = (n == -1) ? *last_dir : n;
|
|
const int dir = (n == -1) ? *last_dir : 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);
|
|
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);
|
|
@@ -3441,12 +3451,8 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
|
|
|
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 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);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Fallback
|
|
|
|
|
|
|
+ // Fallback, try to keep within display
|
|
|
*last_dir = -1;
|
|
*last_dir = -1;
|
|
|
- if (flags & ImGuiWindowFlags_Tooltip) // For tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
|
|
|
|
|
- return base_pos + ImVec2(2,2);
|
|
|
|
|
-
|
|
|
|
|
- // Otherwise try to keep within display
|
|
|
|
|
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);
|
|
@@ -3470,7 +3476,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
|
|
|
|
|
|
|
// Create window the first time
|
|
// Create window the first time
|
|
|
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
|
|
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
|
|
|
- new(window) ImGuiWindow(name);
|
|
|
|
|
|
|
+ IM_PLACEMENT_NEW(window) ImGuiWindow(name);
|
|
|
window->Flags = flags;
|
|
window->Flags = flags;
|
|
|
|
|
|
|
|
if (flags & ImGuiWindowFlags_NoSavedSettings)
|
|
if (flags & ImGuiWindowFlags_NoSavedSettings)
|
|
@@ -3810,19 +3816,21 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|
|
rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight());
|
|
rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight());
|
|
|
else
|
|
else
|
|
|
rect_to_avoid = ImRect(parent_window->Pos.x + style.ItemSpacing.x, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - style.ItemSpacing.x - parent_window->ScrollbarSizes.x, FLT_MAX); // We want some overlap to convey the relative depth of each popup (here hard-coded to 4)
|
|
rect_to_avoid = ImRect(parent_window->Pos.x + style.ItemSpacing.x, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - style.ItemSpacing.x - parent_window->ScrollbarSizes.x, FLT_MAX); // We want some overlap to convey the relative depth of each popup (here hard-coded to 4)
|
|
|
- window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, flags, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
|
|
|
|
+ window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
}
|
|
}
|
|
|
else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_appearing_after_being_hidden)
|
|
else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_appearing_after_being_hidden)
|
|
|
{
|
|
{
|
|
|
ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1);
|
|
ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1);
|
|
|
- window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, flags, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
|
|
|
|
+ window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Position tooltip (always follows mouse)
|
|
// Position tooltip (always follows mouse)
|
|
|
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api)
|
|
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api)
|
|
|
{
|
|
{
|
|
|
ImRect rect_to_avoid(g.IO.MousePos.x - 16, g.IO.MousePos.y - 8, g.IO.MousePos.x + 24, g.IO.MousePos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead?
|
|
ImRect rect_to_avoid(g.IO.MousePos.x - 16, g.IO.MousePos.y - 8, g.IO.MousePos.x + 24, g.IO.MousePos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead?
|
|
|
- window->PosFloat = FindBestPopupWindowPos(g.IO.MousePos, window->Size, flags, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
|
|
|
|
+ window->PosFloat = FindBestPopupWindowPos(g.IO.MousePos, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
|
|
+ if (window->AutoPosLastDirection == -1)
|
|
|
|
|
+ window->PosFloat = g.IO.MousePos + 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.
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// User moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
|
|
// User moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
|
|
@@ -3939,6 +3947,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|
|
window->ScrollbarY = (flags & ImGuiWindowFlags_ForceVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
|
|
window->ScrollbarY = (flags & ImGuiWindowFlags_ForceVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
|
|
|
window->ScrollbarX = (flags & ImGuiWindowFlags_ForceHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
|
|
window->ScrollbarX = (flags & ImGuiWindowFlags_ForceHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
|
|
|
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
|
|
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
|
|
|
|
|
+ window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
|
|
|
|
|
|
|
|
// Window background
|
|
// Window background
|
|
|
if (bg_alpha > 0.0f)
|
|
if (bg_alpha > 0.0f)
|
|
@@ -3978,11 +3987,10 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|
|
// (after the input handling so we don't have a frame of latency)
|
|
// (after the input handling so we don't have a frame of latency)
|
|
|
if (!(flags & ImGuiWindowFlags_NoResize))
|
|
if (!(flags & ImGuiWindowFlags_NoResize))
|
|
|
{
|
|
{
|
|
|
- const float border_size = (window->Flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
|
|
|
|
|
const ImVec2 br = window->Rect().GetBR();
|
|
const ImVec2 br = window->Rect().GetBR();
|
|
|
- window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -border_size));
|
|
|
|
|
- window->DrawList->PathLineTo(br + ImVec2(-border_size, -resize_corner_size));
|
|
|
|
|
- window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - border_size, br.y - window_rounding - border_size), window_rounding, 0, 3);
|
|
|
|
|
|
|
+ window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->BorderSize));
|
|
|
|
|
+ window->DrawList->PathLineTo(br + ImVec2(-window->BorderSize, -resize_corner_size));
|
|
|
|
|
+ window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->BorderSize, br.y - window_rounding - window->BorderSize), window_rounding, 0, 3);
|
|
|
window->DrawList->PathFill(resize_col);
|
|
window->DrawList->PathFill(resize_col);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4072,13 +4080,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|
|
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
|
|
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
|
|
|
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
|
|
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
|
|
|
const ImRect title_bar_rect = window->TitleBarRect();
|
|
const ImRect title_bar_rect = window->TitleBarRect();
|
|
|
- const float border_size = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
|
|
|
|
|
|
|
+ const float border_size = window->BorderSize;
|
|
|
ImRect clip_rect;
|
|
ImRect clip_rect;
|
|
|
clip_rect.Min.x = title_bar_rect.Min.x + 0.5f + ImMax(border_size, window->WindowPadding.x*0.5f);
|
|
clip_rect.Min.x = title_bar_rect.Min.x + 0.5f + ImMax(border_size, window->WindowPadding.x*0.5f);
|
|
|
clip_rect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + 0.5f + border_size;
|
|
clip_rect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + 0.5f + border_size;
|
|
|
clip_rect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, window->WindowPadding.x*0.5f);
|
|
clip_rect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, window->WindowPadding.x*0.5f);
|
|
|
clip_rect.Max.y = window->Pos.y + window->Size.y - border_size - window->ScrollbarSizes.y;
|
|
clip_rect.Max.y = window->Pos.y + window->Size.y - border_size - window->ScrollbarSizes.y;
|
|
|
-
|
|
|
|
|
PushClipRect(clip_rect.Min, clip_rect.Max, true);
|
|
PushClipRect(clip_rect.Min, clip_rect.Max, true);
|
|
|
|
|
|
|
|
// Clear 'accessed' flag last thing
|
|
// Clear 'accessed' flag last thing
|
|
@@ -4094,7 +4101,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
|
|
|
window->Collapsed = parent_window && parent_window->Collapsed;
|
|
window->Collapsed = parent_window && parent_window->Collapsed;
|
|
|
|
|
|
|
|
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
|
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
|
|
- window->Collapsed |= (window->ClipRect.Min.x >= window->ClipRect.Max.x || window->ClipRect.Min.y >= window->ClipRect.Max.y);
|
|
|
|
|
|
|
+ window->Collapsed |= (window->ClippedWindowRect.Min.x >= window->ClippedWindowRect.Max.x || window->ClippedWindowRect.Min.y >= window->ClippedWindowRect.Max.y);
|
|
|
|
|
|
|
|
// We also hide the window from rendering because we've already added its border to the command list.
|
|
// We also hide the window from rendering because we've already added its border to the command list.
|
|
|
// (we could perform the check earlier in the function but it is simpler at this point)
|
|
// (we could perform the check earlier in the function but it is simpler at this point)
|
|
@@ -4145,7 +4152,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal)
|
|
|
bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX);
|
|
bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX);
|
|
|
float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f;
|
|
float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f;
|
|
|
const ImRect window_rect = window->Rect();
|
|
const ImRect window_rect = window->Rect();
|
|
|
- const float border_size = (window->Flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
|
|
|
|
|
|
|
+ const float border_size = window->BorderSize;
|
|
|
ImRect bb = horizontal
|
|
ImRect bb = horizontal
|
|
|
? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size)
|
|
? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size)
|
|
|
: ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size);
|
|
: ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size);
|
|
@@ -4278,8 +4285,8 @@ static void PushMultiItemsWidths(int components, float w_full)
|
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
|
if (w_full <= 0.0f)
|
|
if (w_full <= 0.0f)
|
|
|
w_full = ImGui::CalcItemWidth();
|
|
w_full = ImGui::CalcItemWidth();
|
|
|
- const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
|
|
|
|
- const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
|
|
|
|
|
|
|
+ const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
|
|
|
|
+ const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components-1)));
|
|
|
window->DC.ItemWidthStack.push_back(w_item_last);
|
|
window->DC.ItemWidthStack.push_back(w_item_last);
|
|
|
for (int i = 0; i < components-1; i++)
|
|
for (int i = 0; i < components-1; i++)
|
|
|
window->DC.ItemWidthStack.push_back(w_item_one);
|
|
window->DC.ItemWidthStack.push_back(w_item_one);
|
|
@@ -4300,9 +4307,8 @@ float ImGui::CalcItemWidth()
|
|
|
if (w < 0.0f)
|
|
if (w < 0.0f)
|
|
|
{
|
|
{
|
|
|
// Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well.
|
|
// Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well.
|
|
|
- ImGuiState& g = *GImGui;
|
|
|
|
|
float width_to_right_edge = ImGui::GetContentRegionAvail().x;
|
|
float width_to_right_edge = ImGui::GetContentRegionAvail().x;
|
|
|
- w = ImMax(1.0f, width_to_right_edge + w - g.Style.FramePadding.x * 2.0f);
|
|
|
|
|
|
|
+ w = ImMax(1.0f, width_to_right_edge + w);
|
|
|
}
|
|
}
|
|
|
w = (float)(int)w;
|
|
w = (float)(int)w;
|
|
|
return w;
|
|
return w;
|
|
@@ -5163,8 +5169,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
|
|
const float w = CalcItemWidth();
|
|
const float w = CalcItemWidth();
|
|
|
|
|
|
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
- const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2));
|
|
|
|
|
- const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size);
|
|
|
|
|
|
|
+ const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2));
|
|
|
|
|
+ const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size);
|
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
|
if (!ItemAdd(total_bb, NULL))
|
|
if (!ItemAdd(total_bb, NULL))
|
|
|
return;
|
|
return;
|
|
@@ -5173,7 +5179,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
|
|
const char* value_text_begin = &g.TempBuffer[0];
|
|
const char* value_text_begin = &g.TempBuffer[0];
|
|
|
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
|
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
|
|
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImGuiAlign_VCenter);
|
|
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImGuiAlign_VCenter);
|
|
|
- RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
|
|
|
|
|
|
+ if (label_size.x > 0.0f)
|
|
|
|
|
+ RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
|
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
|
@@ -5271,7 +5278,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
|
|
ImGuiState& g = *GImGui;
|
|
ImGuiState& g = *GImGui;
|
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiStyle& style = g.Style;
|
|
|
const ImGuiID id = window->GetID(label);
|
|
const ImGuiID id = window->GetID(label);
|
|
|
- const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
|
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrentLineTextBaseOffset)
|
|
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrentLineTextBaseOffset)
|
|
@@ -5361,7 +5368,7 @@ static bool CloseWindowButton(bool* p_opened)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (p_opened != NULL && pressed)
|
|
if (p_opened != NULL && pressed)
|
|
|
- *p_opened = !*p_opened;
|
|
|
|
|
|
|
+ *p_opened = false;
|
|
|
|
|
|
|
|
return pressed;
|
|
return pressed;
|
|
|
}
|
|
}
|
|
@@ -5599,8 +5606,9 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display
|
|
|
str_id = label;
|
|
str_id = label;
|
|
|
if (label == NULL)
|
|
if (label == NULL)
|
|
|
label = str_id;
|
|
label = str_id;
|
|
|
|
|
+ const bool label_hide_text_after_double_hash = (label == str_id); // Only search and hide text after ## if we have passed label and ID separately, otherwise allow "##" within format string.
|
|
|
const ImGuiID id = window->GetID(str_id);
|
|
const ImGuiID id = window->GetID(str_id);
|
|
|
- const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, label_hide_text_after_double_hash);
|
|
|
|
|
|
|
|
// We vertically grow up to current line height up the typical widget height.
|
|
// We vertically grow up to current line height up the typical widget height.
|
|
|
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it
|
|
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it
|
|
@@ -5663,7 +5671,7 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display
|
|
|
RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false);
|
|
RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false);
|
|
|
if (g.LogEnabled)
|
|
if (g.LogEnabled)
|
|
|
LogRenderedText(text_pos, ">");
|
|
LogRenderedText(text_pos, ">");
|
|
|
- RenderText(text_pos, label);
|
|
|
|
|
|
|
+ RenderText(text_pos, label, NULL, label_hide_text_after_double_hash);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return opened;
|
|
return opened;
|
|
@@ -5963,7 +5971,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label
|
|
|
|
|
|
|
|
char buf[32];
|
|
char buf[32];
|
|
|
DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf));
|
|
DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf));
|
|
|
- bool value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize() - g.Style.FramePadding*2.0f, ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
|
|
|
|
|
|
|
+ bool value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
|
|
|
if (g.ScalarAsInputTextId == 0)
|
|
if (g.ScalarAsInputTextId == 0)
|
|
|
{
|
|
{
|
|
|
// First frame
|
|
// First frame
|
|
@@ -6164,7 +6172,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
|
|
|
const float w = CalcItemWidth();
|
|
const float w = CalcItemWidth();
|
|
|
|
|
|
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
|
|
|
|
|
|
|
+ const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
|
|
|
|
|
|
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
|
|
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
|
|
@@ -6255,7 +6263,6 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float
|
|
|
char value_buf[64];
|
|
char value_buf[64];
|
|
|
char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
|
|
char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
|
|
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImGuiAlign_Center);
|
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImGuiAlign_Center);
|
|
|
-
|
|
|
|
|
if (label_size.x > 0.0f)
|
|
if (label_size.x > 0.0f)
|
|
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
|
|
|
|
|
|
@@ -6462,7 +6469,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
|
|
|
const float w = CalcItemWidth();
|
|
const float w = CalcItemWidth();
|
|
|
|
|
|
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
|
|
|
|
|
|
|
+ const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
|
|
const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
|
const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
|
|
|
|
|
@@ -6667,9 +6674,9 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge
|
|
|
ImGuiState& g = *GImGui;
|
|
ImGuiState& g = *GImGui;
|
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiStyle& style = g.Style;
|
|
|
|
|
|
|
|
- const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
if (graph_size.x == 0.0f)
|
|
if (graph_size.x == 0.0f)
|
|
|
- graph_size.x = CalcItemWidth() + (style.FramePadding.x * 2);
|
|
|
|
|
|
|
+ graph_size.x = CalcItemWidth();
|
|
|
if (graph_size.y == 0.0f)
|
|
if (graph_size.y == 0.0f)
|
|
|
graph_size.y = label_size.y + (style.FramePadding.y * 2);
|
|
graph_size.y = label_size.y + (style.FramePadding.y * 2);
|
|
|
|
|
|
|
@@ -6758,7 +6765,8 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge
|
|
|
if (overlay_text)
|
|
if (overlay_text)
|
|
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImGuiAlign_Center);
|
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImGuiAlign_Center);
|
|
|
|
|
|
|
|
- RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
|
|
|
|
|
|
+ if (label_size.x > 0.0f)
|
|
|
|
|
+ RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
struct ImGuiPlotArrayGetterData
|
|
struct ImGuiPlotArrayGetterData
|
|
@@ -6809,15 +6817,16 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiStyle& style = g.Style;
|
|
|
|
|
|
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
|
- const ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth() + style.FramePadding.x*2.0f, g.FontSize + style.FramePadding.y*2.0f));
|
|
|
|
|
|
|
+ ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f));
|
|
|
ItemSize(bb, style.FramePadding.y);
|
|
ItemSize(bb, style.FramePadding.y);
|
|
|
if (!ItemAdd(bb, NULL))
|
|
if (!ItemAdd(bb, NULL))
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
// Render
|
|
// Render
|
|
|
fraction = ImSaturate(fraction);
|
|
fraction = ImSaturate(fraction);
|
|
|
- const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
|
|
|
|
|
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
|
|
|
+ bb.Reduce(ImVec2(window->BorderSize, window->BorderSize));
|
|
|
|
|
+ const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
|
|
|
RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);
|
|
RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);
|
|
|
|
|
|
|
|
// Default displaying the fraction as percentage string, but user can override it
|
|
// Default displaying the fraction as percentage string, but user can override it
|
|
@@ -6875,7 +6884,8 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
|
|
|
|
|
|
|
if (g.LogEnabled)
|
|
if (g.LogEnabled)
|
|
|
LogRenderedText(text_bb.GetTL(), *v ? "[x]" : "[ ]");
|
|
LogRenderedText(text_bb.GetTL(), *v ? "[x]" : "[ ]");
|
|
|
- RenderText(text_bb.GetTL(), label);
|
|
|
|
|
|
|
+ if (label_size.x > 0.0f)
|
|
|
|
|
+ RenderText(text_bb.GetTL(), label);
|
|
|
|
|
|
|
|
return pressed;
|
|
return pressed;
|
|
|
}
|
|
}
|
|
@@ -6942,7 +6952,8 @@ bool ImGui::RadioButton(const char* label, bool active)
|
|
|
|
|
|
|
|
if (g.LogEnabled)
|
|
if (g.LogEnabled)
|
|
|
LogRenderedText(text_bb.GetTL(), active ? "(x)" : "( )");
|
|
LogRenderedText(text_bb.GetTL(), active ? "(x)" : "( )");
|
|
|
- RenderText(text_bb.GetTL(), label);
|
|
|
|
|
|
|
+ if (label_size.x > 0.0f)
|
|
|
|
|
+ RenderText(text_bb.GetTL(), label);
|
|
|
|
|
|
|
|
return pressed;
|
|
return pressed;
|
|
|
}
|
|
}
|
|
@@ -7218,9 +7229,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
|
|
const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0;
|
|
const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0;
|
|
|
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
|
|
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
|
|
|
|
|
|
|
|
- const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
- ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), is_multiline ? ImGui::GetTextLineHeight() * 8.0f : label_size.y); // Arbitrary default of 8 lines high for multi-line
|
|
|
|
|
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size + style.FramePadding*2.0f);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
|
|
+ ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? ImGui::GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line
|
|
|
|
|
+ const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f));
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f));
|
|
|
|
|
|
|
|
ImGuiWindow* draw_window = window;
|
|
ImGuiWindow* draw_window = window;
|
|
@@ -7580,7 +7591,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
|
|
|
|
|
|
// Render
|
|
// Render
|
|
|
- const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x + style.FramePadding.x*2.0f, frame_bb.Min.y + size.y + style.FramePadding.y*2.0f);
|
|
|
|
|
|
|
+ const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size
|
|
|
ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
|
ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
|
|
ImVec2 text_size(0.f, 0.f);
|
|
ImVec2 text_size(0.f, 0.f);
|
|
|
if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY")))
|
|
if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY")))
|
|
@@ -7771,15 +7782,13 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data
|
|
|
|
|
|
|
|
ImGuiState& g = *GImGui;
|
|
ImGuiState& g = *GImGui;
|
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiStyle& style = g.Style;
|
|
|
- const float w = CalcItemWidth();
|
|
|
|
|
- const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
|
ImGui::BeginGroup();
|
|
ImGui::BeginGroup();
|
|
|
ImGui::PushID(label);
|
|
ImGui::PushID(label);
|
|
|
- const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding * 2;
|
|
|
|
|
|
|
+ const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding*2.0f;
|
|
|
if (step_ptr)
|
|
if (step_ptr)
|
|
|
- ImGui::PushItemWidth(ImMax(1.0f, w - (button_sz.x + style.ItemInnerSpacing.x)*2));
|
|
|
|
|
|
|
+ ImGui::PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2));
|
|
|
|
|
|
|
|
char buf[64];
|
|
char buf[64];
|
|
|
DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf));
|
|
DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf));
|
|
@@ -7989,7 +7998,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
|
|
const float w = CalcItemWidth();
|
|
const float w = CalcItemWidth();
|
|
|
|
|
|
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
|
|
|
|
|
|
|
+ const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
|
if (!ItemAdd(total_bb, &id))
|
|
if (!ItemAdd(total_bb, &id))
|
|
@@ -8091,7 +8100,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
PopClipRect();
|
|
PopClipRect();
|
|
|
|
|
|
|
|
ImGuiID id = window->GetID(label);
|
|
ImGuiID id = window->GetID(label);
|
|
|
- ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
+ ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
|
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
ImVec2 pos = window->DC.CursorPos;
|
|
|
pos.y += window->DC.CurrentLineTextBaseOffset;
|
|
pos.y += window->DC.CurrentLineTextBaseOffset;
|
|
@@ -8175,10 +8184,10 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
|
|
|
|
|
|
|
|
const ImGuiStyle& style = ImGui::GetStyle();
|
|
const ImGuiStyle& style = ImGui::GetStyle();
|
|
|
const ImGuiID id = ImGui::GetID(label);
|
|
const ImGuiID id = ImGui::GetID(label);
|
|
|
- const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
+ const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
|
|
|
|
|
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
|
// Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
|
|
- ImVec2 size = CalcItemSize(size_arg, CalcItemWidth() + style.FramePadding.x * 2.0f, ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
|
|
|
|
|
|
|
+ ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y);
|
|
|
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
|
|
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
|
|
|
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
|
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
|
|
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
|
@@ -8333,8 +8342,7 @@ bool ImGui::BeginMenuBar()
|
|
|
ImGui::BeginGroup(); // Save position
|
|
ImGui::BeginGroup(); // Save position
|
|
|
ImGui::PushID("##menubar");
|
|
ImGui::PushID("##menubar");
|
|
|
ImRect rect = window->MenuBarRect();
|
|
ImRect rect = window->MenuBarRect();
|
|
|
- float border_size = (window->Flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
|
|
|
|
|
- PushClipRect(ImVec2(rect.Min.x+0.5f, rect.Min.y-0.5f+border_size), ImVec2(rect.Max.x+0.5f, rect.Max.y-0.5f), false);
|
|
|
|
|
|
|
+ PushClipRect(ImVec2(rect.Min.x+0.5f, rect.Min.y-0.5f+window->BorderSize), ImVec2(rect.Max.x+0.5f, rect.Max.y-0.5f), false);
|
|
|
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y);
|
|
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y);
|
|
|
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
|
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
|
|
window->DC.MenuBarAppending = true;
|
|
window->DC.MenuBarAppending = true;
|
|
@@ -8527,7 +8535,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
|
|
|
edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3;
|
|
edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3;
|
|
|
|
|
|
|
|
float f[4] = { col[0], col[1], col[2], col[3] };
|
|
float f[4] = { col[0], col[1], col[2], col[3] };
|
|
|
-
|
|
|
|
|
if (edit_mode == ImGuiColorEditMode_HSV)
|
|
if (edit_mode == ImGuiColorEditMode_HSV)
|
|
|
ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
|
|
ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
|
|
|
|
|
|
|
@@ -8547,8 +8554,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
|
|
|
{
|
|
{
|
|
|
// RGB/HSV 0..255 Sliders
|
|
// RGB/HSV 0..255 Sliders
|
|
|
const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x);
|
|
const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x);
|
|
|
- const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
|
|
|
|
- const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1)));
|
|
|
|
|
|
|
+ const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
|
|
|
|
+ const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1)));
|
|
|
|
|
|
|
|
const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x);
|
|
const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x);
|
|
|
const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
|
const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
|
@@ -8583,18 +8590,19 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
|
|
|
else
|
|
else
|
|
|
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]);
|
|
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]);
|
|
|
ImGui::PushItemWidth(w_slider_all - style.ItemInnerSpacing.x);
|
|
ImGui::PushItemWidth(w_slider_all - style.ItemInnerSpacing.x);
|
|
|
- value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
|
|
|
|
|
|
|
+ if (ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase))
|
|
|
|
|
+ {
|
|
|
|
|
+ value_changed |= true;
|
|
|
|
|
+ char* p = buf;
|
|
|
|
|
+ while (*p == '#' || ImCharIsSpace(*p))
|
|
|
|
|
+ p++;
|
|
|
|
|
+ i[0] = i[1] = i[2] = i[3] = 0;
|
|
|
|
|
+ if (alpha)
|
|
|
|
|
+ sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned)
|
|
|
|
|
+ else
|
|
|
|
|
+ sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
|
|
|
|
+ }
|
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopItemWidth();
|
|
|
- char* p = buf;
|
|
|
|
|
- while (*p == '#' || ImCharIsSpace(*p))
|
|
|
|
|
- p++;
|
|
|
|
|
-
|
|
|
|
|
- // Treat at unsigned (%X is unsigned)
|
|
|
|
|
- i[0] = i[1] = i[2] = i[3] = 0;
|
|
|
|
|
- if (alpha)
|
|
|
|
|
- sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]);
|
|
|
|
|
- else
|
|
|
|
|
- sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
|
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -8615,15 +8623,15 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
|
|
|
const char* button_titles[3] = { "RGB", "HSV", "HEX" };
|
|
const char* button_titles[3] = { "RGB", "HSV", "HEX" };
|
|
|
if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups))
|
|
if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups))
|
|
|
g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away!
|
|
g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away!
|
|
|
- ImGui::SameLine();
|
|
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const char* label_display_end = FindTextDisplayEnd(label);
|
|
|
|
|
+ if (label != label_display_end)
|
|
|
{
|
|
{
|
|
|
- ImGui::SameLine(0, style.ItemInnerSpacing.x);
|
|
|
|
|
|
|
+ ImGui::SameLine(0, (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) ? -1.0f : style.ItemInnerSpacing.x);
|
|
|
|
|
+ ImGui::TextUnformatted(label, label_display_end);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
|
|
|
|
|
-
|
|
|
|
|
// Convert back
|
|
// Convert back
|
|
|
for (int n = 0; n < 4; n++)
|
|
for (int n = 0; n < 4; n++)
|
|
|
f[n] = i[n] / 255.0f;
|
|
f[n] = i[n] / 255.0f;
|
|
@@ -9283,7 +9291,6 @@ void ImGui::ShowMetricsWindow(bool* opened)
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
ImGuiState& g = *GImGui; // Access private state
|
|
ImGuiState& g = *GImGui; // Access private state
|
|
|
- g.DisableHideTextAfterDoubleHash++; // Not exposed (yet). Disable processing that hides text after '##' markers.
|
|
|
|
|
Funcs::NodeWindows(g.Windows, "Windows");
|
|
Funcs::NodeWindows(g.Windows, "Windows");
|
|
|
if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size))
|
|
if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size))
|
|
|
{
|
|
{
|
|
@@ -9309,7 +9316,6 @@ void ImGui::ShowMetricsWindow(bool* opened)
|
|
|
ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
|
|
ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
|
|
|
ImGui::TreePop();
|
|
ImGui::TreePop();
|
|
|
}
|
|
}
|
|
|
- g.DisableHideTextAfterDoubleHash--;
|
|
|
|
|
}
|
|
}
|
|
|
ImGui::End();
|
|
ImGui::End();
|
|
|
}
|
|
}
|