Updated FAQ

This commit is contained in:
ocornut 2015-03-21 23:14:21 +00:00
parent 072c57b0ca
commit 99314dad73

View File

@ -11,7 +11,12 @@
- END-USER GUIDE - END-USER GUIDE
- 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) & 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 - ISSUES & TODO-LIST
- CODE - CODE
- SAMPLE CODE - SAMPLE CODE
@ -172,24 +177,29 @@
- 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes - 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: Q: Can I have multiple widgets with the same label?
A: Yes. A primer on the use of labels/IDs in ImGui..
- in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) - Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget).
A primer on the meaning and use of IDs in ImGui:
- 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. 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("OK"); // Label = "OK", ID = hash of "OK"
Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" 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 so no conflict can happen if you have two buttons called "OK" in two different Windows. - 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:
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. - 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: 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##0"); // Label = "Play", ID = hash of "Play##0"
Button("Play##1"); // Label = "Play", ID = hash of "Play##1" (different from above) 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("Hello###ID"; // Label = "Hello", ID = hash of "ID"
Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) 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" 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"
for (int i = 0; i < 100; i++)
{
PushID(i);
Button("Click"); // Label = "Click", ID = hash of "node" + i + "label"
PopID();
}
PopID();
PushID(my_ptr); PushID(my_ptr);
Button("Click"); // Label = "Click", ID = hash of ptr + "Click" Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click"
PopID();
PopID(); 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. - tree nodes implicitly creates a scope for you by calling PushID().
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. Button("Click"); // Label = "Click", ID = hash of "Click"
if (TreeNode("node"))
{
Button("Click"); // Label = "Click", ID = hash of "node" + "Click"
TreePop();
}
- 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. 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 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! 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->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() 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* font0 = io.Fonts->AddFontDefault();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
@ -240,7 +283,9 @@
// the first loaded font gets used by default // the first loaded font gets used by default
// use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime // 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->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()