mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-13 16:29:54 +02:00
Compare commits
63 Commits
Author | SHA1 | Date | |
---|---|---|---|
d17a586738 | |||
710b9b68b1 | |||
29ba288ea0 | |||
882072cf30 | |||
7bd507d266 | |||
1ff104641a | |||
3b8d1ec207 | |||
e9e1fd2b3c | |||
6062d18cf9 | |||
05f0993616 | |||
6dd2b13220 | |||
5864c45fe3 | |||
4bc3642bdb | |||
a3f32381c4 | |||
67f17a644c | |||
e807d97089 | |||
23d156908d | |||
42d4b4be6a | |||
efc473df98 | |||
bbda899801 | |||
a17885f470 | |||
7de89e0da3 | |||
7c61822d26 | |||
ca027e1754 | |||
c5dacee3a7 | |||
d6f6afabb3 | |||
76a39ad224 | |||
926f7bfcc5 | |||
f6414f2011 | |||
931a4c5b49 | |||
c32221fa20 | |||
a165954a69 | |||
ddf8b280e9 | |||
969b1e0563 | |||
6e15b71663 | |||
f5dbb0a973 | |||
ade21a1ad5 | |||
868ba05a13 | |||
152878571e | |||
fa0aa5ace6 | |||
6267905a17 | |||
1509b8f634 | |||
2bc6346b48 | |||
9169b2911c | |||
a4b96445e8 | |||
6c11d7623e | |||
f33eb89018 | |||
a8d3b045b7 | |||
a830037eab | |||
309ff44579 | |||
f30d23a502 | |||
a905505cca | |||
46eee0cee4 | |||
29863b55ef | |||
530f103dfe | |||
7a3e6aa38d | |||
cda3aecc6a | |||
b6d1d85d86 | |||
9a426faf4f | |||
b0d5600ffb | |||
c52a54ef43 | |||
cc9d63b46a | |||
d3ad5ce475 |
26
README.md
26
README.md
@ -1,11 +1,13 @@
|
||||
ImGui
|
||||
=====
|
||||
|
||||
ImGui is a bloat-free graphical user interface library for C++. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
|
||||
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
|
||||
|
||||
ImGui is designed to allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
|
||||
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
|
||||
|
||||
After ImGui is setup in your application, you can use it like in this example:
|
||||
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
|
||||
|
||||
After ImGui is setup in your engine, you can use it like in this example:
|
||||
|
||||

|
||||
|
||||
@ -28,6 +30,22 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
|
||||
- [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/).
|
||||
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861).
|
||||
|
||||
Frequently Asked Question
|
||||
-------------------------
|
||||
<b>How do you use ImGui on a platform that may not have a mouse and keyboard?</b>
|
||||
|
||||
I recommend using [Synergy](http://synergy-project.org) and the uSynergy.c micro client to share your mouse and keyboard. This way you can seemingly use your PC input devices on a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
|
||||
|
||||
<b>Can you create elaborate/serious tools with ImGui?</b>
|
||||
|
||||
Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. There's no reason you cannot, and in my experience the simplicity of the API is very empowering. However note that ImGui is very programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential.
|
||||
|
||||
<b>Can you reskin the look of ImGui?</b>
|
||||
|
||||
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a more compact UI with different colors:
|
||||
|
||||

|
||||
|
||||
|
||||
Credits
|
||||
-------
|
||||
@ -36,7 +54,7 @@ Developed by [Omar Cornut](http://www.miracleworld.net). The library was develop
|
||||
|
||||
Embeds [proggy_clean](http://www.proggyfonts.net/) font by Tristan Grimmer (also MIT license).
|
||||
|
||||
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Matt Willis. Thanks!
|
||||
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks!
|
||||
|
||||
License
|
||||
-------
|
||||
|
@ -5,147 +5,98 @@
|
||||
#include <dinput.h>
|
||||
#include "../../imgui.h"
|
||||
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
|
||||
static HWND hWnd;
|
||||
static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
|
||||
static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
|
||||
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
|
||||
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
|
||||
static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture
|
||||
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
|
||||
static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
D3DXVECTOR3 position;
|
||||
D3DCOLOR color;
|
||||
float tu, tv;
|
||||
D3DXVECTOR3 position;
|
||||
D3DCOLOR color;
|
||||
float tu, tv;
|
||||
};
|
||||
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
|
||||
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structuer)
|
||||
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
|
||||
{
|
||||
size_t total_vtx_count = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
|
||||
if (total_vtx_count == 0)
|
||||
return;
|
||||
size_t total_vtx_count = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
|
||||
if (total_vtx_count == 0)
|
||||
return;
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
CUSTOMVERTEX* vtx_dst;
|
||||
if (g_pVB->Lock(0, total_vtx_count, (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||
return;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
vtx_dst->position.x = vtx_src->pos.x;
|
||||
vtx_dst->position.y = vtx_src->pos.y;
|
||||
vtx_dst->position.z = 0.0f;
|
||||
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->tu = vtx_src->uv.x;
|
||||
vtx_dst->tv = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
}
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
vtx_dst->position.x = vtx_src->pos.x;
|
||||
vtx_dst->position.y = vtx_src->pos.y;
|
||||
vtx_dst->position.z = 0.0f;
|
||||
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->tu = vtx_src->uv.x;
|
||||
vtx_dst->tv = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
}
|
||||
g_pVB->Unlock();
|
||||
|
||||
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
|
||||
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
|
||||
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
|
||||
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
|
||||
|
||||
// Setup render state: alpha-blending, no face culling, no depth testing
|
||||
// Setup render state: alpha-blending, no face culling, no depth testing
|
||||
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, false );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
|
||||
|
||||
// Setup texture
|
||||
g_pd3dDevice->SetTexture( 0, g_pTexture );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
||||
// Setup texture
|
||||
g_pd3dDevice->SetTexture( 0, g_pTexture );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
||||
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
||||
|
||||
// Setup orthographic projection matrix
|
||||
D3DXMATRIXA16 mat;
|
||||
D3DXMatrixIdentity(&mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
|
||||
D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
|
||||
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat);
|
||||
// Setup orthographic projection matrix
|
||||
D3DXMATRIXA16 mat;
|
||||
D3DXMatrixIdentity(&mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat);
|
||||
g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
|
||||
D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
|
||||
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat);
|
||||
|
||||
// Render command lists
|
||||
int vtx_offset = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
// Render command list
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
|
||||
g_pd3dDevice->SetScissorRect(&r);
|
||||
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
|
||||
vtx_offset += pcmd->vtx_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get text data in Win32 clipboard
|
||||
static const char* ImImpl_GetClipboardTextFn()
|
||||
{
|
||||
static char* buf_local = NULL;
|
||||
if (buf_local)
|
||||
{
|
||||
free(buf_local);
|
||||
buf_local = NULL;
|
||||
}
|
||||
|
||||
if (!OpenClipboard(NULL))
|
||||
return NULL;
|
||||
|
||||
HANDLE buf_handle = GetClipboardData(CF_TEXT);
|
||||
if (buf_handle == NULL)
|
||||
return NULL;
|
||||
|
||||
if (char* buf_global = (char*)GlobalLock(buf_handle))
|
||||
buf_local = strdup(buf_global);
|
||||
GlobalUnlock(buf_handle);
|
||||
CloseClipboard();
|
||||
|
||||
return buf_local;
|
||||
}
|
||||
|
||||
// Set text data in Win32 clipboard
|
||||
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
|
||||
{
|
||||
if (!OpenClipboard(NULL))
|
||||
return;
|
||||
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
|
||||
const int buf_length = (text_end - text) + 1;
|
||||
HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char));
|
||||
if (buf_handle == NULL)
|
||||
return;
|
||||
|
||||
char* buf_global = (char *)GlobalLock(buf_handle);
|
||||
memcpy(buf_global, text, text_end - text);
|
||||
buf_global[text_end - text] = 0;
|
||||
GlobalUnlock(buf_handle);
|
||||
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_TEXT, buf_handle);
|
||||
CloseClipboard();
|
||||
// Render command lists
|
||||
int vtx_offset = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
// Render command list
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
|
||||
g_pd3dDevice->SetScissorRect(&r);
|
||||
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
|
||||
vtx_offset += pcmd->vtx_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT InitD3D(HWND hWnd)
|
||||
@ -160,7 +111,7 @@ HRESULT InitD3D(HWND hWnd)
|
||||
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.EnableAutoDepthStencil = TRUE;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
// Create the D3DDevice
|
||||
if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice) < 0)
|
||||
@ -183,92 +134,119 @@ void Cleanup()
|
||||
|
||||
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
io.MouseDown[0] = true;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
io.MouseDown[0] = false;
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
io.MouseDown[1] = true;
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
io.MouseDown[1] = false;
|
||||
return true;
|
||||
case WM_MOUSEWHEEL:
|
||||
// Mouse wheel: -1,0,+1
|
||||
io.MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1 : -1;
|
||||
return true;
|
||||
case WM_MOUSEMOVE:
|
||||
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MousePos.x = (signed short)(lParam);
|
||||
io.MousePos.y = (signed short)(lParam >> 16);
|
||||
return true;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 1 && wParam < 256)
|
||||
io.AddInputCharacter((char)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Cleanup();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
io.MouseDown[0] = true;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
io.MouseDown[0] = false;
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
io.MouseDown[1] = true;
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
io.MouseDown[1] = false;
|
||||
return true;
|
||||
case WM_MOUSEWHEEL:
|
||||
// Mouse wheel: -1,0,+1
|
||||
io.MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1 : -1;
|
||||
return true;
|
||||
case WM_MOUSEMOVE:
|
||||
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MousePos.x = (signed short)(lParam);
|
||||
io.MousePos.y = (signed short)(lParam >> 16);
|
||||
return true;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 1 && wParam < 256)
|
||||
io.AddInputCharacter((char)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Cleanup();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
void InitImGui()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
|
||||
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
|
||||
// Create the vertex buffer
|
||||
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
// Create the vertex buffer
|
||||
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load font texture
|
||||
const void* png_data;
|
||||
unsigned int png_size;
|
||||
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
|
||||
if (D3DXCreateTextureFromFileInMemory(g_pd3dDevice, png_data, png_size, &g_pTexture) < 0)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
// Load font texture
|
||||
const void* png_data;
|
||||
unsigned int png_size;
|
||||
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
|
||||
if (D3DXCreateTextureFromFileInMemory(g_pd3dDevice, png_data, png_size, &g_pTexture) < 0)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
INT64 ticks_per_second = 0;
|
||||
INT64 time = 0;
|
||||
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
|
||||
time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
// (we already got mouse position, buttons, wheel from the window message callback)
|
||||
BYTE keystate[256];
|
||||
GetKeyboardState(keystate);
|
||||
for (int i = 0; i < 256; i++)
|
||||
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
|
||||
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
|
||||
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
|
||||
// io.MousePos : filled by WM_MOUSEMOVE event
|
||||
// io.MouseDown : filled by WM_*BUTTON* events
|
||||
// io.MouseWheel : filled by WM_MOUSEWHEEL events
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
@ -280,104 +258,94 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
// Create the application's window
|
||||
hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX9 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
INT64 ticks_per_second, time;
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
|
||||
return 1;
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
|
||||
return 1;
|
||||
|
||||
// Initialize Direct3D
|
||||
if (InitD3D(hWnd) >= 0)
|
||||
// Initialize Direct3D
|
||||
if (InitD3D(hWnd) < 0)
|
||||
{
|
||||
// Show the window
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
InitImGui();
|
||||
|
||||
// Enter the message loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1) ImGui start frame, setup time delta & inputs
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
|
||||
time = current_time;
|
||||
BYTE keystate[256];
|
||||
GetKeyboardState(keystate);
|
||||
for (int i = 0; i < 256; i++)
|
||||
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
|
||||
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
|
||||
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
|
||||
// io.MousePos : filled by WM_MOUSEMOVE event
|
||||
// io.MouseDown : filled by WM_*BUTTON* events
|
||||
// io.MouseWheel : filled by WM_MOUSEWHEEL events
|
||||
ImGui::NewFrame();
|
||||
|
||||
// 2) ImGui usage
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
|
||||
if (show_test_window)
|
||||
{
|
||||
// More example code in ShowTestWindow()
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3) Rendering
|
||||
// Clear frame buffer
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
|
||||
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0);
|
||||
if (g_pd3dDevice->BeginScene() >= 0)
|
||||
{
|
||||
// Render ImGui
|
||||
ImGui::Render();
|
||||
g_pd3dDevice->EndScene();
|
||||
}
|
||||
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
ImGui::Shutdown();
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
// Show the window
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
InitImGui();
|
||||
|
||||
// Enter the message loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateImGui();
|
||||
|
||||
// Create a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
|
||||
// Show the ImGui test window
|
||||
// Most of user example code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
// Show another simple window
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Rendering
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
|
||||
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0);
|
||||
if (g_pd3dDevice->BeginScene() >= 0)
|
||||
{
|
||||
ImGui::Render();
|
||||
g_pd3dDevice->EndScene();
|
||||
}
|
||||
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
ImGui::Shutdown();
|
||||
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 0;
|
||||
|
@ -5,7 +5,8 @@
|
||||
#
|
||||
|
||||
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
|
||||
#CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
|
||||
CXXFLAGS+=-I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/Cellar/glfw3/3.0.4/include
|
||||
CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
|
||||
CXXFLAGS+=-lglew -lglfw3
|
||||
CXXFLAGS+=-I../../
|
||||
CXXFLAGS+= -D__APPLE__
|
||||
|
@ -2,10 +2,10 @@
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h" // for .png loading
|
||||
#include "stb_image.h" // for .png loading
|
||||
#include "../../imgui.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#endif
|
||||
|
||||
static GLFWwindow* window;
|
||||
@ -16,234 +16,256 @@ static GLuint fontTex;
|
||||
// A faster way would be to collate all vertices from all cmd_lists into a single vertex buffer
|
||||
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
|
||||
{
|
||||
if (cmd_lists_count == 0)
|
||||
return;
|
||||
if (cmd_lists_count == 0)
|
||||
return;
|
||||
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
//glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
// Bind texture
|
||||
glBindTexture(GL_TEXTURE_2D, fontTex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// Setup texture
|
||||
glBindTexture(GL_TEXTURE_2D, fontTex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Setup matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
// Setup orthographic projection matrix
|
||||
const float width = ImGui::GetIO().DisplaySize.x;
|
||||
const float height = ImGui::GetIO().DisplaySize.y;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const unsigned char* vtx_buffer = (const unsigned char*)cmd_list->vtx_buffer.begin();
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer+8));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer+16));
|
||||
// Render command lists
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const unsigned char* vtx_buffer = (const unsigned char*)cmd_list->vtx_buffer.begin();
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer+8));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer+16));
|
||||
|
||||
int vtx_offset = 0;
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
glScissor((int)pcmd->clip_rect.x, (int)pcmd->clip_rect.y, (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
|
||||
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
|
||||
vtx_offset += pcmd->vtx_count;
|
||||
}
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
int vtx_offset = 0;
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
{
|
||||
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
|
||||
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
|
||||
vtx_offset += pcmd->vtx_count;
|
||||
}
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
static const char* ImImpl_GetClipboardTextFn()
|
||||
{
|
||||
return glfwGetClipboardString(window);
|
||||
return glfwGetClipboardString(window);
|
||||
}
|
||||
|
||||
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
|
||||
// Add a zero-terminator because glfw function doesn't take a size
|
||||
char* buf = (char*)malloc(text_end - text + 1);
|
||||
memcpy(buf, text, text_end-text);
|
||||
buf[text_end-text] = '\0';
|
||||
glfwSetClipboardString(window, buf);
|
||||
free(buf);
|
||||
if (*text_end == 0)
|
||||
{
|
||||
// Already got a zero-terminator at 'text_end', we don't need to add one
|
||||
glfwSetClipboardString(window, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a zero-terminator because glfw function doesn't take a size
|
||||
char* buf = (char*)malloc(text_end - text + 1);
|
||||
memcpy(buf, text, text_end-text);
|
||||
buf[text_end-text] = '\0';
|
||||
glfwSetClipboardString(window, buf);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GLFW callbacks to get events
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fputs(description, stderr);
|
||||
fputs(description, stderr);
|
||||
}
|
||||
|
||||
static float mouse_wheel = 0.0f;
|
||||
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
mouse_wheel = (float)yoffset;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
|
||||
}
|
||||
|
||||
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (action == GLFW_PRESS)
|
||||
io.KeysDown[key] = true;
|
||||
if (action == GLFW_RELEASE)
|
||||
io.KeysDown[key] = false;
|
||||
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (action == GLFW_PRESS)
|
||||
io.KeysDown[key] = true;
|
||||
if (action == GLFW_RELEASE)
|
||||
io.KeysDown[key] = false;
|
||||
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
}
|
||||
|
||||
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
|
||||
{
|
||||
if (c > 0 && c <= 255)
|
||||
ImGui::GetIO().AddInputCharacter((char)c);
|
||||
if (c > 0 && c <= 255)
|
||||
ImGui::GetIO().AddInputCharacter((char)c);
|
||||
}
|
||||
|
||||
// OpenGL code based on http://open.gl tutorials
|
||||
void InitGL()
|
||||
{
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(1);
|
||||
if (!glfwInit())
|
||||
exit(1);
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetKeyCallback(window, glfw_key_callback);
|
||||
glfwSetScrollCallback(window, glfw_scroll_callback);
|
||||
glfwSetCharCallback(window, glfw_char_callback);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetKeyCallback(window, glfw_key_callback);
|
||||
glfwSetScrollCallback(window, glfw_scroll_callback);
|
||||
glfwSetCharCallback(window, glfw_char_callback);
|
||||
|
||||
glewInit();
|
||||
glewInit();
|
||||
}
|
||||
|
||||
void InitImGui()
|
||||
{
|
||||
int w, h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
int w, h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)w, (float)h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.5f; // Align OpenGL texels
|
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
||||
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
||||
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
||||
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)w, (float)h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.5f; // Align OpenGL texels
|
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
||||
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
||||
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
||||
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
||||
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
||||
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
|
||||
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
|
||||
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
|
||||
|
||||
// Load font texture
|
||||
glGenTextures(1, &fontTex);
|
||||
glBindTexture(GL_TEXTURE_2D, fontTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
const void* png_data;
|
||||
unsigned int png_size;
|
||||
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
|
||||
int tex_x, tex_y, tex_comp;
|
||||
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
||||
stbi_image_free(tex_data);
|
||||
// Load font texture
|
||||
glGenTextures(1, &fontTex);
|
||||
glBindTexture(GL_TEXTURE_2D, fontTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
const void* png_data;
|
||||
unsigned int png_size;
|
||||
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
|
||||
int tex_x, tex_y, tex_comp;
|
||||
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
||||
stbi_image_free(tex_data);
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGui::Shutdown();
|
||||
glfwTerminate();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
static double time = 0.0f;
|
||||
const double current_time = glfwGetTime();
|
||||
io.DeltaTime = (float)(current_time - time);
|
||||
time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
|
||||
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
// Application code
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
InitGL();
|
||||
InitImGui();
|
||||
InitGL();
|
||||
InitImGui();
|
||||
|
||||
double time = glfwGetTime();
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
glfwPollEvents();
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = 0;
|
||||
glfwPollEvents();
|
||||
UpdateImGui();
|
||||
|
||||
// 1) ImGui start frame, setup time delta & inputs
|
||||
const double current_time = glfwGetTime();
|
||||
io.DeltaTime = (float)(current_time - time);
|
||||
time = current_time;
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
|
||||
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
|
||||
io.MouseWheel = (mouse_wheel != 0) ? mouse_wheel > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
|
||||
mouse_wheel = 0.0f;
|
||||
ImGui::NewFrame();
|
||||
// Create a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// 2) ImGui usage
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
// Show the ImGui test window
|
||||
// Most of user example code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
if (show_test_window)
|
||||
{
|
||||
// More example code in ShowTestWindow()
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
// Show another simple window
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
// Rendering
|
||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui::Render();
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
// 3) Rendering
|
||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui::Render();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
Shutdown();
|
||||
return 0;
|
||||
ImGui::Shutdown();
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
39
imconfig.h
39
imconfig.h
@ -4,31 +4,38 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
//----- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
|
||||
//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
|
||||
//#include <vector>
|
||||
//#define ImVector std::vector
|
||||
//#define ImVector MyVector
|
||||
//#define ImVector std::vector
|
||||
//#define ImVector MyVector
|
||||
|
||||
//----- Define assertion handler. Default to calling assert().
|
||||
// #define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
|
||||
//----- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
|
||||
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
|
||||
|
||||
//---- If you are loading a custom font, ImGui expect to find a pure white pixel at (0,0)
|
||||
// Change it's UV coordinate here if you can't have a white pixel at (0,0)
|
||||
//#define IMGUI_FONT_TEX_UV_FOR_WHITE ImVec2(0.f/256.f,0.f/256.f)
|
||||
|
||||
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//----- Freely implement extra functions within the ImGui:: namespace.
|
||||
//----- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
|
||||
//---- Freely implement extra functions within the ImGui:: namespace.
|
||||
//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL);
|
||||
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
|
||||
void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL);
|
||||
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
|
||||
};
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
// stb_textedit.h - v1.3 - public domain - Sean Barrett
|
||||
// stb_textedit.h - v1.4 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
//
|
||||
// This C header file implements the guts of a multi-line text-editing
|
||||
@ -30,8 +30,9 @@
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.3 (2013-06-19) fix mouse clicking to round to nearest char boundary
|
||||
// 1.2 (2013-05-27) fix some RAD types that had crept into the new code
|
||||
// 1.4 (2014-08-17) fix signed/unsigned warnings
|
||||
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
|
||||
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code
|
||||
// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE )
|
||||
// 1.0 (2012-07-26) improve documentation, initial public release
|
||||
// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode
|
||||
@ -41,7 +42,7 @@
|
||||
// ADDITIONAL CONTRIBUTORS
|
||||
//
|
||||
// Ulf Winklemann: move-by-word in 1.1
|
||||
// Scott Graham: mouse selectiom bugfix in 1.3
|
||||
// Scott Graham: mouse selection bugfix in 1.3
|
||||
//
|
||||
// USAGE
|
||||
//
|
||||
@ -445,7 +446,7 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
|
||||
typedef struct
|
||||
@ -649,7 +650,7 @@ static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
stb_textedit_delete_selection(str,state);
|
||||
// try to insert the characters
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
|
||||
stb_text_makeundo_insert(str, state, state->cursor, len);
|
||||
stb_text_makeundo_insert(state, state->cursor, len);
|
||||
state->cursor += len;
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
@ -684,7 +685,7 @@ retry:
|
||||
} else {
|
||||
stb_textedit_delete_selection(str,state); // implicity clamps
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
stb_text_makeundo_insert(str, state, state->cursor, 1);
|
||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
@ -1007,13 +1008,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
|
||||
memmove(state->undo_char, state->undo_char + n, state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE));
|
||||
memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
|
||||
}
|
||||
--state->undo_point;
|
||||
memmove(state->undo_rec, state->undo_rec+1, state->undo_point*sizeof(state->undo_rec[0]));
|
||||
memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1031,13 +1032,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE));
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
|
||||
}
|
||||
++state->redo_point;
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]));
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,7 +1204,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
s->redo_point++;
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_insert(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
stb_text_createundo(&state->undostate, where, 0, length);
|
||||
}
|
||||
|
BIN
web/skinning_sample_01.png
Normal file
BIN
web/skinning_sample_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Reference in New Issue
Block a user