Updated Imgui and ImguiSFML

master
mitchellhansen 7 years ago
parent 33a8e3af8b
commit dd44955f33

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2018 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -5,7 +5,34 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#pragma once #pragma once
// Add this to your imconfig.h
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Color.hpp>
#define IM_VEC2_CLASS_EXTRA \
template <typename T> \
ImVec2(const sf::Vector2<T>& v) { \
x = static_cast<float>(v.x); \
y = static_cast<float>(v.y); \
} \
\
template <typename T> \
operator sf::Vector2<T>() const { \
return sf::Vector2<T>(x, y); \
}
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const sf::Color & c) \
: ImVec4(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f) { \
} \
operator sf::Color() const { \
return sf::Color( \
static_cast<sf::Uint8>(x * 255.f), \
static_cast<sf::Uint8>(y * 255.f), \
static_cast<sf::Uint8>(z * 255.f), \
static_cast<sf::Uint8>(w * 255.f)); \
}
//---- Define assertion handler. Defaults to calling assert(). //---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) //#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
@ -13,23 +40,27 @@
//#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport ) //#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Include imgui_user.h at the end of imgui.h //---- Include imgui_user.h at the end of imgui.h
//#define IMGUI_INCLUDE_IMGUI_USER_H //#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
//#define IMGUI_DISABLE_TEST_WINDOWS //---- It is very strongly recommended to NOT disable the demo windows. Please read the comment at the top of imgui_demo.cpp to learn why.
//#define IMGUI_DISABLE_DEMO_WINDOWS
//---- Don't define obsolete functions names //---- Don't implement ImFormatString(), ImFormatStringV() so you can reimplement them yourself.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
//---- Pack colors to BGRA instead of RGBA (remove need to post process vertex buffer in back ends) //---- Pack colors to BGRA instead of RGBA (remove need to post process vertex buffer in back ends)
//#define IMGUI_USE_BGRA_PACKED_COLOR //#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Implement STB libraries in a namespace to avoid conflicts //---- Implement STB libraries in a namespace to avoid linkage conflicts
//#define IMGUI_STB_NAMESPACE ImGuiStb //#define IMGUI_STB_NAMESPACE ImGuiStb
//---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. //---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
@ -43,6 +74,9 @@
operator MyVec4() const { return MyVec4(x,y,z,w); } operator MyVec4() const { return MyVec4(x,y,z,w); }
*/ */
//---- Use 32-bit vertex indices (instead of default: 16-bit) to allow meshes with more than 64K vertices
//#define ImDrawIdx unsigned int
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
//---- e.g. create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. //---- e.g. create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers.
/* /*
@ -51,29 +85,4 @@ namespace ImGui
void Value(const char* prefix, const MyMatrix44& v, const char* float_format = NULL); void Value(const char* prefix, const MyMatrix44& v, const char* float_format = NULL);
} }
*/ */
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Color.hpp>
#define IM_VEC2_CLASS_EXTRA \
template <typename T> \
ImVec2(const sf::Vector2<T>& v) { \
x = static_cast<float>(v.x); \
y = static_cast<float>(v.y); \
} \
\
template <typename T> \
operator sf::Vector2<T>() const { \
return sf::Vector2<T>(x, y); \
}
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const sf::Color & c) \
: ImVec4(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f) { \
} \
operator sf::Color() const { \
return sf::Color( \
static_cast<sf::Uint8>(x * 255.f), \
static_cast<sf::Uint8>(y * 255.f), \
static_cast<sf::Uint8>(z * 255.f), \
static_cast<sf::Uint8>(w * 255.f)); \
}

@ -1,419 +0,0 @@
#include "imgui/imgui-SFML.h"
#include "imgui/imgui.h"
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Window.hpp>
#include <cstddef> // offsetof, NULL
#include <cassert>
// Supress warnings caused by converting from uint to void* in pCmd->TextureID
#ifdef __clang__
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
#endif
static bool s_windowHasFocus = true;
static bool s_mousePressed[3] = { false, false, false };
static sf::Texture* s_fontTexture = NULL; // owning pointer to internal font atlas which is used if user doesn't set custom sf::Texture.
namespace
{
ImVec2 getTopLeftAbsolute(const sf::FloatRect& rect);
ImVec2 getDownRightAbsolute(const sf::FloatRect& rect);
inline void RenderDrawLists(ImDrawData* draw_data); // rendering callback function prototype
// Implementation of ImageButton overload
bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding,
const sf::Color& bgColor, const sf::Color& tintColor);
} // anonymous namespace for helper / "private" functions
namespace ImGui
{
namespace SFML
{
void Init(sf::RenderTarget& target, sf::Texture* fontTexture)
{
ImGuiIO& io = ImGui::GetIO();
// init keyboard mapping
io.KeyMap[ImGuiKey_Tab] = sf::Keyboard::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = sf::Keyboard::Left;
io.KeyMap[ImGuiKey_RightArrow] = sf::Keyboard::Right;
io.KeyMap[ImGuiKey_UpArrow] = sf::Keyboard::Up;
io.KeyMap[ImGuiKey_DownArrow] = sf::Keyboard::Down;
io.KeyMap[ImGuiKey_PageUp] = sf::Keyboard::PageUp;
io.KeyMap[ImGuiKey_PageDown] = sf::Keyboard::PageDown;
io.KeyMap[ImGuiKey_Home] = sf::Keyboard::Home;
io.KeyMap[ImGuiKey_End] = sf::Keyboard::End;
io.KeyMap[ImGuiKey_Delete] = sf::Keyboard::Delete;
io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::BackSpace;
io.KeyMap[ImGuiKey_Enter] = sf::Keyboard::Return;
io.KeyMap[ImGuiKey_Escape] = sf::Keyboard::Escape;
io.KeyMap[ImGuiKey_A] = sf::Keyboard::A;
io.KeyMap[ImGuiKey_C] = sf::Keyboard::C;
io.KeyMap[ImGuiKey_V] = sf::Keyboard::V;
io.KeyMap[ImGuiKey_X] = sf::Keyboard::X;
io.KeyMap[ImGuiKey_Y] = sf::Keyboard::Y;
io.KeyMap[ImGuiKey_Z] = sf::Keyboard::Z;
// init rendering
io.DisplaySize = static_cast<sf::Vector2f>(target.getSize());
io.RenderDrawListsFn = RenderDrawLists; // set render callback
if (fontTexture == NULL) {
if (s_fontTexture) { // delete previously created texture
delete s_fontTexture;
}
s_fontTexture = new sf::Texture;
createFontTexture(*s_fontTexture);
setFontTexture(*s_fontTexture);
} else {
setFontTexture(*fontTexture);
}
}
void ProcessEvent(const sf::Event& event)
{
ImGuiIO& io = ImGui::GetIO();
if (s_windowHasFocus) {
switch (event.type)
{
case sf::Event::MouseButtonPressed: // fall-through
case sf::Event::MouseButtonReleased:
{
int button = event.mouseButton.button;
if (event.type == sf::Event::MouseButtonPressed &&
button >= 0 && button < 3) {
s_mousePressed[event.mouseButton.button] = true;
}
}
break;
case sf::Event::MouseWheelMoved:
io.MouseWheel += static_cast<float>(event.mouseWheel.delta);
break;
case sf::Event::KeyPressed: // fall-through
case sf::Event::KeyReleased:
io.KeysDown[event.key.code] = (event.type == sf::Event::KeyPressed);
io.KeyCtrl = event.key.control;
io.KeyShift = event.key.shift;
io.KeyAlt = event.key.alt;
break;
case sf::Event::TextEntered:
if (event.text.unicode > 0 && event.text.unicode < 0x10000) {
io.AddInputCharacter(static_cast<ImWchar>(event.text.unicode));
}
break;
default:
break;
}
}
switch (event.type)
{
case sf::Event::LostFocus:
s_windowHasFocus = false;
break;
case sf::Event::GainedFocus:
s_windowHasFocus = true;
break;
default:
break;
}
}
void Update(sf::RenderWindow& window, sf::Time dt)
{
Update(window, window, dt);
}
void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt)
{
Update(sf::Mouse::getPosition(window), static_cast<sf::Vector2f>(target.getSize()), dt);
window.setMouseCursorVisible(!ImGui::GetIO().MouseDrawCursor); // don't draw mouse cursor if ImGui draws it
}
void Update(const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::Time dt)
{
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = displaySize;
io.DeltaTime = dt.asSeconds();
if (s_windowHasFocus) {
io.MousePos = mousePos;
for (int i = 0; i < 3; ++i) {
io.MouseDown[i] = s_mousePressed[i] || sf::Mouse::isButtonPressed((sf::Mouse::Button)i);
s_mousePressed[i] = false;
}
}
assert(io.Fonts->Fonts.Size > 0); // You forgot to create and set up font atlas (see createFontTexture)
ImGui::NewFrame();
}
void Shutdown()
{
ImGui::GetIO().Fonts->TexID = NULL;
if (s_fontTexture) { // if internal texture was created, we delete it
delete s_fontTexture;
s_fontTexture = NULL;
}
ImGui::Shutdown(); // need to specify namespace here, otherwise ImGui::SFML::Shutdown would be called
}
void createFontTexture(sf::Texture& texture)
{
unsigned char* pixels;
int width, height;
ImGuiIO& io = ImGui::GetIO();
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
texture.create(width, height);
texture.update(pixels);
io.Fonts->ClearInputData();
io.Fonts->ClearTexData();
}
void setFontTexture(sf::Texture& texture)
{
ImGui::GetIO().Fonts->TexID = (void*)texture.getNativeHandle();
if (&texture != s_fontTexture) { // internal texture is not needed anymore
delete s_fontTexture;
s_fontTexture = NULL;
}
}
} // end of namespace SFML
/////////////// Image Overloads
void Image(const sf::Texture& texture,
const sf::Color& tintColor, const sf::Color& borderColor)
{
Image(texture, static_cast<sf::Vector2f>(texture.getSize()), tintColor, borderColor);
}
void Image(const sf::Texture& texture, const sf::Vector2f& size,
const sf::Color& tintColor, const sf::Color& borderColor)
{
ImGui::Image((void*)texture.getNativeHandle(), size, ImVec2(0, 0), ImVec2(1, 1), tintColor, borderColor);
}
void Image(const sf::Texture& texture, const sf::FloatRect& textureRect,
const sf::Color& tintColor, const sf::Color& borderColor)
{
Image(texture, sf::Vector2f(textureRect.width, textureRect.height), textureRect, tintColor, borderColor);
}
void Image(const sf::Texture& texture, const sf::Vector2f& size, const sf::FloatRect& textureRect,
const sf::Color& tintColor, const sf::Color& borderColor)
{
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
ImVec2 uv0(textureRect.left / textureSize.x, textureRect.top / textureSize.y);
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
(textureRect.top + textureRect.height) / textureSize.y);
ImGui::Image((void*)texture.getNativeHandle(), size, uv0, uv1, tintColor, borderColor);
}
void Image(const sf::Sprite& sprite,
const sf::Color& tintColor, const sf::Color& borderColor)
{
sf::FloatRect bounds = sprite.getGlobalBounds();
Image(sprite, sf::Vector2f(bounds.width, bounds.height), tintColor, borderColor);
}
void Image(const sf::Sprite& sprite, const sf::Vector2f& size,
const sf::Color& tintColor, const sf::Color& borderColor)
{
const sf::Texture* texturePtr = sprite.getTexture();
// sprite without texture cannot be drawn
if (!texturePtr) { return; }
Image(*texturePtr, size, tintColor, borderColor);
}
/////////////// Image Button Overloads
bool ImageButton(const sf::Texture& texture,
const int framePadding, const sf::Color& bgColor, const sf::Color& tintColor)
{
return ImageButton(texture, static_cast<sf::Vector2f>(texture.getSize()), framePadding, bgColor, tintColor);
}
bool ImageButton(const sf::Texture& texture, const sf::Vector2f& size,
const int framePadding, const sf::Color& bgColor, const sf::Color& tintColor)
{
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
return ::imageButtonImpl(texture, sf::FloatRect(0.f, 0.f, textureSize.x, textureSize.y), size, framePadding, bgColor, tintColor);
}
bool ImageButton(const sf::Sprite& sprite,
const int framePadding, const sf::Color& bgColor, const sf::Color& tintColor)
{
sf::FloatRect spriteSize = sprite.getGlobalBounds();
return ImageButton(sprite, sf::Vector2f(spriteSize.width, spriteSize.height), framePadding, bgColor, tintColor);
}
bool ImageButton(const sf::Sprite& sprite, const sf::Vector2f& size,
const int framePadding, const sf::Color& bgColor, const sf::Color& tintColor)
{
const sf::Texture* texturePtr = sprite.getTexture();
if (!texturePtr) { return false; }
return ::imageButtonImpl(*texturePtr, static_cast<sf::FloatRect>(sprite.getTextureRect()), size, framePadding, bgColor, tintColor);
}
/////////////// Draw_list Overloads
void DrawLine(const sf::Vector2f& a, const sf::Vector2f& b, const sf::Color& color,
float thickness)
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
sf::Vector2f pos = ImGui::GetCursorScreenPos();
draw_list->AddLine(a + pos, b + pos, ColorConvertFloat4ToU32(color), thickness);
}
void DrawRect(const sf::FloatRect& rect, const sf::Color& color,
float rounding, int rounding_corners, float thickness)
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRect(
getTopLeftAbsolute(rect),
getDownRightAbsolute(rect),
ColorConvertFloat4ToU32(color), rounding, rounding_corners, thickness);
}
void DrawRectFilled(const sf::FloatRect& rect, const sf::Color& color,
float rounding, int rounding_corners)
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRect(
getTopLeftAbsolute(rect),
getDownRightAbsolute(rect),
ColorConvertFloat4ToU32(color), rounding, rounding_corners);
}
} // end of namespace ImGui
namespace
{
ImVec2 getTopLeftAbsolute(const sf::FloatRect & rect)
{
ImVec2 pos = ImGui::GetCursorScreenPos();
return ImVec2(rect.left + pos.x, rect.top + pos.y);
}
ImVec2 getDownRightAbsolute(const sf::FloatRect & rect)
{
ImVec2 pos = ImGui::GetCursorScreenPos();
return ImVec2(rect.left + rect.width + pos.x, rect.top + rect.height + pos.y);
}
// Rendering callback
void RenderDrawLists(ImDrawData* draw_data)
{
if (draw_data->CmdListsCount == 0) {
return;
}
ImGuiIO& io = ImGui::GetIO();
assert(io.Fonts->TexID != NULL); // You forgot to create and set font texture
// scale stuff (needed for proper handling of window resize)
int fb_width = static_cast<int>(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = static_cast<int>(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0) { return; }
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Save OpenGL state
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
for (int n = 0; n < draw_data->CmdListsCount; ++n) {
const ImDrawList* cmd_list = draw_data->CmdLists[n];
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front();
const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, col)));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); ++cmd_i) {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) {
pcmd->UserCallback(cmd_list, pcmd);
} else {
GLuint tex_id = (GLuint)*((unsigned int*)&pcmd->TextureId);
glBindTexture(GL_TEXTURE_2D, tex_id);
glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w),
(int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer);
}
idx_buffer += pcmd->ElemCount;
}
}
// Restore modified state
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
}
bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding,
const sf::Color& bgColor, const sf::Color& tintColor)
{
sf::Vector2f textureSize = static_cast<sf::Vector2f>(texture.getSize());
ImVec2 uv0(textureRect.left / textureSize.x, textureRect.top / textureSize.y);
ImVec2 uv1((textureRect.left + textureRect.width) / textureSize.x,
(textureRect.top + textureRect.height) / textureSize.y);
return ImGui::ImageButton((void*)texture.getNativeHandle(), size, uv0, uv1, framePadding, bgColor, tintColor);
}
} // end of anonymous namespace

@ -1,3 +1,6 @@
#ifndef IMGUI_SFML_H
#define IMGUI_SFML_H
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Rect.hpp> #include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
@ -17,7 +20,7 @@ namespace ImGui
{ {
namespace SFML namespace SFML
{ {
void Init(sf::RenderTarget& target, sf::Texture* fontTexture = NULL); void Init(sf::RenderTarget& target, bool loadDefaultFont = true);
void ProcessEvent(const sf::Event& event); void ProcessEvent(const sf::Event& event);
@ -25,10 +28,12 @@ namespace SFML
void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt); void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt);
void Update(const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::Time dt); void Update(const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::Time dt);
void Render(sf::RenderTarget& target);
void Shutdown(); void Shutdown();
void createFontTexture(sf::Texture& texture); void UpdateFontTexture();
void setFontTexture(sf::Texture& texture); sf::Texture& GetFontTexture();
} }
// custom ImGui widgets for SFML stuff // custom ImGui widgets for SFML stuff
@ -73,3 +78,5 @@ namespace SFML
void DrawRect(const sf::FloatRect& rect, const sf::Color& color, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f); void DrawRect(const sf::FloatRect& rect, const sf::Color& color, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f);
void DrawRectFilled(const sf::FloatRect& rect, const sf::Color& color, float rounding = 0.0f, int rounding_corners = 0x0F); void DrawRectFilled(const sf::FloatRect& rect, const sf::Color& color, float rounding = 0.0f, int rounding_corners = 0x0F);
} }
#endif //# IMGUI_SFML_H

@ -1,186 +1,187 @@
//
//#pragma once
#include "imgui.h" //#include "imgui.h"
#include "imgui_internal.h" //#include "imgui_internal.h"
//
//
namespace ImGui { //
//namespace ImGui {
static ImU32 InvertColorU32(ImU32 in) //
{ // static ImU32 InvertColorU32(ImU32 in)
ImVec4 in4 = ColorConvertU32ToFloat4(in); // {
in4.x = 1.f - in4.x; // ImVec4 in4 = ColorConvertU32ToFloat4(in);
in4.y = 1.f - in4.y; // in4.x = 1.f - in4.x;
in4.z = 1.f - in4.z; // in4.y = 1.f - in4.y;
return GetColorU32(in4); // in4.z = 1.f - in4.z;
} // return GetColorU32(in4);
// }
static void PlotMultiEx( //
ImGuiPlotType plot_type, // static void PlotMultiEx(
const char* label, // ImGuiPlotType plot_type,
int num_datas, // const char* label,
const char** names, // int num_datas,
const ImColor* colors, // const char** names,
float(*getter)(const void* data, int idx), // const ImColor* colors,
const void * const * datas, // float(*getter)(const void* data, int idx),
int values_count, // const void * const * datas,
float scale_min, // int values_count,
float scale_max, // float scale_min,
ImVec2 graph_size) // float scale_max,
{ // ImVec2 graph_size)
const int values_offset = 0; // {
// const int values_offset = 0;
ImGuiWindow* window = GetCurrentWindow(); //
if (window->SkipItems) // ImGuiWindow* window = GetCurrentWindow();
return; // if (window->SkipItems)
// return;
ImGuiContext& g = *GImGui; //
const ImGuiStyle& style = g.Style; // ImGuiContext& g = *GImGui;
// const ImGuiStyle& style = g.Style;
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); //
if (graph_size.x == 0.0f) // const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
graph_size.x = CalcItemWidth(); // if (graph_size.x == 0.0f)
if (graph_size.y == 0.0f) // graph_size.x = CalcItemWidth();
graph_size.y = label_size.y + (style.FramePadding.y * 2); // if (graph_size.y == 0.0f)
// graph_size.y = label_size.y + (style.FramePadding.y * 2);
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); //
const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); // const ImRect frame_bb();//window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y));
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); // const ImRect inner_bb();//frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
ItemSize(total_bb, style.FramePadding.y); // const ImRect total_bb();//frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0));
if (!ItemAdd(total_bb, NULL)) // ItemSize(total_bb, style.FramePadding.y);
return; // if (!ItemAdd(total_bb, NULL))
// return;
// Determine scale from values if not specified //
if (scale_min == FLT_MAX || scale_max == FLT_MAX) // // Determine scale from values if not specified
{ // if (scale_min == FLT_MAX || scale_max == FLT_MAX)
float v_min = FLT_MAX; // {
float v_max = -FLT_MAX; // float v_min = FLT_MAX;
for (int data_idx = 0; data_idx < num_datas; ++data_idx) // float v_max = -FLT_MAX;
{ // for (int data_idx = 0; data_idx < num_datas; ++data_idx)
for (int i = 0; i < values_count; i++) // {
{ // for (int i = 0; i < values_count; i++)
const float v = getter(datas[data_idx], i); // {
v_min = ImMin(v_min, v); // const float v = getter(datas[data_idx], i);
v_max = ImMax(v_max, v); // v_min = ImMin(v_min, v);
} // v_max = ImMax(v_max, v);
} // }
if (scale_min == FLT_MAX) // }
scale_min = v_min; // if (scale_min == FLT_MAX)
if (scale_max == FLT_MAX) // scale_min = v_min;
scale_max = v_max; // if (scale_max == FLT_MAX)
} // scale_max = v_max;
// }
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); //
// RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
int res_w = ImMin((int) graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); //
int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); // int res_w = ImMin((int) graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0);
// int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0);
// Tooltip on hover //
int v_hovered = -1; // // Tooltip on hover
if (IsHovered(inner_bb, 0)) // int v_hovered = -1;
{ // if (IsHovered(inner_bb, 0))
const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); // {
const int v_idx = (int) (t * item_count); // const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f);
IM_ASSERT(v_idx >= 0 && v_idx < values_count); // const int v_idx = (int) (t * item_count);
// IM_ASSERT(v_idx >= 0 && v_idx < values_count);
// std::string toolTip; //
ImGui::BeginTooltip(); // // std::string toolTip;
const int idx0 = (v_idx + values_offset) % values_count; // ImGui::BeginTooltip();
if (plot_type == ImGuiPlotType_Lines) // const int idx0 = (v_idx + values_offset) % values_count;
{ // if (plot_type == ImGuiPlotType_Lines)
const int idx1 = (v_idx + 1 + values_offset) % values_count; // {
Text("%8d %8d | Name", v_idx, v_idx+1); // const int idx1 = (v_idx + 1 + values_offset) % values_count;
for (int dataIdx = 0; dataIdx < num_datas; ++dataIdx) // Text("%8d %8d | Name", v_idx, v_idx+1);
{ // for (int dataIdx = 0; dataIdx < num_datas; ++dataIdx)
const float v0 = getter(datas[dataIdx], idx0); // {
const float v1 = getter(datas[dataIdx], idx1); // const float v0 = getter(datas[dataIdx], idx0);
TextColored(colors[dataIdx], "%8.4g %8.4g | %s", v0, v1, names[dataIdx]); // const float v1 = getter(datas[dataIdx], idx1);
} // TextColored(colors[dataIdx], "%8.4g %8.4g | %s", v0, v1, names[dataIdx]);
} // }
else if (plot_type == ImGuiPlotType_Histogram) // }
{ // else if (plot_type == ImGuiPlotType_Histogram)
for (int dataIdx = 0; dataIdx < num_datas; ++dataIdx) // {
{ // for (int dataIdx = 0; dataIdx < num_datas; ++dataIdx)
const float v0 = getter(datas[dataIdx], idx0); // {
TextColored(colors[dataIdx], "%d: %8.4g | %s", v_idx, v0, names[dataIdx]); // const float v0 = getter(datas[dataIdx], idx0);
} // TextColored(colors[dataIdx], "%d: %8.4g | %s", v_idx, v0, names[dataIdx]);
} // }
ImGui::EndTooltip(); // }
v_hovered = v_idx; // ImGui::EndTooltip();
} // v_hovered = v_idx;
// }
for (int data_idx = 0; data_idx < num_datas; ++data_idx) //
{ // for (int data_idx = 0; data_idx < num_datas; ++data_idx)
const float t_step = 1.0f / (float) res_w; // {
// const float t_step = 1.0f / (float) res_w;
float v0 = getter(datas[data_idx], (0 + values_offset) % values_count); //
float t0 = 0.0f; // float v0 = getter(datas[data_idx], (0 + values_offset) % values_count);
ImVec2 tp0 = ImVec2(t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min))); // Point in the normalized space of our target rectangle // float t0 = 0.0f;
// ImVec2 tp0 = ImVec2(t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min))); // Point in the normalized space of our target rectangle
const ImU32 col_base = colors[data_idx]; //
const ImU32 col_hovered = InvertColorU32(colors[data_idx]); // const ImU32 col_base = colors[data_idx];
// const ImU32 col_hovered = InvertColorU32(colors[data_idx]);
//const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); //
//const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); // //const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram);
// //const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered);
for (int n = 0; n < res_w; n++) //
{ // for (int n = 0; n < res_w; n++)
const float t1 = t0 + t_step; // {
const int v1_idx = (int) (t0 * item_count + 0.5f); // const float t1 = t0 + t_step;
IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); // const int v1_idx = (int) (t0 * item_count + 0.5f);
const float v1 = getter(datas[data_idx], (v1_idx + values_offset + 1) % values_count); // IM_ASSERT(v1_idx >= 0 && v1_idx < values_count);
const ImVec2 tp1 = ImVec2(t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min))); // const float v1 = getter(datas[data_idx], (v1_idx + values_offset + 1) % values_count);
// const ImVec2 tp1 = ImVec2(t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)));
// NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. //
ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); // // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU.
ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, 1.0f)); // ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0);
if (plot_type == ImGuiPlotType_Lines) // ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, 1.0f));
{ // if (plot_type == ImGuiPlotType_Lines)
window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); // {
} // window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base);
else if (plot_type == ImGuiPlotType_Histogram) // }
{ // else if (plot_type == ImGuiPlotType_Histogram)
if (pos1.x >= pos0.x + 2.0f) // {
pos1.x -= 1.0f; // if (pos1.x >= pos0.x + 2.0f)
window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); // pos1.x -= 1.0f;
} // window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base);
// }
t0 = t1; //
tp0 = tp1; // t0 = t1;
} // tp0 = tp1;
} // }
// }
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); //
} // RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
//}
void PlotMultiLines( //
const char* label, //void PlotMultiLines(
int num_datas, // const char* label,
const char** names, // int num_datas,
const ImColor* colors, // const char** names,
float(*getter)(const void* data, int idx), // const ImColor* colors,
const void * const * datas, // float(*getter)(const void* data, int idx),
int values_count, // const void * const * datas,
float scale_min, // int values_count,
float scale_max, // float scale_min,
ImVec2 graph_size) // float scale_max,
{ // ImVec2 graph_size)
PlotMultiEx(ImGuiPlotType_Lines, label, num_datas, names, colors, getter, datas, values_count, scale_min, scale_max, graph_size); //{
} // PlotMultiEx(ImGuiPlotType_Lines, label, num_datas, names, colors, getter, datas, values_count, scale_min, scale_max, graph_size);
//}
void PlotMultiHistograms( //
const char* label, //void PlotMultiHistograms(
int num_hists, // const char* label,
const char** names, // int num_hists,
const ImColor* colors, // const char** names,
float(*getter)(const void* data, int idx), // const ImColor* colors,
const void * const * datas, // float(*getter)(const void* data, int idx),
int values_count, // const void * const * datas,
float scale_min, // int values_count,
float scale_max, // float scale_min,
ImVec2 graph_size) // float scale_max,
{ // ImVec2 graph_size)
PlotMultiEx(ImGuiPlotType_Histogram, label, num_hists, names, colors, getter, datas, values_count, scale_min, scale_max, graph_size); //{
} // PlotMultiEx(ImGuiPlotType_Histogram, label, num_hists, names, colors, getter, datas, values_count, scale_min, scale_max, graph_size);
//}
} // namespace ImGui //
//} // namespace ImGui

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,9 +1,10 @@
// dear imgui, v1.50 WIP // dear imgui, v1.53
// (internals) // (internals)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
// Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) // Set:
// #define IMGUI_DEFINE_MATH_OPERATORS // #define IMGUI_DEFINE_MATH_OPERATORS
// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
#pragma once #pragma once
@ -37,15 +38,16 @@ struct ImGuiGroupData;
struct ImGuiSimpleColumns; struct ImGuiSimpleColumns;
struct ImGuiDrawContext; struct ImGuiDrawContext;
struct ImGuiTextEditState; struct ImGuiTextEditState;
struct ImGuiIniData;
struct ImGuiMouseCursorData; struct ImGuiMouseCursorData;
struct ImGuiPopupRef; struct ImGuiPopupRef;
struct ImGuiWindow; struct ImGuiWindow;
struct ImGuiWindowSettings;
typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_
typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_
typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_
typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// STB libraries // STB libraries
@ -75,7 +77,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
// Helpers // Helpers
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
#define IM_PI 3.14159265358979323846f #define IM_PI 3.14159265358979323846f
#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) #define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM))
@ -90,19 +91,27 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons
IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings
IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0);
IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode);
IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c);
static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; }
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
// Helpers: Geometry
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w);
// Helpers: String // Helpers: String
IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStricmp(const char* str1, const char* str2);
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count);
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count);
IMGUI_API char* ImStrdup(const char* str); IMGUI_API char* ImStrdup(const char* str);
IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API int ImStrlenW(const ImWchar* str);
IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_PRINTFARGS(3); IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args); IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
// Helpers: Math // Helpers: Math
// We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined)
@ -117,7 +126,9 @@ static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs)
static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); }
static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); } static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); }
static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); }
#endif #endif
static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; }
@ -130,40 +141,54 @@ static inline int ImClamp(int v, int mn, int mx)
static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); }
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
static inline void ImSwap(int& a, int& b) { int tmp = a; a = b; b = tmp; }
static inline void ImSwap(float& a, float& b) { float tmp = a; a = b; b = tmp; }
static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); }
static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; }
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)f; } static inline float ImFloor(float f) { return (float)(int)f; }
static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions. // Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
#ifdef IMGUI_DEFINE_PLACEMENT_NEW struct ImNewPlacementDummy {};
struct ImPlacementNewDummy {}; inline void* operator new(size_t, ImNewPlacementDummy, void* ptr) { return ptr; }
inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; } inline void operator delete(void*, ImNewPlacementDummy, void*) {} // This is only required so we can use the symetrical new()
inline void operator delete(void*, ImPlacementNewDummy, void*) {} #define IM_PLACEMENT_NEW(_PTR) new(ImNewPlacementDummy(), _PTR)
#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR) #define IM_NEW(_TYPE) new(ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
#endif template <typename T> void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p); p = NULL; } }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Types // Types
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui.
#define IMGUI_PAYLOAD_TYPE_DOCKABLE "_IMDOCK" // ImGuiWindow* // [Internal] Docking/tabs
enum ImGuiButtonFlags_ enum ImGuiButtonFlags_
{ {
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set) ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // return true on click + release on same item [DEFAULT if no PressedOn* flag is set]
ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release) ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release)
ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release) ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release)
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release) ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release)
ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping ImGuiButtonFlags_FlattenChildren = 1 << 5, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press ImGuiButtonFlags_AllowItemOverlap = 1 << 6, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction ImGuiButtonFlags_DontClosePopups = 1 << 7, // disable automatically closing parent popup on press // [UNUSED]
ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only ImGuiButtonFlags_Disabled = 1 << 8, // disable interactions
ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable ImGuiButtonFlags_NoKeyModifiers = 1 << 10, // disable interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12 // press when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
}; };
enum ImGuiSliderFlags_ enum ImGuiSliderFlags_
@ -171,15 +196,31 @@ enum ImGuiSliderFlags_
ImGuiSliderFlags_Vertical = 1 << 0 ImGuiSliderFlags_Vertical = 1 << 0
}; };
enum ImGuiColumnsFlags_
{
// Default: 0
ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers
ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers
ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns
ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window
ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove.
};
enum ImGuiSelectableFlagsPrivate_ enum ImGuiSelectableFlagsPrivate_
{ {
// NB: need to be in sync with last value of ImGuiSelectableFlags_ // NB: need to be in sync with last value of ImGuiSelectableFlags_
ImGuiSelectableFlags_Menu = 1 << 3, ImGuiSelectableFlags_Menu = 1 << 3, // -> PressedOnClick
ImGuiSelectableFlags_MenuItem = 1 << 4, ImGuiSelectableFlags_MenuItem = 1 << 4, // -> PressedOnRelease
ImGuiSelectableFlags_Disabled = 1 << 5, ImGuiSelectableFlags_Disabled = 1 << 5,
ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6
}; };
enum ImGuiSeparatorFlags_
{
ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar
ImGuiSeparatorFlags_Vertical = 1 << 1
};
// FIXME: this is in development, not exposed/functional as a generic feature yet. // FIXME: this is in development, not exposed/functional as a generic feature yet.
enum ImGuiLayoutType_ enum ImGuiLayoutType_
{ {
@ -187,6 +228,13 @@ enum ImGuiLayoutType_
ImGuiLayoutType_Horizontal ImGuiLayoutType_Horizontal
}; };
enum ImGuiAxis
{
ImGuiAxis_None = -1,
ImGuiAxis_X = 0,
ImGuiAxis_Y = 1
};
enum ImGuiPlotType enum ImGuiPlotType
{ {
ImGuiPlotType_Lines, ImGuiPlotType_Lines,
@ -197,16 +245,17 @@ enum ImGuiDataType
{ {
ImGuiDataType_Int, ImGuiDataType_Int,
ImGuiDataType_Float, ImGuiDataType_Float,
ImGuiDataType_Float2, ImGuiDataType_Float2
}; };
enum ImGuiCorner enum ImGuiDir
{ {
ImGuiCorner_TopLeft = 1 << 0, // 1 ImGuiDir_None = -1,
ImGuiCorner_TopRight = 1 << 1, // 2 ImGuiDir_Left = 0,
ImGuiCorner_BottomRight = 1 << 2, // 4 ImGuiDir_Right = 1,
ImGuiCorner_BottomLeft = 1 << 3, // 8 ImGuiDir_Up = 2,
ImGuiCorner_All = 0x0F ImGuiDir_Down = 3,
ImGuiDir_Count_
}; };
// 2D axis aligned bounding-box // 2D axis aligned bounding-box
@ -236,9 +285,11 @@ struct IMGUI_API ImRect
void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; }
void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; }
void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; }
void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; }
void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); }
bool IsFinite() const { return Min.x != FLT_MAX; }
ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const
{ {
if (!on_edge && Contains(p)) if (!on_edge && Contains(p))
@ -282,13 +333,6 @@ struct ImGuiGroupData
bool AdvanceCursor; bool AdvanceCursor;
}; };
// Per column data for Columns()
struct ImGuiColumnData
{
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
//float IndentX;
};
// Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper.
struct IMGUI_API ImGuiSimpleColumns struct IMGUI_API ImGuiSimpleColumns
{ {
@ -328,13 +372,24 @@ struct IMGUI_API ImGuiTextEditState
}; };
// Data saved in imgui.ini file // Data saved in imgui.ini file
struct ImGuiIniData struct ImGuiWindowSettings
{ {
char* Name; char* Name;
ImGuiID Id; ImGuiID Id;
ImVec2 Pos; ImVec2 Pos;
ImVec2 Size; ImVec2 Size;
bool Collapsed; bool Collapsed;
ImGuiWindowSettings() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; }
};
struct ImGuiSettingsHandler
{
const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']'
ImGuiID TypeHash; // == ImHash(TypeName, 0, 0)
void* (*ReadOpenFn)(ImGuiContext& ctx, const char* name);
void (*ReadLineFn)(ImGuiContext& ctx, void* entry, const char* line);
void (*WriteAllFn)(ImGuiContext& ctx, ImGuiTextBuffer* out_buf);
}; };
// Mouse cursor data (used when io.MouseDrawCursor is set) // Mouse cursor data (used when io.MouseDrawCursor is set)
@ -359,6 +414,62 @@ struct ImGuiPopupRef
ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
}; };
struct ImGuiColumnData
{
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
float OffsetNormBeforeResize;
ImGuiColumnsFlags Flags; // Not exposed
ImRect ClipRect;
ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; }
};
struct ImGuiColumnsSet
{
ImGuiID ID;
ImGuiColumnsFlags Flags;
bool IsFirstFrame;
bool IsBeingResized;
int Current;
int Count;
float MinX, MaxX;
float StartPosY;
float StartMaxPosX; // Backup of CursorMaxPos
float CellMinY, CellMaxY;
ImVector<ImGuiColumnData> Columns;
ImGuiColumnsSet() { Clear(); }
void Clear()
{
ID = 0;
Flags = 0;
IsFirstFrame = false;
IsBeingResized = false;
Current = 0;
Count = 1;
MinX = MaxX = 0.0f;
StartPosY = 0.0f;
StartMaxPosX = 0.0f;
CellMinY = CellMaxY = 0.0f;
Columns.clear();
}
};
struct ImDrawListSharedData
{
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
ImFont* Font; // Current/default font (optional, for simplified AddText overload)
float FontSize; // Current/default font size (optional, for simplified AddText overload)
float CurveTessellationTol;
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
// Const data
// FIXME: Bake rounded corners fill/borders in atlas
ImVec2 CircleVtx12[12];
ImDrawListSharedData();
};
// Main state for ImGui // Main state for ImGui
struct ImGuiContext struct ImGuiContext
{ {
@ -366,9 +477,9 @@ struct ImGuiContext
ImGuiIO IO; ImGuiIO IO;
ImGuiStyle Style; ImGuiStyle Style;
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel ImDrawListSharedData DrawListSharedData;
float Time; float Time;
int FrameCount; int FrameCount;
@ -376,25 +487,27 @@ struct ImGuiContext
int FrameCountRendered; int FrameCountRendered;
ImVector<ImGuiWindow*> Windows; ImVector<ImGuiWindow*> Windows;
ImVector<ImGuiWindow*> WindowsSortBuffer; ImVector<ImGuiWindow*> WindowsSortBuffer;
ImGuiWindow* CurrentWindow; // Being drawn into
ImVector<ImGuiWindow*> CurrentWindowStack; ImVector<ImGuiWindow*> CurrentWindowStack;
ImGuiWindow* FocusedWindow; // Will catch keyboard inputs ImGuiStorage WindowsById;
int WindowsActiveCount;
ImGuiWindow* CurrentWindow; // Being drawn into
ImGuiWindow* NavWindow; // Nav/focused window for navigation
ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
ImGuiID HoveredId; // Hovered widget ImGuiID HoveredId; // Hovered widget
bool HoveredIdAllowOverlap; bool HoveredIdAllowOverlap;
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;
float HoveredIdTimer;
ImGuiID ActiveId; // Active widget ImGuiID ActiveId; // Active widget
ImGuiID ActiveIdPreviousFrame; ImGuiID ActiveIdPreviousFrame;
bool ActiveIdIsAlive; float ActiveIdTimer;
bool ActiveIdIsAlive; // Active widget has been seen this frame
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Set only by active widget bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow; ImGuiWindow* ActiveIdWindow;
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window.
ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId
ImVector<ImGuiIniData> Settings; // .ini Settings
float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
@ -403,20 +516,21 @@ struct ImGuiContext
// Storage for SetNexWindow** and SetNextTreeNode*** functions // Storage for SetNexWindow** and SetNextTreeNode*** functions
ImVec2 SetNextWindowPosVal; ImVec2 SetNextWindowPosVal;
ImVec2 SetNextWindowPosPivot;
ImVec2 SetNextWindowSizeVal; ImVec2 SetNextWindowSizeVal;
ImVec2 SetNextWindowContentSizeVal; ImVec2 SetNextWindowContentSizeVal;
bool SetNextWindowCollapsedVal; bool SetNextWindowCollapsedVal;
ImGuiSetCond SetNextWindowPosCond; ImGuiCond SetNextWindowPosCond;
ImGuiSetCond SetNextWindowSizeCond; ImGuiCond SetNextWindowSizeCond;
ImGuiSetCond SetNextWindowContentSizeCond; ImGuiCond SetNextWindowContentSizeCond;
ImGuiSetCond SetNextWindowCollapsedCond; ImGuiCond SetNextWindowCollapsedCond;
ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true
ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback; ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback;
void* SetNextWindowSizeConstraintCallbackUserData; void* SetNextWindowSizeConstraintCallbackUserData;
bool SetNextWindowSizeConstraint; bool SetNextWindowSizeConstraint;
bool SetNextWindowFocus; bool SetNextWindowFocus;
bool SetNextTreeNodeOpenVal; bool SetNextTreeNodeOpenVal;
ImGuiSetCond SetNextTreeNodeOpenCond; ImGuiCond SetNextTreeNodeOpenCond;
// Render // Render
ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user
@ -426,21 +540,41 @@ struct ImGuiContext
ImGuiMouseCursor MouseCursor; ImGuiMouseCursor MouseCursor;
ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_];
// Drag and Drop
bool DragDropActive;
ImGuiDragDropFlags DragDropSourceFlags;
int DragDropMouseButton;
ImGuiPayload DragDropPayload;
ImRect DragDropTargetRect;
ImGuiID DragDropTargetId;
float DragDropAcceptIdCurrRectSurface;
ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload)
ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets)
int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source
ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly
unsigned char DragDropPayloadBufLocal[8];
// Widget state // Widget state
ImGuiTextEditState InputTextState; ImGuiTextEditState InputTextState;
ImFont InputTextPasswordFont; ImFont InputTextPasswordFont;
ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
ImVec4 ColorPickerRef;
float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings
ImVec2 DragLastMouseDelta; ImVec2 DragLastMouseDelta;
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
float DragSpeedScaleSlow; float DragSpeedScaleSlow;
float DragSpeedScaleFast; float DragSpeedScaleFast;
ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
char Tooltip[1024]; int TooltipOverrideCount;
char* PrivateClipboard; // If no custom clipboard handler is defined ImVector<char> PrivateClipboard; // If no custom clipboard handler is defined
ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor
// Settings
float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
ImVector<ImGuiWindowSettings> SettingsWindows; // .ini settings for ImGuiWindow
ImVector<ImGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
// Logging // Logging
bool LogEnabled; bool LogEnabled;
FILE* LogFile; // If != NULL log to stdout/ file FILE* LogFile; // If != NULL log to stdout/ file
@ -452,37 +586,39 @@ struct ImGuiContext
float FramerateSecPerFrame[120]; // calculate estimate of framerate for user float FramerateSecPerFrame[120]; // calculate estimate of framerate for user
int FramerateSecPerFrameIdx; int FramerateSecPerFrameIdx;
float FramerateSecPerFrameAccum; float FramerateSecPerFrameAccum;
int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags
int CaptureKeyboardNextFrame; int WantCaptureKeyboardNextFrame;
int WantTextInputNextFrame;
char TempBuffer[1024*3+1]; // temporary text buffer char TempBuffer[1024*3+1]; // temporary text buffer
ImGuiContext() ImGuiContext() : OverlayDrawList(NULL)
{ {
Initialized = false; Initialized = false;
Font = NULL; Font = NULL;
FontSize = FontBaseSize = 0.0f; FontSize = FontBaseSize = 0.0f;
FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
Time = 0.0f; Time = 0.0f;
FrameCount = 0; FrameCount = 0;
FrameCountEnded = FrameCountRendered = -1; FrameCountEnded = FrameCountRendered = -1;
WindowsActiveCount = 0;
CurrentWindow = NULL; CurrentWindow = NULL;
FocusedWindow = NULL; NavWindow = NULL;
HoveredWindow = NULL; HoveredWindow = NULL;
HoveredRootWindow = NULL; HoveredRootWindow = NULL;
HoveredId = 0; HoveredId = 0;
HoveredIdAllowOverlap = false; HoveredIdAllowOverlap = false;
HoveredIdPreviousFrame = 0; HoveredIdPreviousFrame = 0;
HoveredIdTimer = 0.0f;
ActiveId = 0; ActiveId = 0;
ActiveIdPreviousFrame = 0; ActiveIdPreviousFrame = 0;
ActiveIdTimer = 0.0f;
ActiveIdIsAlive = false; ActiveIdIsAlive = false;
ActiveIdIsJustActivated = false; ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false; ActiveIdAllowOverlap = false;
ActiveIdClickOffset = ImVec2(-1,-1); ActiveIdClickOffset = ImVec2(-1,-1);
ActiveIdWindow = NULL; ActiveIdWindow = NULL;
MovedWindow = NULL; MovingWindow = NULL;
MovedWindowMoveId = 0; MovingWindowMoveId = 0;
SettingsDirtyTimer = 0.0f;
SetNextWindowPosVal = ImVec2(0.0f, 0.0f); SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
@ -499,22 +635,33 @@ struct ImGuiContext
SetNextTreeNodeOpenVal = false; SetNextTreeNodeOpenVal = false;
SetNextTreeNodeOpenCond = 0; SetNextTreeNodeOpenCond = 0;
DragDropActive = false;
DragDropSourceFlags = 0;
DragDropMouseButton = -1;
DragDropTargetId = 0;
DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
DragDropAcceptFrameCount = -1;
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
ScalarAsInputTextId = 0; ScalarAsInputTextId = 0;
ColorEditOptions = ImGuiColorEditFlags__OptionsDefault;
DragCurrentValue = 0.0f; DragCurrentValue = 0.0f;
DragLastMouseDelta = ImVec2(0.0f, 0.0f); DragLastMouseDelta = ImVec2(0.0f, 0.0f);
DragSpeedDefaultRatio = 1.0f / 100.0f; DragSpeedDefaultRatio = 1.0f / 100.0f;
DragSpeedScaleSlow = 0.01f; DragSpeedScaleSlow = 1.0f / 100.0f;
DragSpeedScaleFast = 10.0f; DragSpeedScaleFast = 10.0f;
ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f);
memset(Tooltip, 0, sizeof(Tooltip)); TooltipOverrideCount = 0;
PrivateClipboard = NULL;
OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f);
ModalWindowDarkeningRatio = 0.0f; ModalWindowDarkeningRatio = 0.0f;
OverlayDrawList._Data = &DrawListSharedData;
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
MouseCursor = ImGuiMouseCursor_Arrow; MouseCursor = ImGuiMouseCursor_Arrow;
memset(MouseCursorData, 0, sizeof(MouseCursorData)); memset(MouseCursorData, 0, sizeof(MouseCursorData));
SettingsDirtyTimer = 0.0f;
LogEnabled = false; LogEnabled = false;
LogFile = NULL; LogFile = NULL;
LogClipboard = NULL; LogClipboard = NULL;
@ -524,11 +671,23 @@ struct ImGuiContext
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = 0; FramerateSecPerFrameIdx = 0;
FramerateSecPerFrameAccum = 0.0f; FramerateSecPerFrameAccum = 0.0f;
CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1; WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
memset(TempBuffer, 0, sizeof(TempBuffer)); memset(TempBuffer, 0, sizeof(TempBuffer));
} }
}; };
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
enum ImGuiItemFlags_
{
ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
ImGuiItemFlags_Disabled = 1 << 2, // false // FIXME-WIP: Disable interactions but doesn't affect visuals. Should be: grey out and disable interactions with widgets that affect data + view widgets (WIP)
//ImGuiItemFlags_NoNav = 1 << 3, // false
//ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus
};
// Transient per-window data, reset at the beginning of the frame // Transient per-window data, reset at the beginning of the frame
// FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered. // FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered.
struct IMGUI_API ImGuiDrawContext struct IMGUI_API ImGuiDrawContext
@ -536,7 +695,7 @@ struct IMGUI_API ImGuiDrawContext
ImVec2 CursorPos; ImVec2 CursorPos;
ImVec2 CursorPosPrevLine; ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos; ImVec2 CursorStartPos;
ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame
float CurrentLineHeight; float CurrentLineHeight;
float CurrentLineTextBaseOffset; float CurrentLineTextBaseOffset;
float PrevLineHeight; float PrevLineHeight;
@ -545,8 +704,7 @@ struct IMGUI_API ImGuiDrawContext
int TreeDepth; int TreeDepth;
ImGuiID LastItemId; ImGuiID LastItemId;
ImRect LastItemRect; ImRect LastItemRect;
bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) bool LastItemRectHoveredRect;
bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window)
bool MenuBarAppending; bool MenuBarAppending;
float MenuBarOffsetX; float MenuBarOffsetX;
ImVector<ImGuiWindow*> ChildWindows; ImVector<ImGuiWindow*> ChildWindows;
@ -554,31 +712,19 @@ struct IMGUI_API ImGuiDrawContext
ImGuiLayoutType LayoutType; ImGuiLayoutType LayoutType;
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default]
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true] ImVector<ImGuiItemFlags>ItemFlagsStack;
bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false]
ImVector<float> ItemWidthStack; ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack; ImVector<float> TextWrapPosStack;
ImVector<bool> AllowKeyboardFocusStack;
ImVector<bool> ButtonRepeatStack;
ImVector<ImGuiGroupData>GroupStack; ImVector<ImGuiGroupData>GroupStack;
ImGuiColorEditMode ColorEditMode;
int StackSizesBackup[6]; // Store size of various stacks for asserting int StackSizesBackup[6]; // Store size of various stacks for asserting
float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
float GroupOffsetX; float GroupOffsetX;
float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
int ColumnsCurrent; ImGuiColumnsSet* ColumnsSet; // Current columns set
int ColumnsCount;
float ColumnsMinX;
float ColumnsMaxX;
float ColumnsStartPosY;
float ColumnsCellMinY;
float ColumnsCellMaxY;
bool ColumnsShowBorders;
ImGuiID ColumnsSetId;
ImVector<ImGuiColumnData> ColumnsData;
ImGuiDrawContext() ImGuiDrawContext()
{ {
@ -588,29 +734,21 @@ struct IMGUI_API ImGuiDrawContext
LogLinePosY = -1.0f; LogLinePosY = -1.0f;
TreeDepth = 0; TreeDepth = 0;
LastItemId = 0; LastItemId = 0;
LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); LastItemRect = ImRect();
LastItemHoveredAndUsable = LastItemHoveredRect = false; LastItemRectHoveredRect = false;
MenuBarAppending = false; MenuBarAppending = false;
MenuBarOffsetX = 0.0f; MenuBarOffsetX = 0.0f;
StateStorage = NULL; StateStorage = NULL;
LayoutType = ImGuiLayoutType_Vertical; LayoutType = ImGuiLayoutType_Vertical;
ItemWidth = 0.0f; ItemWidth = 0.0f;
ButtonRepeat = false; ItemFlags = ImGuiItemFlags_Default_;
AllowKeyboardFocus = true;
TextWrapPos = -1.0f; TextWrapPos = -1.0f;
ColorEditMode = ImGuiColorEditMode_RGB;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
IndentX = 0.0f; IndentX = 0.0f;
GroupOffsetX = 0.0f; GroupOffsetX = 0.0f;
ColumnsOffsetX = 0.0f; ColumnsOffsetX = 0.0f;
ColumnsCurrent = 0; ColumnsSet = NULL;
ColumnsCount = 1;
ColumnsMinX = ColumnsMaxX = 0.0f;
ColumnsStartPosY = 0.0f;
ColumnsCellMinY = ColumnsCellMaxY = 0.0f;
ColumnsShowBorders = true;
ColumnsSetId = 0;
} }
}; };
@ -620,51 +758,60 @@ struct IMGUI_API ImGuiWindow
char* Name; char* Name;
ImGuiID ID; // == ImHash(Name) ImGuiID ID; // == ImHash(Name)
ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_
int IndexWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
ImVec2 PosFloat; ImVec2 PosFloat;
ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Pos; // Position rounded-up to nearest pixel
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFull; // Size when non collapsed
ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars.
ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. Include decoration, window title, border, menu, etc.
ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize()
ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis
ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect ImVec2 WindowPadding; // Window padding at the time of begin.
float WindowRounding; // Window rounding at the time of begin.
float WindowBorderSize; // Window border size at the time of begin.
ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID MoveId; // == window->GetID("#MOVE")
ImVec2 Scroll; ImVec2 Scroll;
ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
bool ScrollbarX, ScrollbarY; bool ScrollbarX, ScrollbarY;
ImVec2 ScrollbarSizes; ImVec2 ScrollbarSizes;
float BorderSize;
bool Active; // Set to true on Begin() bool Active; // Set to true on Begin()
bool WasActive; bool WasActive;
bool Accessed; // Set to true when any widget access the current window bool WriteAccessed; // Set to true when any widget access the current window
bool Collapsed; // Set when collapsing window to become only title-bar bool Collapsed; // Set when collapsing window to become only title-bar
bool SkipItems; // == Visible && !Collapsed bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
bool CloseButton; // Set when the window has a close button (p_open != NULL)
int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
int AutoFitFramesX, AutoFitFramesY; int AutoFitFramesX, AutoFitFramesY;
bool AutoFitOnlyGrows; bool AutoFitOnlyGrows;
int AutoPosLastDirection; int AutoFitChildAxises;
ImGuiDir AutoPosLastDirection;
int HiddenFrames; int HiddenFrames;
int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call.
int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call.
int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call.
bool SetWindowPosCenterWanted; ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right.
ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2.
ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window.
ImRect InnerRect;
int LastFrameActive; int LastFrameActive;
float ItemWidthDefault; float ItemWidthDefault;
ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items
ImGuiStorage StateStorage; ImGuiStorage StateStorage;
ImVector<ImGuiColumnsSet> ColumnsStorage;
float FontWindowScale; // Scale multiplier per-window float FontWindowScale; // Scale multiplier per-window
ImDrawList* DrawList; ImDrawList* DrawList;
ImGuiWindow* RootWindow; // If we are a child window, this is pointing to the first non-child parent window. Else point to ourself. ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL.
ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself. ImGuiWindow* RootWindow; // Generally point to ourself. If we are a child window, this is pointing to the first non-child parent window.
ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL. ImGuiWindow* RootNonPopupWindow; // Generally point to ourself. Used to display TitleBgActive color and for selecting which window to use for NavWindowing
// Navigation / Focus // Navigation / Focus
int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
@ -675,13 +822,15 @@ struct IMGUI_API ImGuiWindow
int FocusIdxTabRequestNext; // " int FocusIdxTabRequestNext; // "
public: public:
ImGuiWindow(const char* name); ImGuiWindow(ImGuiContext* context, const char* name);
~ImGuiWindow(); ~ImGuiWindow();
ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const char* str, const char* str_end = NULL);
ImGuiID GetID(const void* ptr); ImGuiID GetID(const void* ptr);
ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL);
ImGuiID GetIDFromRectangle(const ImRect& r_abs);
// We don't use g.FontSize because the window may be != g.CurrentWidow.
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); }
float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; }
float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; }
@ -690,6 +839,18 @@ public:
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
}; };
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
struct ImGuiItemHoveredDataBackup
{
ImGuiID LastItemId;
ImRect LastItemRect;
bool LastItemRectHoveredRect;
ImGuiItemHoveredDataBackup() { Backup(); }
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; }
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; }
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Internal API // Internal API
// No guarantee of forward compatibility here. // No guarantee of forward compatibility here.
@ -702,12 +863,18 @@ namespace ImGui
// - ImGui::NewFrame() has never been called, which is illegal. // - ImGui::NewFrame() has never been called, which is illegal.
// - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
IMGUI_API ImGuiWindow* GetParentWindow();
IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void FocusWindow(ImGuiWindow* window); IMGUI_API void FocusWindow(ImGuiWindow* window);
IMGUI_API void BringWindowToFront(ImGuiWindow* window);
IMGUI_API void BringWindowToBack(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! IMGUI_API void Initialize();
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(ImGuiID type_id);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
IMGUI_API void ClearActiveID(); IMGUI_API void ClearActiveID();
@ -716,31 +883,56 @@ namespace ImGui
IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f);
IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f);
IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id);
IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop = true); // Return true if focus is requested IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void PushMultiItemsWidths(int components, float width_full = 0.0f);
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing);
IMGUI_API void ClosePopup(ImGuiID id);
IMGUI_API bool IsPopupOpen(ImGuiID id);
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate);
IMGUI_API void Scrollbar(ImGuiLayoutType direction);
IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout.
IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f);
IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
IMGUI_API void ClearDragDrop();
IMGUI_API bool IsDragDropPayloadBeingAccepted();
// NB: All position are in absolute pixels coordinates (not window coordinates) // FIXME-WIP: New Columns API
// FIXME: All those functions are a mess and needs to be refactored into something decent. AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
// We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. IMGUI_API void EndColumns(); // close columns
IMGUI_API void PushColumnClipRect(int column_index = -1);
// NB: All position are in absolute pixels coordinates (never using window coordinates internally)
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); 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, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); 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, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); 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 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
IMGUI_API void RenderTriangle(ImVec2 pos, ImGuiDir dir, float scale = 1.0f);
IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderBullet(ImVec2 pos);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz);
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); 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 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); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
IMGUI_API bool ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags = 0);
IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0);
IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power);
@ -756,6 +948,9 @@ namespace ImGui
IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags);
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging
IMGUI_API void TreePushRawID(ImGuiID id); IMGUI_API void TreePushRawID(ImGuiID id);
@ -765,8 +960,22 @@ namespace ImGui
IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value);
IMGUI_API float RoundScalar(float value, int decimal_precision); IMGUI_API float RoundScalar(float value, int decimal_precision);
// Shade functions
IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1);
IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x);
IMGUI_API void ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp);
} // namespace ImGui } // namespace ImGui
// ImFontAtlas internals
IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif

@ -1,5 +1,5 @@
#include "imgui/imgui-SFML.h" #include "imgui/imgui-SFML.h"
#include "imgui/imgui.h" #include <imgui/imgui.h>
#include <SFML/OpenGL.hpp> #include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
@ -10,8 +10,102 @@
#include <SFML/Window/Event.hpp> #include <SFML/Window/Event.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Window/Window.hpp>
#include <cmath> // abs
#include <cstddef> // offsetof, NULL #include <cstddef> // offsetof, NULL
#include <cassert> #include <cassert>
#include <SFML/Window/Touch.hpp>
#ifdef ANDROID
#ifdef USE_JNI
#include <jni.h>
#include <android/native_activity.h>
#include <SFML/System/NativeActivity.hpp>
static bool s_wantTextInput = false;
int openKeyboardIME()
{
ANativeActivity *activity = sf::getNativeActivity();
JavaVM* vm = activity->vm;
JNIEnv* env = activity->env;
JavaVMAttachArgs attachargs;
attachargs.version = JNI_VERSION_1_6;
attachargs.name = "NativeThread";
attachargs.group = NULL;
jint res = vm->AttachCurrentThread(&env, &attachargs);
if (res == JNI_ERR)
return EXIT_FAILURE;
jclass natact = env->FindClass("android/app/NativeActivity");
jclass context = env->FindClass("android/content/Context");
jfieldID fid = env->GetStaticFieldID(context, "INPUT_METHOD_SERVICE", "Ljava/lang/String;");
jobject svcstr = env->GetStaticObjectField(context, fid);
jmethodID getss = env->GetMethodID(natact, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject imm_obj = env->CallObjectMethod(activity->clazz, getss, svcstr);
jclass imm_cls = env->GetObjectClass(imm_obj);
jmethodID toggleSoftInput = env->GetMethodID(imm_cls, "toggleSoftInput", "(II)V");
env->CallVoidMethod(imm_obj, toggleSoftInput, 2, 0);
env->DeleteLocalRef(imm_obj);
env->DeleteLocalRef(imm_cls);
env->DeleteLocalRef(svcstr);
env->DeleteLocalRef(context);
env->DeleteLocalRef(natact);
vm->DetachCurrentThread();
return EXIT_SUCCESS;
}
int closeKeyboardIME()
{
ANativeActivity *activity = sf::getNativeActivity();
JavaVM* vm = activity->vm;
JNIEnv* env = activity->env;
JavaVMAttachArgs attachargs;
attachargs.version = JNI_VERSION_1_6;
attachargs.name = "NativeThread";
attachargs.group = NULL;
jint res = vm->AttachCurrentThread(&env, &attachargs);
if (res == JNI_ERR)
return EXIT_FAILURE;
jclass natact = env->FindClass("android/app/NativeActivity");
jclass context = env->FindClass("android/content/Context");
jfieldID fid = env->GetStaticFieldID(context, "INPUT_METHOD_SERVICE", "Ljava/lang/String;");
jobject svcstr = env->GetStaticObjectField(context, fid);
jmethodID getss = env->GetMethodID(natact, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject imm_obj = env->CallObjectMethod(activity->clazz, getss, svcstr);
jclass imm_cls = env->GetObjectClass(imm_obj);
jmethodID toggleSoftInput = env->GetMethodID(imm_cls, "toggleSoftInput", "(II)V");
env->CallVoidMethod(imm_obj, toggleSoftInput, 1, 0);
env->DeleteLocalRef(imm_obj);
env->DeleteLocalRef(imm_cls);
env->DeleteLocalRef(svcstr);
env->DeleteLocalRef(context);
env->DeleteLocalRef(natact);
vm->DetachCurrentThread();
return EXIT_SUCCESS;
}
#endif
#endif
// Supress warnings caused by converting from uint to void* in pCmd->TextureID // Supress warnings caused by converting from uint to void* in pCmd->TextureID
#ifdef __clang__ #ifdef __clang__
@ -22,6 +116,9 @@
static bool s_windowHasFocus = true; static bool s_windowHasFocus = true;
static bool s_mousePressed[3] = { false, false, false }; static bool s_mousePressed[3] = { false, false, false };
static bool s_touchDown[3] = { false, false, false };
static bool s_mouseMoved = false;
static sf::Vector2i s_touchPos;
static sf::Texture* s_fontTexture = NULL; // owning pointer to internal font atlas which is used if user doesn't set custom sf::Texture. static sf::Texture* s_fontTexture = NULL; // owning pointer to internal font atlas which is used if user doesn't set custom sf::Texture.
namespace namespace
{ {
@ -29,7 +126,7 @@ namespace
ImVec2 getTopLeftAbsolute(const sf::FloatRect& rect); ImVec2 getTopLeftAbsolute(const sf::FloatRect& rect);
ImVec2 getDownRightAbsolute(const sf::FloatRect& rect); ImVec2 getDownRightAbsolute(const sf::FloatRect& rect);
inline void RenderDrawLists(ImDrawData* draw_data); // rendering callback function prototype void RenderDrawLists(ImDrawData* draw_data); // rendering callback function prototype
// Implementation of ImageButton overload // Implementation of ImageButton overload
bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding, bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding,
@ -42,7 +139,7 @@ namespace ImGui
namespace SFML namespace SFML
{ {
void Init(sf::RenderTarget& target, sf::Texture* fontTexture) void Init(sf::RenderTarget& target, bool loadDefaultFont)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -56,8 +153,12 @@ void Init(sf::RenderTarget& target, sf::Texture* fontTexture)
io.KeyMap[ImGuiKey_PageDown] = sf::Keyboard::PageDown; io.KeyMap[ImGuiKey_PageDown] = sf::Keyboard::PageDown;
io.KeyMap[ImGuiKey_Home] = sf::Keyboard::Home; io.KeyMap[ImGuiKey_Home] = sf::Keyboard::Home;
io.KeyMap[ImGuiKey_End] = sf::Keyboard::End; io.KeyMap[ImGuiKey_End] = sf::Keyboard::End;
#ifdef ANDROID
io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::Delete;
#else
io.KeyMap[ImGuiKey_Delete] = sf::Keyboard::Delete; io.KeyMap[ImGuiKey_Delete] = sf::Keyboard::Delete;
io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::BackSpace; io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::BackSpace;
#endif
io.KeyMap[ImGuiKey_Enter] = sf::Keyboard::Return; io.KeyMap[ImGuiKey_Enter] = sf::Keyboard::Return;
io.KeyMap[ImGuiKey_Escape] = sf::Keyboard::Escape; io.KeyMap[ImGuiKey_Escape] = sf::Keyboard::Escape;
io.KeyMap[ImGuiKey_A] = sf::Keyboard::A; io.KeyMap[ImGuiKey_A] = sf::Keyboard::A;
@ -71,16 +172,15 @@ void Init(sf::RenderTarget& target, sf::Texture* fontTexture)
io.DisplaySize = static_cast<sf::Vector2f>(target.getSize()); io.DisplaySize = static_cast<sf::Vector2f>(target.getSize());
io.RenderDrawListsFn = RenderDrawLists; // set render callback io.RenderDrawListsFn = RenderDrawLists; // set render callback
if (fontTexture == NULL) {
if (s_fontTexture) { // delete previously created texture if (s_fontTexture) { // delete previously created texture
delete s_fontTexture; delete s_fontTexture;
} }
s_fontTexture = new sf::Texture; s_fontTexture = new sf::Texture;
createFontTexture(*s_fontTexture);
setFontTexture(*s_fontTexture); if (loadDefaultFont) {
} else { // this will load default font automatically
setFontTexture(*fontTexture); // No need to call AddDefaultFont
UpdateFontTexture();
} }
} }
@ -90,6 +190,9 @@ void ProcessEvent(const sf::Event& event)
if (s_windowHasFocus) { if (s_windowHasFocus) {
switch (event.type) switch (event.type)
{ {
case sf::Event::MouseMoved:
s_mouseMoved = true;
break;
case sf::Event::MouseButtonPressed: // fall-through case sf::Event::MouseButtonPressed: // fall-through
case sf::Event::MouseButtonReleased: case sf::Event::MouseButtonReleased:
{ {
@ -100,6 +203,17 @@ void ProcessEvent(const sf::Event& event)
} }
} }
break; break;
case sf::Event::TouchBegan: // fall-through
case sf::Event::TouchEnded:
{
s_mouseMoved = false;
int button = event.touch.finger;
if (event.type == sf::Event::TouchBegan &&
button >= 0 && button < 3) {
s_touchDown[event.touch.finger] = true;
}
}
break;
case sf::Event::MouseWheelMoved: case sf::Event::MouseWheelMoved:
io.MouseWheel += static_cast<float>(event.mouseWheel.delta); io.MouseWheel += static_cast<float>(event.mouseWheel.delta);
break; break;
@ -140,7 +254,16 @@ void Update(sf::RenderWindow& window, sf::Time dt)
void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt) void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt)
{ {
if (!s_mouseMoved)
{
if (sf::Touch::isDown(0))
s_touchPos = sf::Touch::getPosition(0, window);
Update(s_touchPos, static_cast<sf::Vector2f>(target.getSize()), dt);
} else {
Update(sf::Mouse::getPosition(window), static_cast<sf::Vector2f>(target.getSize()), dt); Update(sf::Mouse::getPosition(window), static_cast<sf::Vector2f>(target.getSize()), dt);
}
window.setMouseCursorVisible(!ImGui::GetIO().MouseDrawCursor); // don't draw mouse cursor if ImGui draws it window.setMouseCursorVisible(!ImGui::GetIO().MouseDrawCursor); // don't draw mouse cursor if ImGui draws it
} }
@ -152,16 +275,38 @@ void Update(const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::T
if (s_windowHasFocus) { if (s_windowHasFocus) {
io.MousePos = mousePos; io.MousePos = mousePos;
for (int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; i++) {
io.MouseDown[i] = s_mousePressed[i] || sf::Mouse::isButtonPressed((sf::Mouse::Button)i); io.MouseDown[i] = s_touchDown[i] || sf::Touch::isDown(i) || s_mousePressed[i] || sf::Mouse::isButtonPressed((sf::Mouse::Button)i);
s_mousePressed[i] = false; s_mousePressed[i] = false;
s_touchDown[i] = false;
} }
} }
#ifdef ANDROID
#ifdef USE_JNI
if (io.WantTextInput && !s_wantTextInput)
{
openKeyboardIME();
s_wantTextInput = true;
}
if (!io.WantTextInput && s_wantTextInput)
{
closeKeyboardIME();
s_wantTextInput = false;
}
#endif
#endif
assert(io.Fonts->Fonts.Size > 0); // You forgot to create and set up font atlas (see createFontTexture) assert(io.Fonts->Fonts.Size > 0); // You forgot to create and set up font atlas (see createFontTexture)
ImGui::NewFrame(); ImGui::NewFrame();
} }
void Render(sf::RenderTarget& target)
{
target.resetGLStates();
ImGui::Render();
}
void Shutdown() void Shutdown()
{ {
ImGui::GetIO().Fonts->TexID = NULL; ImGui::GetIO().Fonts->TexID = NULL;
@ -171,31 +316,31 @@ void Shutdown()
s_fontTexture = NULL; s_fontTexture = NULL;
} }
ImGui::Shutdown(); // need to specify namespace here, otherwise ImGui::SFML::Shutdown would be called //ImGui::Shutdown(); // need to specify namespace here, otherwise ImGui::SFML::Shutdown would be called
} }
void createFontTexture(sf::Texture& texture) void UpdateFontTexture()
{ {
sf::Texture& texture = *s_fontTexture;
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels; unsigned char* pixels;
int width, height; int width, height;
ImGuiIO& io = ImGui::GetIO();
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
texture.create(width, height); texture.create(width, height);
texture.update(pixels); texture.update(pixels);
io.Fonts->TexID = (void*)texture.getNativeHandle();
io.Fonts->ClearInputData(); io.Fonts->ClearInputData();
io.Fonts->ClearTexData(); io.Fonts->ClearTexData();
} }
void setFontTexture(sf::Texture& texture) sf::Texture& GetFontTexture()
{ {
ImGui::GetIO().Fonts->TexID = (void*)texture.getNativeHandle(); return *s_fontTexture;
if (&texture != s_fontTexture) { // internal texture is not needed anymore
delete s_fontTexture;
s_fontTexture = NULL;
}
} }
} // end of namespace SFML } // end of namespace SFML
@ -218,7 +363,7 @@ void Image(const sf::Texture& texture, const sf::Vector2f& size,
void Image(const sf::Texture& texture, const sf::FloatRect& textureRect, void Image(const sf::Texture& texture, const sf::FloatRect& textureRect,
const sf::Color& tintColor, const sf::Color& borderColor) const sf::Color& tintColor, const sf::Color& borderColor)
{ {
Image(texture, sf::Vector2f(textureRect.width, textureRect.height), textureRect, tintColor, borderColor); Image(texture, sf::Vector2f(std::abs(textureRect.width), std::abs(textureRect.height)), textureRect, tintColor, borderColor);
} }
void Image(const sf::Texture& texture, const sf::Vector2f& size, const sf::FloatRect& textureRect, void Image(const sf::Texture& texture, const sf::Vector2f& size, const sf::FloatRect& textureRect,
@ -302,7 +447,7 @@ void DrawRectFilled(const sf::FloatRect& rect, const sf::Color& color,
float rounding, int rounding_corners) float rounding, int rounding_corners)
{ {
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRect( draw_list->AddRectFilled(
getTopLeftAbsolute(rect), getTopLeftAbsolute(rect),
getDownRightAbsolute(rect), getDownRightAbsolute(rect),
ColorConvertFloat4ToU32(color), rounding, rounding_corners); ColorConvertFloat4ToU32(color), rounding, rounding_corners);
@ -312,6 +457,7 @@ void DrawRectFilled(const sf::FloatRect& rect, const sf::Color& color,
namespace namespace
{ {
ImVec2 getTopLeftAbsolute(const sf::FloatRect & rect) ImVec2 getTopLeftAbsolute(const sf::FloatRect & rect)
{ {
ImVec2 pos = ImGui::GetCursorScreenPos(); ImVec2 pos = ImGui::GetCursorScreenPos();
@ -326,6 +472,7 @@ ImVec2 getDownRightAbsolute(const sf::FloatRect & rect)
// Rendering callback // Rendering callback
void RenderDrawLists(ImDrawData* draw_data) void RenderDrawLists(ImDrawData* draw_data)
{ {
if (draw_data->CmdListsCount == 0) { if (draw_data->CmdListsCount == 0) {
return; return;
} }
@ -339,32 +486,43 @@ void RenderDrawLists(ImDrawData* draw_data)
if (fb_width == 0 || fb_height == 0) { return; } if (fb_width == 0 || fb_height == 0) { return; }
draw_data->ScaleClipRects(io.DisplayFramebufferScale); draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Save OpenGL state
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
#ifdef GL_VERSION_ES_CL_1_1
GLint last_program, last_texture, last_array_buffer, last_element_array_buffer;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
#else
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
#endif
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity(); glLoadIdentity();
#ifdef GL_VERSION_ES_CL_1_1
glOrthof(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f);
#else
glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f);
#endif
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity(); glLoadIdentity();
for (int n = 0; n < draw_data->CmdListsCount; ++n) { for (int n = 0; n < draw_data->CmdListsCount; ++n) {
@ -390,18 +548,14 @@ void RenderDrawLists(ImDrawData* draw_data)
idx_buffer += pcmd->ElemCount; idx_buffer += pcmd->ElemCount;
} }
} }
#ifdef GL_VERSION_ES_CL_1_1
// Restore modified state glBindTexture(GL_TEXTURE_2D, last_texture);
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glMatrixMode(GL_TEXTURE); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
glPopMatrix(); glDisable(GL_SCISSOR_TEST);
glMatrixMode(GL_MODELVIEW); #else
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib(); glPopAttrib();
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); #endif
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
} }
bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding, bool imageButtonImpl(const sf::Texture& texture, const sf::FloatRect& textureRect, const sf::Vector2f& size, const int framePadding,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save