1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-11-25 00:00:40 +01:00

Merge branch 'master' into 2016-02-colorpicker

This commit is contained in:
omar 2017-08-08 11:30:10 +08:00
commit a4012fd5b2

154
imgui.cpp
View File

@ -16,6 +16,8 @@
- MISSION STATEMENT - MISSION STATEMENT
- END-USER GUIDE - END-USER GUIDE
- PROGRAMMER GUIDE (read me!) - PROGRAMMER GUIDE (read me!)
- Read first
- Getting started with integrating imgui in your code/engine
- 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 can I help?
@ -50,22 +52,21 @@
Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes:
- doesn't look fancy, doesn't animate - doesn't look fancy, doesn't animate
- limited layout features, intricate layouts are typically crafted in code - limited layout features, intricate layouts are typically crafted in code
- occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction.
END-USER GUIDE END-USER GUIDE
============== ==============
- double-click title bar to collapse window - Double-click title bar to collapse window
- click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin() - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin()
- click and drag on lower right corner to resize window - Click and drag on lower right corner to resize window
- click and drag on any empty space to move window - Click and drag on any empty space to move window
- double-click/double-tap on lower right corner grip to auto-fit to content - Double-click/double-tap on lower right corner grip to auto-fit to content
- TAB/SHIFT+TAB to cycle through keyboard editable fields - TAB/SHIFT+TAB to cycle through keyboard editable fields
- use mouse wheel to scroll - Use mouse wheel to scroll
- use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true) - Use CTRL+mouse wheel to zoom window contents (if io.FontAllowScaling is true)
- CTRL+Click on a slider or drag box to input value as text - CTRL+Click on a slider or drag box to input value as text
- text editor: - Text editor:
- Hold SHIFT or use mouse to select text. - Hold SHIFT or use mouse to select text.
- CTRL+Left/Right to word jump - CTRL+Left/Right to word jump
- CTRL+Shift+Left/Right to select words - CTRL+Shift+Left/Right to select words
@ -74,76 +75,80 @@
- CTRL+Z,CTRL+Y to undo/redo - CTRL+Z,CTRL+Y to undo/redo
- ESCAPE to revert text to its original value - ESCAPE to revert text to its original value
- You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)
- Controls are automatically adjusted for OSX to match standard OSX text editing operations.
PROGRAMMER GUIDE PROGRAMMER GUIDE
================ ================
- read the FAQ below this section! READ FIRST
- your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs.
- call and read ImGui::ShowTestWindow() for demo code demonstrating most features.
- see examples/ folder for standalone sample applications. Prefer reading examples/opengl2_example/ first as it is the simplest.
you may be able to grab and copy a ready made imgui_impl_*** file from the examples/.
- customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme).
- getting started: - Read the FAQ below this section!
- init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'. - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs.
- init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features.
- every frame: - Customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme).
1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input'
2/ call ImGui::NewFrame() as early as you can!
3/ use any ImGui function you want between NewFrame() and Render()
4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure.
(if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.)
- all rendering information are stored into command-lists until ImGui::Render() is called.
- ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide.
- effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application.
- refer to the examples applications in the examples/ folder for instruction on how to setup your code.
- a typical application skeleton may be:
// Application init GETTING STARTED WITH INTEGRATING IMGUI IN YOUR CODE/ENGINE
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize.x = 1920.0f;
io.DisplaySize.y = 1280.0f;
io.IniFilename = "imgui.ini";
io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data.
// TODO: Fill others settings of the io structure
// Load texture atlas - See examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first as it is the simplest.
// There is a default font so you don't need to care about choosing a font yet You may be able to grab and copy a ready made imgui_impl_*** file from the examples/.
unsigned char* pixels; - Init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'.
int width, height; - Init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory.
io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); - Every frame:
// TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input'
// TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' 2/ call ImGui::NewFrame() as early as you can!
3/ use any ImGui function you want between NewFrame() and Render()
4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure.
(if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.)
- All rendering information are stored into command-lists until ImGui::Render() is called.
- ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide.
- Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application.
- Refer to the examples applications in the examples/ folder for instruction on how to setup your code.
- A typical application skeleton may be:
// Application main loop // Application init
while (true) ImGuiIO& io = ImGui::GetIO();
{ io.DisplaySize.x = 1920.0f;
// 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.) io.DisplaySize.y = 1280.0f;
// TODO: fill all fields of IO structure and call NewFrame io.IniFilename = "imgui.ini";
ImGuiIO& io = ImGui::GetIO(); io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data.
io.DeltaTime = 1.0f/60.0f; // TODO: Fill others settings of the io structure
io.MousePos = mouse_pos;
io.MouseDown[0] = mouse_button_0;
io.MouseDown[1] = mouse_button_1;
io.KeysDown[i] = ...
// 2) call NewFrame(), after this point you can use ImGui::* functions anytime // Load texture atlas (there is a default font so you don't need to care about choosing a font yet)
ImGui::NewFrame(); unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height);
// TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system
// TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID'
// 3) most of your application code here // Application main loop
MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); while (true)
MyGameRender(); // may use any ImGui functions {
// 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.)
// TODO: fill all fields of IO structure and call NewFrame
ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = 1.0f/60.0f;
io.MousePos = mouse_pos;
io.MouseDown[0] = mouse_button_0;
io.MouseDown[1] = mouse_button_1;
io.KeysDown[i] = ...
// 4) render & swap video buffers // 2) call NewFrame(), after this point you can use ImGui::* functions anytime
ImGui::Render(); ImGui::NewFrame();
SwapBuffers();
} // 3) most of your application code here
MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End();
MyGameRender(); // may use any ImGui functions
// 4) render & swap video buffers
ImGui::Render();
SwapBuffers();
}
- When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated.
They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide
mouse inputs from the rest of your application. Read the FAQ below for more information about those flags.
- When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated.
They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide
mouse inputs from the rest of your application. Read the FAQ below for more information about those flags.
API BREAKING CHANGES API BREAKING CHANGES
@ -272,7 +277,7 @@
Q: How can I help? 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! 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. - Become a Patron/donate! Convince your company to become a Patron or provide serious funding for development time! See http://www.patreon.com/imgui
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:
@ -493,9 +498,9 @@
- 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.
- window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd.
- 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 after Begin() if we haven't appended items yet
- splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - 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. (#395)
- 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)
- main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them.
@ -577,13 +582,14 @@
- textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#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
- stb: add defines to disable stb implementations
- style: add window shadows. - 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.
- style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle
- 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: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance
@ -596,6 +602,7 @@
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
- filters: set a current filter that tree node can automatically query to hide themselves - filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wildcards (with implicit leading/trailing *), regexps - filters: handle wildcards (with implicit leading/trailing *), regexps
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- 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. (#323) - keyboard: full keyboard navigation and focus. (#323)
@ -5336,7 +5343,7 @@ float ImGui::GetScrollY()
float ImGui::GetScrollMaxX() float ImGui::GetScrollMaxX()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x) + 50); return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x));
} }
float ImGui::GetScrollMaxY() float ImGui::GetScrollMaxY()
@ -6479,6 +6486,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
} }
// Create text input in place of a slider (when CTRL+Clicking on slider) // Create text input in place of a slider (when CTRL+Clicking on slider)
// FIXME: Logic is messy and confusing.
bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -6492,9 +6500,8 @@ 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 text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll);
if (g.ScalarAsInputTextId == 0) if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget
{ {
// First frame
IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible)
g.ScalarAsInputTextId = g.ActiveId; g.ScalarAsInputTextId = g.ActiveId;
SetHoveredID(id); SetHoveredID(id);
@ -10410,6 +10417,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
ImGui::Text("ActiveIdWindow: '%s", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
ImGui::TreePop(); ImGui::TreePop();
} }
} }