Updated ImGui.

This commit is contained in:
Branimir Karadžić 2016-04-27 21:35:15 -07:00
parent ab3ba43756
commit d2d40498eb
5 changed files with 82 additions and 48 deletions

View File

@ -152,6 +152,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.
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer.
- 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
- 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337)
- 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete).
@ -410,13 +411,17 @@
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
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.
Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
A: When loading a font, pass custom Unicode ranges to specify the glyphs to load.
All strings passed need to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application
As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
- tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
- tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
- tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings)
@ -537,7 +542,7 @@
- style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle
- 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: fix AddRemapChar() to work before font has been built.
- 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: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
@ -557,7 +562,6 @@
- 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.
- remote: make a system like RemoteImGui first-class citizen/project (#75)
!- demo: custom render demo pushes a clipping rectangle past parent window bounds. expose ImGui::PushClipRect() from imgui_internal.h?
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- examples: directx9: save/restore device state more thoroughly.
- examples: window minimize, maximize (#583)
@ -2369,23 +2373,11 @@ static void AddWindowToRenderList(ImVector<ImDrawList*>& out_render_list, ImGuiW
}
}
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect)
void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
{
ImGuiWindow* window = GetCurrentWindow();
ImRect cr(clip_rect_min, clip_rect_max);
if (intersect_with_existing_clip_rect) // Clip our argument with the current clip rect
cr.Clip(window->ClipRect);
cr.Max.x = ImMax(cr.Min.x, cr.Max.x);
cr.Max.y = ImMax(cr.Min.y, cr.Max.y);
cr.Min.x = (float)(int)(cr.Min.x + 0.5f); // Round (expecting to round down). Ensure that e.g. (int)(max.x-min.x) in user code produce correct result.
cr.Min.y = (float)(int)(cr.Min.y + 0.5f);
cr.Max.x = (float)(int)(cr.Max.x + 0.5f);
cr.Max.y = (float)(int)(cr.Max.y + 0.5f);
IM_ASSERT(cr.Min.x <= cr.Max.x && cr.Min.y <= cr.Max.y);
window->ClipRect = cr;
window->DrawList->PushClipRect(ImVec4(cr.Min.x, cr.Min.y, cr.Max.x, cr.Max.y));
window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);
window->ClipRect = window->DrawList->_ClipRectStack.back();
}
void ImGui::PopClipRect()
@ -3224,8 +3216,8 @@ static void CloseInactivePopups()
static ImGuiWindow* GetFrontMostModalRootWindow()
{
ImGuiState& g = *GImGui;
if (!g.OpenedPopupStack.empty())
if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.back().Window)
for (int n = g.OpenedPopupStack.Size-1; n >= 0; n--)
if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.Data[n].Window)
if (front_most_popup->Flags & ImGuiWindowFlags_Modal)
return front_most_popup;
return NULL;
@ -8375,7 +8367,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w);
bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f));
if (shortcut_size.x > 0.0f)
{
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
@ -8384,7 +8376,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
}
if (selected)
RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(ImGuiCol_Text));
RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled));
return pressed;
}

View File

@ -368,6 +368,10 @@ namespace ImGui
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed)
// Clipping
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
IMGUI_API void PopClipRect();
// Utilities
IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse?
IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this
@ -1131,7 +1135,7 @@ struct ImDrawList
ImDrawList() { _OwnerName = NULL; Clear(); }
~ImDrawList() { ClearFreeMemory(); }
IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. Note that the values are (x1,y1,x2,y2) and NOT (x1,y1,w,h). This is passed down to your render function but not used for CPU-side clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
IMGUI_API void PushClipRectFullScreen();
IMGUI_API void PopClipRect();
IMGUI_API void PushTextureID(const ImTextureID& texture_id);
@ -1261,7 +1265,7 @@ struct ImFontAtlas
void SetTexID(void* id) { TexID = id; }
// Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list)
// (Those functions could be static but aren't so most users don't have to refer to the ImFontAtlas:: name ever if in their code; just using io.Fonts->)
// NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details.
IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin
IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters
IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
@ -1319,10 +1323,10 @@ struct ImFont
IMGUI_API ~ImFont();
IMGUI_API void Clear();
IMGUI_API void BuildLookupTable();
IMGUI_API const Glyph* FindGlyph(unsigned short c) const;
IMGUI_API const Glyph* FindGlyph(ImWchar c) const;
IMGUI_API void SetFallbackChar(ImWchar c);
float GetCharAdvance(unsigned short c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; }
bool IsLoaded() const { return ContainerAtlas != NULL; }
float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; }
bool IsLoaded() const { return ContainerAtlas != NULL; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
@ -1330,6 +1334,10 @@ struct ImFont
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const;
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
// Private
IMGUI_API void GrowIndex(int new_size);
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
};
//---- Include imgui_user.h at the end of imgui.h

View File

@ -1863,7 +1863,7 @@ static void ShowExampleAppCustomRendering(bool* opened)
points.pop_back();
}
}
draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.)
draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f);
draw_list->PopClipRect();

View File

@ -215,20 +215,33 @@ void ImDrawList::UpdateTextureID()
#undef GetCurrentClipRect
#undef GetCurrentTextureId
// Scissoring. The values in clip_rect are x1, y1, x2, y2. Only apply to rendering! Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
void ImDrawList::PushClipRect(const ImVec4& clip_rect)
// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
{
_ClipRectStack.push_back(clip_rect);
ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
if (intersect_with_current_clip_rect && _ClipRectStack.Size)
{
ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1];
if (cr.x < current.x) cr.x = current.x;
if (cr.y < current.y) cr.y = current.y;
if (cr.z > current.z) cr.z = current.z;
if (cr.w > current.w) cr.w = current.w;
}
cr.z = ImMax(cr.x, cr.z);
cr.w = ImMax(cr.y, cr.w);
cr.x = (float)(int)(cr.x + 0.5f); // Round (expecting to round down). Ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
cr.y = (float)(int)(cr.y + 0.5f);
cr.z = (float)(int)(cr.z + 0.5f);
cr.w = (float)(int)(cr.w + 0.5f);
_ClipRectStack.push_back(cr);
UpdateClipRect();
}
void ImDrawList::PushClipRectFullScreen()
{
PushClipRect(GNullClipRect);
// FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here?
//ImGuiState& g = *GImGui;
//PushClipRect(GetVisibleRect());
PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w));
//PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here?
}
void ImDrawList::PopClipRect()
@ -1679,14 +1692,8 @@ void ImFont::BuildLookupTable()
IM_ASSERT(Glyphs.Size < 32*1024);
IndexXAdvance.clear();
IndexXAdvance.resize(max_codepoint + 1);
IndexLookup.clear();
IndexLookup.resize(max_codepoint + 1);
for (int i = 0; i < max_codepoint + 1; i++)
{
IndexXAdvance[i] = -1.0f;
IndexLookup[i] = (short)-1;
}
GrowIndex(max_codepoint + 1);
for (int i = 0; i < Glyphs.Size; i++)
{
int codepoint = (int)Glyphs[i].Codepoint;
@ -1722,6 +1729,36 @@ void ImFont::SetFallbackChar(ImWchar c)
BuildLookupTable();
}
void ImFont::GrowIndex(int new_size)
{
IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size);
int old_size = IndexLookup.Size;
if (new_size <= old_size)
return;
IndexXAdvance.resize(new_size);
IndexLookup.resize(new_size);
for (int i = old_size; i < new_size; i++)
{
IndexXAdvance[i] = -1.0f;
IndexLookup[i] = (short)-1;
}
}
void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
{
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
int index_size = IndexLookup.Size;
if (dst < index_size && IndexLookup.Data[dst] == -1 && !overwrite_dst) // 'dst' already exists
return;
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
return;
GrowIndex(dst + 1);
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : -1;
IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f;
}
const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const
{
if (c < IndexLookup.Size)

View File

@ -707,13 +707,10 @@ namespace ImGui
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
IMGUI_API void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false);
IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool opened, float scale = 1.0f, bool shadow = false);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col);
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true);
IMGUI_API void PopClipRect();
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);