Merge remote-tracking branch 'origin' into 2016-02-colorpicker

This commit is contained in:
omar 2017-08-07 22:34:30 +08:00
commit 1c991b525a
4 changed files with 77 additions and 49 deletions

View File

@ -44,8 +44,8 @@ ImGui allows you create elaborate tools as well as very short-lived ones. On the
Binaries/Demo Binaries/Demo
------------- -------------
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here. You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB) - [imgui-demo-binaries-20170723.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20170723.zip) (Windows binaries, ImGui 1.51+ 2017/07/23, 5 executables, 808 KB)
Bindings Bindings
-------- --------

View File

@ -18,8 +18,9 @@
io.Fonts->AddFontDefault(); io.Fonts->AddFontDefault();
ImFontConfig config; ImFontConfig config;
config.MergeMode = true; config.MergeMode = true;
const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges);
// Usage, e.g. // Usage, e.g.
ImGui::Text("%s Search", ICON_FA_SEARCH); ImGui::Text("%s Search", ICON_FA_SEARCH);
@ -153,6 +154,9 @@
https://github.com/SamBrishes/kenney-icon-font https://github.com/SamBrishes/kenney-icon-font
https://design.google.com/icons/ https://design.google.com/icons/
IcoMoon - Custom Icon font builder
https://icomoon.io/app
Typefaces for source code beautification Typefaces for source code beautification
https://github.com/chrissimpkins/codeface https://github.com/chrissimpkins/codeface

View File

@ -141,8 +141,9 @@
SwapBuffers(); SwapBuffers();
} }
- You can read back 'io.WantCaptureMouse', 'io.WantCaptureKeybord' etc. flags from the IO structure to tell how ImGui intends to use your - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated.
inputs and to know if you should share them or hide them from the rest of your application. Read the FAQ below for more information. 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
@ -400,11 +401,13 @@
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!
Q: How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? Q: How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application?
A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame, but either should be fine. A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure.
When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application.
When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console without a keyboard).
ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is also generally ok,
(Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. as the bool toggles fairly rarely and you don't generally expect to interact with either ImGui or your application during the same frame when that transition occurs.
ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered.
(Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantCaptureKeyboard=false'.
Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.)
Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13)
@ -3609,7 +3612,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
} }
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
char name[20]; char name[20];
if (flags & ImGuiWindowFlags_ChildMenu) if (flags & ImGuiWindowFlags_ChildMenu)
@ -4262,12 +4265,15 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (window->ScrollTarget.y < FLT_MAX) if (window->ScrollTarget.y < FLT_MAX)
{ {
float center_ratio = window->ScrollTargetCenterRatio.y; float center_ratio = window->ScrollTargetCenterRatio.y;
window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * window->SizeFull.y); window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * (window->SizeFull.y - window->ScrollbarSizes.y));
window->ScrollTarget.y = FLT_MAX; window->ScrollTarget.y = FLT_MAX;
} }
window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f));
if (!window->Collapsed && !window->SkipItems) if (!window->Collapsed && !window->SkipItems)
window->Scroll = ImMin(window->Scroll, ImMax(ImVec2(0.0f, 0.0f), window->SizeContents - window->SizeFull + window->ScrollbarSizes)); {
window->Scroll.x = ImMin(window->Scroll.x, GetScrollMaxX());
window->Scroll.y = ImMin(window->Scroll.y, GetScrollMaxY());
}
// Modal window darkens what is behind them // Modal window darkens what is behind them
if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow())
@ -4321,6 +4327,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// Scrollbars // Scrollbars
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
@ -4568,10 +4576,10 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal)
// V denote the main axis of the scrollbar // V denote the main axis of the scrollbar
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y;
float win_size_avail_v = (horizontal ? window->Size.x : window->Size.y) - other_scrollbar_size_w; float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w;
float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y;
// The grabable box size generally represent the amount visible (vs the total scrollable amount) // The grabbable box size generally represent the amount visible (vs the total scrollable amount)
// But we maintain a minimum size in pixel to allow for the user to still aim inside. // But we maintain a minimum size in pixel to allow for the user to still aim inside.
const float grab_h_pixels = ImMin(ImMax(scrollbar_size_v * ImSaturate(win_size_avail_v / ImMax(win_size_contents_v, win_size_avail_v)), style.GrabMinSize), scrollbar_size_v); const float grab_h_pixels = ImMin(ImMax(scrollbar_size_v * ImSaturate(win_size_avail_v / ImMax(win_size_contents_v, win_size_avail_v)), style.GrabMinSize), scrollbar_size_v);
const float grab_h_norm = grab_h_pixels / scrollbar_size_v; const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
@ -5328,13 +5336,13 @@ float ImGui::GetScrollY()
float ImGui::GetScrollMaxX() float ImGui::GetScrollMaxX()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
return window->SizeContents.x - window->SizeFull.x - window->ScrollbarSizes.x; return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x) + 50);
} }
float ImGui::GetScrollMaxY() float ImGui::GetScrollMaxY()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
return window->SizeContents.y - window->SizeFull.y - window->ScrollbarSizes.y; return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
} }
void ImGui::SetScrollX(float scroll_x) void ImGui::SetScrollX(float scroll_x)
@ -5366,8 +5374,9 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio)
void ImGui::SetScrollHere(float center_y_ratio) void ImGui::SetScrollHere(float center_y_ratio)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
float target_y = window->DC.CursorPosPrevLine.y + (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space
SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio); target_y += (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
SetScrollFromPosY(target_y, center_y_ratio);
} }
void ImGui::SetKeyboardFocusHere(int offset) void ImGui::SetKeyboardFocusHere(int offset)
@ -6434,16 +6443,16 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
scalar_format = "%d"; scalar_format = "%d";
int* v = (int*)data_ptr; int* v = (int*)data_ptr;
const int old_v = *v; const int old_v = *v;
int arg0 = *v; int arg0i = *v;
if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1)
return false; return false;
// Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision
float arg1 = 0.0f; float arg1f = 0.0f;
if (op == '+') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 + arg1); } // Add (use "+-" to subtract) if (op == '+') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); } // Add (use "+-" to subtract)
else if (op == '*') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 * arg1); } // Multiply else if (op == '*') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); } // Multiply
else if (op == '/') { if (sscanf(buf, "%f", &arg1) == 1 && arg1 != 0.0f) *v = (int)(arg0 / arg1); }// Divide else if (op == '/') { if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); }// Divide
else { if (sscanf(buf, scalar_format, &arg0) == 1) *v = arg0; } // Assign constant else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign constant (read as integer so big values are not lossy)
return (old_v != *v); return (old_v != *v);
} }
else if (data_type == ImGuiDataType_Float) else if (data_type == ImGuiDataType_Float)
@ -6452,17 +6461,17 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
scalar_format = "%f"; scalar_format = "%f";
float* v = (float*)data_ptr; float* v = (float*)data_ptr;
const float old_v = *v; const float old_v = *v;
float arg0 = *v; float arg0f = *v;
if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1)
return false; return false;
float arg1 = 0.0f; float arg1f = 0.0f;
if (sscanf(buf, scalar_format, &arg1) < 1) if (sscanf(buf, scalar_format, &arg1f) < 1)
return false; return false;
if (op == '+') { *v = arg0 + arg1; } // Add (use "+-" to subtract) if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract)
else if (op == '*') { *v = arg0 * arg1; } // Multiply else if (op == '*') { *v = arg0f * arg1f; } // Multiply
else if (op == '/') { if (arg1 != 0.0f) *v = arg0 / arg1; } // Divide else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide
else { *v = arg1; } // Assign constant else { *v = arg1f; } // Assign constant
return (old_v != *v); return (old_v != *v);
} }
@ -9943,7 +9952,7 @@ float ImGui::GetColumnOffset(int column_index)
IM_ASSERT(column_index < window->DC.ColumnsData.Size); IM_ASSERT(column_index < window->DC.ColumnsData.Size);
const float t = window->DC.ColumnsData[column_index].OffsetNorm; const float t = window->DC.ColumnsData[column_index].OffsetNorm;
const float x_offset = window->DC.ColumnsMinX + t * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); const float x_offset = ImLerp(window->DC.ColumnsMinX, window->DC.ColumnsMaxX, t);
return (float)(int)x_offset; return (float)(int)x_offset;
} }
@ -10046,7 +10055,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
window->DC.ColumnsShowBorders = border; window->DC.ColumnsShowBorders = border;
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x;
window->DC.ColumnsMinX = window->DC.IndentX; // Lock our horizontal range window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range
window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x;
window->DC.ColumnsStartPosY = window->DC.CursorPos.y; window->DC.ColumnsStartPosY = window->DC.CursorPos.y;
window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y;
@ -10192,7 +10201,10 @@ static const char* GetClipboardTextFn_DefaultImpl(void*)
return NULL; return NULL;
HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT);
if (wbuf_handle == NULL) if (wbuf_handle == NULL)
{
CloseClipboard();
return NULL; return NULL;
}
if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle))
{ {
int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1;

View File

@ -6,14 +6,18 @@
// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). // Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow().
// During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! // During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu!
// Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library. // Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library.
// Note that you can #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h for the same effect. // Note that you can #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h for the same effect.
// If you want to link core ImGui in your public builds but not those test windows, #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h and those functions will be empty. // If you want to link core ImGui in your public builds but not those test windows, #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h and those functions will be empty.
// For any other case, if you have ImGui available you probably want this to be available for reference and execution. // For any other case, if you have ImGui available you probably want this to be available for reference and execution.
// Thank you, // Thank you,
// -Your beloved friend, imgui_demo.cpp (that you won't delete) // -Your beloved friend, imgui_demo.cpp (that you won't delete)
// Message to beginner C/C++ programmer about the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions.
// We do this as a way to gather code and data in the same place, make the demo code faster to read, faster to write, and smaller. A static variable persist across calls,
// so it is essentially like a global variable but declared inside the scope of the function.
// It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads.
// This may be a pattern you want to use in your code (simple is beautiful!), but most of the real data you would be editing is likely to be stored outside your function.
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#endif #endif
@ -538,9 +542,13 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::TreePop(); ImGui::TreePop();
} }
static bool a=false; static bool my_toggle = false;
if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; } if (ImGui::Button("Button"))
if (a) {
printf("Clicked\n");
my_toggle = !my_toggle;
}
if (my_toggle)
{ {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("Thanks for clicking me!"); ImGui::Text("Thanks for clicking me!");
@ -1199,9 +1207,9 @@ void ImGui::ShowTestWindow(bool* p_open)
static int track_line = 50, scroll_to_px = 200; static int track_line = 50, scroll_to_px = 200;
ImGui::Checkbox("Track", &track); ImGui::Checkbox("Track", &track);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line %.0f"); ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %.0f");
bool scroll_to = ImGui::Button("Scroll To"); bool scroll_to = ImGui::Button("Scroll To Pos");
ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px"); ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %.0f px");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
if (scroll_to) track = false; if (scroll_to) track = false;
@ -1225,7 +1233,9 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::Text("Line %d", line); ImGui::Text("Line %d", line);
} }
} }
float scroll_y = ImGui::GetScrollY(), scroll_max_y = ImGui::GetScrollMaxY();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y);
ImGui::EndGroup(); ImGui::EndGroup();
} }
ImGui::TreePop(); ImGui::TreePop();
@ -1260,12 +1270,14 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::PopID(); ImGui::PopID();
} }
} }
float scroll_x = ImGui::GetScrollX(), scroll_max_x = ImGui::GetScrollMaxX();
ImGui::EndChild(); ImGui::EndChild();
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
float scroll_x_delta = 0.0f; float scroll_x_delta = 0.0f;
ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine();
ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine();
ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine();
ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x);
if (scroll_x_delta != 0.0f) if (scroll_x_delta != 0.0f)
{ {
ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window) ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window)
@ -2562,10 +2574,10 @@ static void ShowExampleAppLog(bool* p_open)
{ {
static ExampleAppLog log; static ExampleAppLog log;
// Demo fill // Demo: add random items (unless Ctrl is held)
static float last_time = -1.0f; static float last_time = -1.0f;
float time = ImGui::GetTime(); float time = ImGui::GetTime();
if (time - last_time >= 0.3f) if (time - last_time >= 0.20f && !ImGui::GetIO().KeyCtrl)
{ {
const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" }; const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" };
log.AddLog("[%s] Hello, time is %.1f, rand() %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, (int)rand()); log.AddLog("[%s] Hello, time is %.1f, rand() %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, (int)rand());