Clarify usage of right-aligned items in Layout>Widgets Width. Tweaks FAQ, added missing syntax coloring.

This commit is contained in:
ocornut 2020-11-20 17:24:18 +01:00
parent d4f08d893e
commit e0cae25c3c
5 changed files with 99 additions and 71 deletions

View File

@ -85,6 +85,7 @@ Other Changes:
- Misc: Made EndFrame() assertion for key modifiers being unchanged during the frame (added in 1.76) more - Misc: Made EndFrame() assertion for key modifiers being unchanged during the frame (added in 1.76) more
lenient, allowing full mid-frame releases. This is to accommodate the use of mid-frame modal native lenient, allowing full mid-frame releases. This is to accommodate the use of mid-frame modal native
windows calls, which leads backends such as GLFW to send key clearing events on focus loss. (#3575) windows calls, which leads backends such as GLFW to send key clearing events on focus loss. (#3575)
- Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width.
- Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...) - Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn] when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]
- Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon] - Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon]

View File

@ -188,14 +188,14 @@ Unique ID are used internally to track active widgets and occasionally associate
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element. Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
- Unique ID are often derived from a string label and at minimum scoped within their host window: - Unique ID are often derived from a string label and at minimum scoped within their host window:
```c ```cpp
Begin("MyWindow"); Begin("MyWindow");
Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK") Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
Button("Cancel"); // Label = "Cancel", ID = hash of ("MyWindow", "Cancel") Button("Cancel"); // Label = "Cancel", ID = hash of ("MyWindow", "Cancel")
End(); End();
``` ```
- Other elements such as tree nodes, etc. also pushes to the ID stack: - Other elements such as tree nodes, etc. also pushes to the ID stack:
```c ```cpp
Begin("MyWindow"); Begin("MyWindow");
if (TreeNode("MyTreeNode")) if (TreeNode("MyTreeNode"))
{ {
@ -205,7 +205,7 @@ if (TreeNode("MyTreeNode"))
End(); End();
``` ```
- Two items labeled "OK" in different windows or different tree locations won't collide: - Two items labeled "OK" in different windows or different tree locations won't collide:
``` ```cpp
Begin("MyFirstWindow"); Begin("MyFirstWindow");
Button("OK"); // Label = "OK", ID = hash of ("MyFirstWindow", "OK") Button("OK"); // Label = "OK", ID = hash of ("MyFirstWindow", "OK")
End(); End();
@ -217,7 +217,7 @@ End();
We used "..." above to signify whatever was already pushed to the ID stack previously: We used "..." above to signify whatever was already pushed to the ID stack previously:
- If you have a same ID twice in the same location, you'll have a conflict: - If you have a same ID twice in the same location, you'll have a conflict:
```c ```cpp
Button("OK"); Button("OK");
Button("OK"); // ID collision! Interacting with either button will trigger the first one. Button("OK"); // ID collision! Interacting with either button will trigger the first one.
``` ```
@ -228,7 +228,7 @@ When passing a label you can optionally specify extra ID information within stri
Use "##" to pass a complement to the ID that won't be visible to the end-user. Use "##" to pass a complement to the ID that won't be visible to the end-user.
This helps solving the simple collision cases when you know e.g. at compilation time which items This helps solving the simple collision cases when you know e.g. at compilation time which items
are going to be created: are going to be created:
```c ```cpp
Begin("MyWindow"); Begin("MyWindow");
Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play") Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play")
Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above
@ -236,15 +236,15 @@ Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo
End(); End();
``` ```
- If you want to completely hide the label, but still need an ID: - If you want to completely hide the label, but still need an ID:
```c ```cpp
Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox! Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox!
``` ```
- Occasionally/rarely you might want change a label while preserving a constant ID. This allows - Occasionally/rarely you might want change a label while preserving a constant ID. This allows
you to animate labels. For example you may want to include varying information in a window title bar, you to animate labels. For example you may want to include varying information in a window title bar,
but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID: but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID:
```c ```cpp
Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID") Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID")
Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same as above, even if the label looks different Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same ID, different label
sprintf(buf, "My game (%f FPS)###MyGame", fps); sprintf(buf, "My game (%f FPS)###MyGame", fps);
Begin(buf); // Variable title, ID = hash of "MyGame" Begin(buf); // Variable title, ID = hash of "MyGame"
@ -256,7 +256,7 @@ creating many UI elements programmatically.
You can push a pointer, a string or an integer value into the ID stack. You can push a pointer, a string or an integer value into the ID stack.
Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack. Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack.
At each level of the stack we store the seed used for items at this level of the ID stack. At each level of the stack we store the seed used for items at this level of the ID stack.
```c ```cpp
Begin("Window"); Begin("Window");
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
@ -281,7 +281,7 @@ for (int i = 0; i < 100; i++)
End(); End();
``` ```
- You can stack multiple prefixes into the ID stack: - You can stack multiple prefixes into the ID stack:
```c ```cpp
Button("Click"); // Label = "Click", ID = hash of (..., "Click") Button("Click"); // Label = "Click", ID = hash of (..., "Click")
PushID("node"); PushID("node");
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click") Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
@ -291,7 +291,7 @@ PushID("node");
PopID(); PopID();
``` ```
- Tree nodes implicitly creates a scope for you by calling PushID(). - Tree nodes implicitly creates a scope for you by calling PushID().
```c ```cpp
Button("Click"); // Label = "Click", ID = hash of (..., "Click") Button("Click"); // Label = "Click", ID = hash of (..., "Click")
if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag) if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag)
{ {
@ -328,22 +328,22 @@ Long explanation:
ImTextureID is nothing more that a void*, aka 4/8 bytes worth of data: just enough to store 1 pointer or 1 integer of your choice. ImTextureID is nothing more that a void*, aka 4/8 bytes worth of data: just enough to store 1 pointer or 1 integer of your choice.
Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function. Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function.
- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using: - In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using:
``` ```cpp
OpenGL: OpenGL:
- ImTextureID = GLuint - ImTextureID = GLuint
- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp - See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp
``` ```
``` ```cpp
DirectX9: DirectX9:
- ImTextureID = LPDIRECT3DTEXTURE9 - ImTextureID = LPDIRECT3DTEXTURE9
- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp - See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp
``` ```
``` ```cpp
DirectX11: DirectX11:
- ImTextureID = ID3D11ShaderResourceView* - ImTextureID = ID3D11ShaderResourceView*
- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp - See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp
``` ```
``` ```cpp
DirectX12: DirectX12:
- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE - ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE
- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp - See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp
@ -429,8 +429,7 @@ provide similar or better string helpers.
### Q: How can I display custom shapes? (using low-level ImDrawList API) ### Q: How can I display custom shapes? (using low-level ImDrawList API)
- You can use the low-level `ImDrawList` api to render shapes within a window. - You can use the low-level `ImDrawList` api to render shapes within a window.
```cpp
```
ImGui::Begin("My shapes"); ImGui::Begin("My shapes");
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
@ -466,9 +465,9 @@ ImGui::End();
### Q: How should I handle DPI in my application? ### Q: How should I handle DPI in my application?
The short answer is: obtain the desired DPI scale, load a suitable font resized with that scale (always round down font size to nearest integer), and scale your Style structure accordingly using `style.ScaleAllSizes()`. The short answer is: obtain the desired DPI scale, load your fonts resized with that scale (always round down fonts size to nearest integer), and scale your Style structure accordingly using `style.ScaleAllSizes()`.
Your application may want to detect DPI change and reload the font and reset style being frames. Your application may want to detect DPI change and reload the fonts and reset style between frames.
Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead. Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
@ -507,7 +506,7 @@ backslash \ within a string literal, you need to write it double backslash "\\":
```cpp ```cpp
io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escaping the M here!) io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escaping the M here!)
io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT (Windows only)
io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT
``` ```
@ -644,7 +643,7 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci
# Q&A: Community # Q&A: Community
### Q: How can I help? ### Q: How can I help?
- Businesses: please reach out to `contact AT dearimgui.org` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding we can hire more people working on this project. - Businesses: please reach out to `contact AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding we can hire more people working on this project.
- Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). - Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md).
- If you are experienced with Dear ImGui and C++, look at the [GitHub Issues](https://github.com/ocornut/imgui/issues), look at the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help! - If you are experienced with Dear ImGui and C++, look at the [GitHub Issues](https://github.com/ocornut/imgui/issues), look at the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help!
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.

View File

@ -75,7 +75,7 @@ ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels); ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
// Select font at runtime // Select font at runtime
ImGui::Text("Hello"); // use the default font (which is the first loaded font) ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2); ImGui::PushFont(font2);
ImGui::Text("Hello with another font"); ImGui::Text("Hello with another font");
ImGui::PopFont(); ImGui::PopFont();
@ -311,39 +311,31 @@ In some situations, you may also use `/` path separator under Windows.
Some fonts files are available in the `misc/fonts/` folder: Some fonts files are available in the `misc/fonts/` folder:
``` **Roboto-Medium.ttf**, by Christian Robetson
Roboto-Medium.ttf <br>Apache License 2.0
Apache License 2.0 <br>https://fonts.google.com/specimen/Roboto
by Christian Robetson
https://fonts.google.com/specimen/Roboto
Cousine-Regular.ttf **Cousine-Regular.ttf**, by Steve Matteson
by Steve Matteson <br>Digitized data copyright (c) 2010 Google Corporation.
Digitized data copyright (c) 2010 Google Corporation. <br>Licensed under the SIL Open Font License, Version 1.1
Licensed under the SIL Open Font License, Version 1.1 <br>https://fonts.google.com/specimen/Cousine
https://fonts.google.com/specimen/Cousine
DroidSans.ttf **DroidSans.ttf**, by Steve Matteson
Copyright (c) Steve Matteson <br>Apache License 2.0
Apache License, version 2.0 <br>https://www.fontsquirrel.com/fonts/droid-sans
https://www.fontsquirrel.com/fonts/droid-sans
ProggyClean.ttf **ProggyClean.ttf**, by Tristan Grimmer
Copyright (c) 2004, 2005 Tristan Grimmer <br>MIT License
MIT License <br>(recommended loading setting: Size = 13.0, GlyphOffset.y = +1)
recommended loading setting: Size = 13.0, GlyphOffset.y = +1 <br>http://www.proggyfonts.net/
http://www.proggyfonts.net/
ProggyTiny.ttf **ProggyTiny.ttf**, by Tristan Grimmer
Copyright (c) 2004, 2005 Tristan Grimmer <br>MIT License
MIT License <br>(recommended loading setting: Size = 10.0, GlyphOffset.y = +1)
recommended loading setting: Size = 10.0, GlyphOffset.y = +1 <br>http://www.proggyfonts.net/
http://www.proggyfonts.net/
Karla-Regular.ttf **Karla-Regular.ttf**, by Jonathan Pinhorn
Copyright (c) 2012, Jonathan Pinhorn <br>SIL OPEN FONT LICENSE Version 1.1
SIL OPEN FONT LICENSE Version 1.1
```
##### [Return to Index](#index) ##### [Return to Index](#index)

View File

@ -3410,7 +3410,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (root_window != NULL && !is_closed_popup) if (root_window != NULL && !is_closed_popup)
{ {
StartMouseMovingWindow(g.HoveredWindow); StartMouseMovingWindow(g.HoveredWindow); //-V595
// Cancel moving if clicked outside of title bar // Cancel moving if clicked outside of title bar
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar)) if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar))

View File

@ -308,8 +308,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
// Most "big" widgets share a common width settings by default. See 'Demo->Layout->Widgets Width' for details. // Most "big" widgets share a common width settings by default. See 'Demo->Layout->Widgets Width' for details.
// e.g. Use 2/3 of the space for widgets and 1/3 for labels (default) // e.g. Use 2/3 of the space for widgets and 1/3 for labels (right align)
//ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); //ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.35f);
// e.g. Leave a fixed amount of width for labels (by passing a negative value), the rest goes to widgets. // e.g. Leave a fixed amount of width for labels (by passing a negative value), the rest goes to widgets.
ImGui::PushItemWidth(ImGui::GetFontSize() * -12); ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
@ -476,6 +476,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ShowDemoWindowMisc(); ShowDemoWindowMisc();
// End of ShowDemoWindow() // End of ShowDemoWindow()
ImGui::PopItemWidth();
ImGui::End(); ImGui::End();
} }
@ -2170,34 +2171,69 @@ static void ShowDemoWindowLayout()
// e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc. // e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc.
static float f = 0.0f; static float f = 0.0f;
static bool show_indented_items = true;
ImGui::Checkbox("Show indented items", &show_indented_items);
ImGui::Text("SetNextItemWidth/PushItemWidth(100)"); ImGui::Text("SetNextItemWidth/PushItemWidth(100)");
ImGui::SameLine(); HelpMarker("Fixed width."); ImGui::SameLine(); HelpMarker("Fixed width.");
ImGui::SetNextItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("float##1", &f); ImGui::DragFloat("float##1b", &f);
if (show_indented_items)
ImGui::Text("SetNextItemWidth/PushItemWidth(GetWindowWidth() * 0.5f)"); {
ImGui::SameLine(); HelpMarker("Half of window width."); ImGui::Indent();
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() * 0.5f); ImGui::DragFloat("float (indented)##1b", &f);
ImGui::DragFloat("float##2", &f); ImGui::Unindent();
}
ImGui::Text("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)"); ImGui::PopItemWidth();
ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)");
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.5f);
ImGui::DragFloat("float##3", &f);
ImGui::Text("SetNextItemWidth/PushItemWidth(-100)"); ImGui::Text("SetNextItemWidth/PushItemWidth(-100)");
ImGui::SameLine(); HelpMarker("Align to right edge minus 100"); ImGui::SameLine(); HelpMarker("Align to right edge minus 100");
ImGui::SetNextItemWidth(-100); ImGui::PushItemWidth(-100);
ImGui::DragFloat("float##4", &f); ImGui::DragFloat("float##2a", &f);
if (show_indented_items)
{
ImGui::Indent();
ImGui::DragFloat("float (indented)##2b", &f);
ImGui::Unindent();
}
ImGui::PopItemWidth();
ImGui::Text("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)");
ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)");
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.5f);
ImGui::DragFloat("float##3a", &f);
if (show_indented_items)
{
ImGui::Indent();
ImGui::DragFloat("float (indented)##3b", &f);
ImGui::Unindent();
}
ImGui::PopItemWidth();
ImGui::Text("SetNextItemWidth/PushItemWidth(-GetContentRegionAvail().x * 0.5f)");
ImGui::SameLine(); HelpMarker("Align to right edge minus half");
ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f);
ImGui::DragFloat("float##4a", &f);
if (show_indented_items)
{
ImGui::Indent();
ImGui::DragFloat("float (indented)##4b", &f);
ImGui::Unindent();
}
ImGui::PopItemWidth();
// Demonstrate using PushItemWidth to surround three items. // Demonstrate using PushItemWidth to surround three items.
// Calling SetNextItemWidth() before each of them would have the same effect. // Calling SetNextItemWidth() before each of them would have the same effect.
ImGui::Text("SetNextItemWidth/PushItemWidth(-1)"); ImGui::Text("SetNextItemWidth/PushItemWidth(-FLT_MIN)");
ImGui::SameLine(); HelpMarker("Align to right edge"); ImGui::SameLine(); HelpMarker("Align to right edge");
ImGui::PushItemWidth(-1); ImGui::PushItemWidth(-FLT_MIN);
ImGui::DragFloat("##float5a", &f); ImGui::DragFloat("##float5a", &f);
ImGui::DragFloat("##float5b", &f); if (show_indented_items)
ImGui::DragFloat("##float5c", &f); {
ImGui::Indent();
ImGui::DragFloat("float (indented)##5b", &f);
ImGui::Unindent();
}
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::TreePop(); ImGui::TreePop();