|
|
|
@ -11,7 +11,12 @@ |
|
|
|
|
- END-USER GUIDE |
|
|
|
|
- PROGRAMMER GUIDE (read me!) |
|
|
|
|
- API BREAKING CHANGES (read me when you update!) |
|
|
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ) & TROUBLESHOOTING (read me!) |
|
|
|
|
- FREQUENTLY ASKED QUESTIONS (FAQ), TIPS |
|
|
|
|
- Can I have multiple widgets with the same label? (Yes) |
|
|
|
|
- Why is my text output blurry? |
|
|
|
|
- How can I load a different font than the default?
|
|
|
|
|
- How can I load multiple fonts? |
|
|
|
|
- How can I display and input Chinese, Japanese, Korean characters? |
|
|
|
|
- ISSUES & TODO-LIST |
|
|
|
|
- CODE |
|
|
|
|
- SAMPLE CODE |
|
|
|
@ -172,24 +177,29 @@ |
|
|
|
|
- 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FREQUENTLY ASKED QUESTIONS (FAQ) & TROUBLESHOOTING |
|
|
|
|
================================================== |
|
|
|
|
FREQUENTLY ASKED QUESTIONS (FAQ), TIPS |
|
|
|
|
====================================== |
|
|
|
|
|
|
|
|
|
If text or lines are blurry when integrating ImGui in your engine: |
|
|
|
|
|
|
|
|
|
- in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) |
|
|
|
|
|
|
|
|
|
A primer on the meaning and use of IDs in ImGui: |
|
|
|
|
Q: Can I have multiple widgets with the same label?
|
|
|
|
|
A: Yes. A primer on the use of labels/IDs in ImGui.. |
|
|
|
|
|
|
|
|
|
- widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). |
|
|
|
|
- Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). |
|
|
|
|
to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer. |
|
|
|
|
|
|
|
|
|
Button("OK"); // Label = "OK", ID = hash of "OK"
|
|
|
|
|
Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel"
|
|
|
|
|
|
|
|
|
|
- element that are not interactive, such as Text() items don't need an ID. |
|
|
|
|
- Elements that are not clickable, such as Text() items don't need an ID. |
|
|
|
|
|
|
|
|
|
- ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows |
|
|
|
|
or in two different locations of a tree. |
|
|
|
|
|
|
|
|
|
- if you have a same ID twice in the same location, you'll have a conflict: |
|
|
|
|
|
|
|
|
|
- ID are uniquely scoped within Windows so no conflict can happen if you have two buttons called "OK" in two different Windows. |
|
|
|
|
Button("OK"); |
|
|
|
|
Button("OK"); // ID collision! Both buttons will be treated as the same.
|
|
|
|
|
|
|
|
|
|
Fear not! this is easy to solve and there are many ways to solve it! |
|
|
|
|
|
|
|
|
|
- when passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. |
|
|
|
|
use "##" to pass a complement to the ID that won't be visible to the end-user: |
|
|
|
@ -197,41 +207,74 @@ |
|
|
|
|
Button("Play##0"); // Label = "Play", ID = hash of "Play##0"
|
|
|
|
|
Button("Play##1"); // Label = "Play", ID = hash of "Play##1" (different from above)
|
|
|
|
|
|
|
|
|
|
use "###" to pass a label that isn't part of ID. You can use that to change labels while preserving a constant ID. |
|
|
|
|
- occasionally (rarely) you might want change a label while preserving a constant ID. This allows you to animate labels. |
|
|
|
|
use "###" to pass a label that isn't part of ID: |
|
|
|
|
|
|
|
|
|
Button("Hello###ID"; // Label = "Hello", ID = hash of "ID"
|
|
|
|
|
Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above)
|
|
|
|
|
|
|
|
|
|
- use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window: |
|
|
|
|
- use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. |
|
|
|
|
this is the most convenient way of distinguish ID if you are iterating and creating many UI elements. |
|
|
|
|
you can push a pointer, a string or an integer value. remember that ID are formed from the addition of everything in the ID stack! |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 100; i++) |
|
|
|
|
{ |
|
|
|
|
PushID(i); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of integer + "label" (unique)
|
|
|
|
|
PopID(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 100; i++) |
|
|
|
|
{ |
|
|
|
|
MyObject* obj = Objects[i]; |
|
|
|
|
PushID(obj); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of pointer + "label" (unique)
|
|
|
|
|
PopID(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 100; i++) |
|
|
|
|
{ |
|
|
|
|
MyObject* obj = Objects[i]; |
|
|
|
|
PushID(obj->Name); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of string + "label" (unique)
|
|
|
|
|
PopID(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- more example showing that you can stack multiple prefixes into the ID stack: |
|
|
|
|
|
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "Click"
|
|
|
|
|
PushID("node"); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "node" + "Click"
|
|
|
|
|
for (int i = 0; i < 100; i++) |
|
|
|
|
PushID(my_ptr); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click"
|
|
|
|
|
PopID(); |
|
|
|
|
PopID(); |
|
|
|
|
|
|
|
|
|
- tree nodes implicitly creates a scope for you by calling PushID(). |
|
|
|
|
|
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "Click"
|
|
|
|
|
if (TreeNode("node")) |
|
|
|
|
{ |
|
|
|
|
PushID(i); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "node" + i + "label"
|
|
|
|
|
PopID(); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of "node" + "Click"
|
|
|
|
|
TreePop(); |
|
|
|
|
} |
|
|
|
|
PopID(); |
|
|
|
|
PushID(my_ptr); |
|
|
|
|
Button("Click"); // Label = "Click", ID = hash of ptr + "Click"
|
|
|
|
|
PopID(); |
|
|
|
|
|
|
|
|
|
so if you have a loop creating multiple items, you can use PushID() / PopID() with the index of each item, or their pointer, etc. |
|
|
|
|
some functions like TreeNode() implicitly creates a scope for you by calling PushID(). |
|
|
|
|
|
|
|
|
|
- when working with trees, ID are used to preserve the opened/closed state of tree nodes. |
|
|
|
|
- when working with trees, ID are used to preserve the opened/closed state of each tree node. |
|
|
|
|
depending on your use cases you may want to use strings, indices or pointers as ID.
|
|
|
|
|
e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. |
|
|
|
|
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! |
|
|
|
|
|
|
|
|
|
If you want to load a different font than the default (ProggyClean.ttf, size 13) |
|
|
|
|
Q: Why is my text output blurry? |
|
|
|
|
A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) |
|
|
|
|
|
|
|
|
|
Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) |
|
|
|
|
A: Use the font atlas to load the TTF file you want: |
|
|
|
|
|
|
|
|
|
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); |
|
|
|
|
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() |
|
|
|
|
|
|
|
|
|
If you want to load multiple fonts, use the font atlas to pack them into a single texture! |
|
|
|
|
Q: How can I load multiple fonts? |
|
|
|
|
A: Use the font atlas to pack them into a single texture: |
|
|
|
|
|
|
|
|
|
ImFont* font0 = io.Fonts->AddFontDefault(); |
|
|
|
|
ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); |
|
|
|
@ -240,7 +283,9 @@ |
|
|
|
|
// the first loaded font gets used by default
|
|
|
|
|
// use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime
|
|
|
|
|
|
|
|
|
|
If you want to display Chinese, Japanese, Korean characters, pass custom Unicode ranges when loading a font: |
|
|
|
|
Q: How can I render and input Chinese, Japanese, Korean characters? |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters
|
|
|
|
|
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() |
|
|
|
|