Merge branch 'master' into 2016-02-colorpicker

This commit is contained in:
ocornut 2016-12-23 12:15:58 +01:00
commit a60b2cc645
7 changed files with 123 additions and 72 deletions

View File

@ -43,6 +43,40 @@ 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.
- [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)
Bindings
--------
_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API. People who create language bindings sometimes haven't used the C++ API themselves. ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, always check the original C++ version first!_
Languages:
- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui
- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET
- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs
- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui
- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui
- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui
- LUA: https://github.com/patrickriordan/imgui_lua_bindings
Frameworks:
- Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples
- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301
- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336
- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801
- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281
- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421
- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui
- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI
- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI
- LÖVE backend for dear imgui https://github.com/slages/love-imgui
- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src
- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui
- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml
- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends
- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551
- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example
For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/).
Please contact me with the Issues tracker or Twitter to fix/update this list.
Gallery
-------

View File

@ -94,6 +94,15 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup viewport
D3DVIEWPORT9 vp;
vp.X = vp.Y = 0;
vp.Width = (DWORD)io.DisplaySize.x;
vp.Height = (DWORD)io.DisplaySize.y;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
g_pd3dDevice->SetViewport(&vp);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader(NULL);

View File

@ -29,11 +29,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -lglfw3
#LIBS += -L/usr/local/lib -lglfw3
LIBS += -L/usr/local/lib -lglfw
CXXFLAGS = -I../../ -I/usr/local/include
CXXFLAGS += -Wall -Wformat
# CXXFLAGS += -D__APPLE__
CFLAGS = $(CXXFLAGS)
endif

View File

@ -31,12 +31,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X"
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -lglfw3
#LIBS += -L/usr/local/lib -lglfw
#LIBS += -L/usr/local/lib -lglfw3
LIBS += -L/usr/local/lib -lglfw
CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include
CXXFLAGS += -Wall -Wformat
# CXXFLAGS += -D__APPLE__
CFLAGS = $(CXXFLAGS)
endif

107
imgui.cpp
View File

@ -5,6 +5,7 @@
// Newcomers, read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui
// Releases change-log at https://github.com/ocornut/imgui/releases
// Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/772
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
// This library is free but I need your support to sustain development and maintenance.
// If you work for a company, please consider financial support, e.g: https://www.patreon.com/imgui
@ -282,7 +283,6 @@
Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. If you have a problem with a function, search for its name
in the code, there will likely be a comment about it. Please report any issue to the GitHub page!
Q: What is ImTextureID and how do I display an image?
A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function.
ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry!
@ -466,7 +466,7 @@
ISSUES & TODO-LIST
==================
Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues
The list below consist mostly of notes of things to do before they are requested/discussed by users (at that point it usually happens on the github)
The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point it usually moves to the github)
- doc: add a proper documentation+regression testing system (#435)
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
@ -686,9 +686,9 @@ static void AddWindowToSortedBuffer(ImVector<ImGuiWindow*>& out_sort
static ImGuiIniData* FindWindowSettings(const char* name);
static ImGuiIniData* AddWindowSettings(const char* name);
static void LoadSettings();
static void SaveSettings();
static void MarkSettingsDirty();
static void LoadIniSettingsFromDisk(const char* ini_filename);
static void SaveIniSettingsToDisk(const char* ini_filename);
static void MarkIniSettingsDirty();
static void PushColumnClipRect(int column_index = -1);
static ImRect GetVisibleRect();
@ -1297,7 +1297,7 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float&
FILE* ImFileOpen(const char* filename, const char* mode)
{
#ifdef _MSC_VER
#if defined(_WIN32) && !defined(__CYGWIN__)
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can)
const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1;
const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
@ -2137,7 +2137,7 @@ void ImGui::NewFrame()
IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer();
IM_ASSERT(g.Settings.empty());
LoadSettings();
LoadIniSettingsFromDisk(g.IO.IniFilename);
g.Initialized = true;
}
@ -2222,8 +2222,8 @@ void ImGui::NewFrame()
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove))
{
g.MovedWindow->PosFloat += g.IO.MouseDelta;
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f))
MarkIniSettingsDirty();
}
FocusWindow(g.MovedWindow);
}
@ -2245,7 +2245,7 @@ void ImGui::NewFrame()
{
g.SettingsDirtyTimer -= g.IO.DeltaTime;
if (g.SettingsDirtyTimer <= 0.0f)
SaveSettings();
SaveIniSettingsToDisk(g.IO.IniFilename);
}
// Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow
@ -2372,7 +2372,7 @@ void ImGui::Shutdown()
if (!g.Initialized)
return;
SaveSettings();
SaveIniSettingsToDisk(g.IO.IniFilename);
for (int i = 0; i < g.Windows.Size; i++)
{
@ -2452,15 +2452,14 @@ static ImGuiIniData* AddWindowSettings(const char* name)
// Zero-tolerance, poor-man .ini parsing
// FIXME: Write something less rubbish
static void LoadSettings()
static void LoadIniSettingsFromDisk(const char* ini_filename)
{
ImGuiContext& g = *GImGui;
const char* filename = g.IO.IniFilename;
if (!filename)
if (!ini_filename)
return;
int file_size;
char* file_data = (char*)ImLoadFileToMemory(filename, "rb", &file_size, 1);
char* file_data = (char*)ImLoadFileToMemory(ini_filename, "rb", &file_size, 1);
if (!file_data)
return;
@ -2498,11 +2497,11 @@ static void LoadSettings()
ImGui::MemFree(file_data);
}
static void SaveSettings()
static void SaveIniSettingsToDisk(const char* ini_filename)
{
ImGuiContext& g = *GImGui;
const char* filename = g.IO.IniFilename;
if (!filename)
g.SettingsDirtyTimer = 0.0f;
if (!ini_filename)
return;
// Gather data from windows that were active during this session
@ -2519,7 +2518,7 @@ static void SaveSettings()
// Write .ini file
// If a window wasn't opened in this session we preserve its settings
FILE* f = ImFileOpen(filename, "wt");
FILE* f = ImFileOpen(ini_filename, "wt");
if (!f)
return;
for (int i = 0; i != g.Settings.Size; i++)
@ -2540,7 +2539,7 @@ static void SaveSettings()
fclose(f);
}
static void MarkSettingsDirty()
static void MarkIniSettingsDirty()
{
ImGuiContext& g = *GImGui;
if (g.SettingsDirtyTimer <= 0.0f)
@ -4012,7 +4011,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
{
window->Collapsed = !window->Collapsed;
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
MarkIniSettingsDirty();
FocusWindow(window);
}
}
@ -4087,7 +4086,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (window->AutoFitFramesY > 0)
window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
MarkIniSettingsDirty();
}
}
@ -4216,7 +4215,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// Manual auto-fit when double-clicking
ApplySizeFullWithConstraint(window, size_auto_fit);
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
MarkIniSettingsDirty();
SetActiveID(0);
}
else if (held)
@ -4224,7 +4223,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos);
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
MarkSettingsDirty();
MarkIniSettingsDirty();
}
window->Size = window->SizeFull;
@ -6447,6 +6446,31 @@ float ImGui::RoundScalar(float value, int decimal_precision)
return negative ? -value : value;
}
static inline float SliderBehaviorCalcRatioFromValue(float v, float v_min, float v_max, float power, float linear_zero_pos)
{
if (v_min == v_max)
return 0.0f;
const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f);
const float v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min);
if (is_non_linear)
{
if (v_clamped < 0.0f)
{
const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min);
return (1.0f - powf(f, 1.0f/power)) * linear_zero_pos;
}
else
{
const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min));
return linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos);
}
}
// Linear slider
return (v_clamped - v_min) / (v_max - v_min);
}
bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags)
{
ImGuiContext& g = *GImGui;
@ -6456,7 +6480,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
// Draw frame
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f;
const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f);
const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
const float grab_padding = 2.0f;
@ -6465,7 +6489,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
if (decimal_precision > 0)
grab_sz = ImMin(style.GrabMinSize, slider_sz);
else
grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit
grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit
const float slider_usable_sz = slider_sz - grab_sz;
const float slider_usable_pos_min = (is_horizontal ? frame_bb.Min.x : frame_bb.Min.y) + grab_padding + grab_sz*0.5f;
const float slider_usable_pos_max = (is_horizontal ? frame_bb.Max.x : frame_bb.Max.y) - grab_padding - grab_sz*0.5f;
@ -6492,7 +6516,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
if (g.IO.MouseDown[0])
{
const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
float clicked_t = ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f);
float clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f;
if (!is_horizontal)
clicked_t = 1.0f - clicked_t;
@ -6527,7 +6551,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
// Round past decimal precision
new_value = RoundScalar(new_value, decimal_precision);
if (*v != new_value && (v_min != v_max))
if (*v != new_value)
{
*v = new_value;
value_changed = true;
@ -6540,26 +6564,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
}
// Calculate slider grab positioning
float v_clamped = (v_min < v_max) ? ImClamp(*v, v_min, v_max) : ImClamp(*v, v_max, v_min);
float grab_t;
if (is_non_linear)
{
if (v_clamped < 0.0f)
{
const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min);
grab_t = (1.0f - powf(f, 1.0f/power)) * linear_zero_pos;
}
else
{
const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min));
grab_t = linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos);
}
}
else
{
// Linear slider
grab_t = (v_clamped - v_min) / (v_max - v_min);
}
float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
// Draw
if (!is_horizontal)
@ -8395,7 +8400,7 @@ bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_fla
static bool Items_ArrayGetter(void* data, int idx, const char** out_text)
{
const char** items = (const char**)data;
const char* const* items = (const char* const*)data;
if (out_text)
*out_text = items[idx];
return true;
@ -8422,7 +8427,7 @@ static bool Items_SingleStringGetter(void* data, int idx, const char** out_text)
}
// Combo box helper allowing to pass an array of strings.
bool ImGui::Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items)
bool ImGui::Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items)
{
const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items);
return value_changed;
@ -8699,7 +8704,7 @@ void ImGui::ListBoxFooter()
EndGroup();
}
bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items)
bool ImGui::ListBox(const char* label, int* current_item, const char* const* items, int items_count, int height_items)
{
const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items);
return value_changed;

26
imgui.h
View File

@ -265,7 +265,7 @@ namespace ImGui
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active);
IMGUI_API bool RadioButton(const char* label, int* v, int v_button);
IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1);
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0
IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
@ -340,7 +340,7 @@ namespace ImGui
// Widgets: Selectable / Lists
IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0));
IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards.
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // "
@ -792,29 +792,29 @@ struct ImGuiIO
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
// Functions
IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[]
IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Helper to add new characters into InputCharacters[] from an UTF-8 string
inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Helper to clear the text input buffer
IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[]
IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Add new characters into InputCharacters[] from an UTF-8 string
inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Clear the text input buffer manually
//------------------------------------------------------------------
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
// Output - Retrieve after calling NewFrame()
//------------------------------------------------------------------
bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input)
bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input)
bool WantTextInput; // Some text input widget is active, which will read input characters from the InputCharacters array.
float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames
bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input). Use to hide mouse from the rest of your application
bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input). Use to hide keyboard from the rest of your application
bool WantTextInput; // Some text input widget is active, which will read input characters from the InputCharacters array. Use to activate on screen keyboard if your system needs one
float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames
int MetricsAllocs; // Number of active memory allocations
int MetricsRenderVertices; // Vertices output during last call to Render()
int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3
int MetricsActiveWindows; // Number of visible windows (exclude child windows)
int MetricsActiveWindows; // Number of visible root windows (exclude child windows)
ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative, so a disappearing/reappearing mouse won't have a huge delta for one frame.
//------------------------------------------------------------------
// [Private] ImGui will maintain those fields. Forward compatibility not guaranteed!
//------------------------------------------------------------------
ImVec2 MousePosPrev; // Previous mouse position
ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative to allow mouse enabling/disabling.
ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame())
bool MouseClicked[5]; // Mouse button went from !Down to Down
ImVec2 MouseClickedPos[5]; // Position at time of clicking
float MouseClickedTime[5]; // Time of last click (used to figure out double-click)

View File

@ -1123,7 +1123,8 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetItemsLineHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar);
for (int line = 0; line < lines; line++)
{
// Display random stuff
// Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off
// manipulating the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets yourself. You may also want to use the lower-level ImDrawList API)
int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3);
for (int n = 0; n < num_buttons; n++)
{
@ -1181,6 +1182,8 @@ void ImGui::ShowTestWindow(bool* p_open)
const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" };
static bool toggles[] = { true, false, false, false, false };
// Simple selection popup
// (If you want to show the current selection inside the Button itself, you may want to build a string using the "###" operator to preserve a constant ID with a variable label)
if (ImGui::Button("Select.."))
ImGui::OpenPopup("select");
ImGui::SameLine();
@ -1195,6 +1198,7 @@ void ImGui::ShowTestWindow(bool* p_open)
ImGui::EndPopup();
}
// Showing a menu with toggles
if (ImGui::Button("Toggle.."))
ImGui::OpenPopup("toggle");
if (ImGui::BeginPopup("toggle"))
@ -1229,8 +1233,8 @@ void ImGui::ShowTestWindow(bool* p_open)
}
if (ImGui::Button("Popup Menu.."))
ImGui::OpenPopup("popup from button");
if (ImGui::BeginPopup("popup from button"))
ImGui::OpenPopup("FilePopup");
if (ImGui::BeginPopup("FilePopup"))
{
ShowExampleMenuFile();
ImGui::EndPopup();