Previous 199869 Revisions Next

r36358 Tuesday 10th March, 2015 at 07:05:28 UTC by Miodrag Milanović
update 3rdparty libs
[3rdparty/bgfx]README.md
[3rdparty/bgfx/3rdparty/ib-compress]writebitstream.h
[3rdparty/bgfx/3rdparty/ocornut-imgui]imconfig.h imgui.cpp imgui.h
[3rdparty/bgfx/examples/common/entry]entry.cpp entry.h entry_android.cpp entry_asmjs.cpp entry_ios.mm entry_nacl.cpp entry_osx.mm entry_p.h entry_qnx.cpp entry_sdl.cpp entry_windows.cpp entry_winrt.cpp entry_x11.cpp
[3rdparty/bgfx/examples/common/imgui]ocornut_imgui.cpp
[3rdparty/bgfx/scripts]bgfx.lua
[3rdparty/bx/include/bx]handlealloc.h
[3rdparty/genie]README.md
[3rdparty/genie/src/actions/make]make_cpp.lua
[3rdparty/genie/src/host]premake.c scripts.c
[3rdparty/mongoose]mongoose.c
[3rdparty/mongoose/docs]API.md
[3rdparty/mongoose/examples/multi_threaded_server]Makefile
[3rdparty/mongoose/examples/proxy_server]Makefile
[3rdparty/mongoose/examples/web_server]Makefile web_server.c
[3rdparty/mongoose/examples/web_server/certs]cert.pem*
[3rdparty/mongoose/examples/websocket_ssl_proxy]Makefile

trunk/3rdparty/bgfx/3rdparty/ib-compress/writebitstream.h
r244869r244870
3434#define WBS_INLINE __forceinline
3535#else
3636#define WBS_INLINE inline
37#endif
37#endif
3838
39// Very simple bitstream for writing that will grow to accomodate written bits.
39// Very simple bitstream for writing that will grow to accomodate written bits.
4040class WriteBitstream
4141{
4242public:
4343
44    // Construct the bit stream with an initial buffer capacity - should be a multiple of 8 and > 0
44    // Construct the bit stream with an initial buffer capacity - should be a multiple of 8 and > 0
4545    WriteBitstream( size_t initialBufferCapacity = 16 )
4646    {
4747        m_bufferCursor =
r244869r244870
6666    // Write a V int to the stream.
6767    void WriteVInt( uint32_t value );
6868
69    // Get the size in bytes
69    // Get the size in bytes
7070    size_t ByteSize() const { return ( m_size + 7 ) >> 3; }
7171
7272    // Finish writing by flushing the buffer.
r244869r244870
8080    // If we need to grow the buffer.
8181    void GrowBuffer();
8282
83    // Not copyable
83    // Not copyable
8484    WriteBitstream( const WriteBitstream& );
8585
8686    // Not assignable
r244869r244870
9696
9797WBS_INLINE void WriteBitstream::Write( uint32_t value, uint32_t bitCount )
9898{
99    m_bitBuffer |= ( static_cast<uint64_t>( value ) << ( 64 - m_bitsLeft ) ) & ( m_bitsLeft == 0 ? 0 : 0xFFFFFFFFFFFFFFFF );
99    m_bitBuffer |= ( static_cast<uint64_t>( value ) << ( 64 - m_bitsLeft ) ) & ( m_bitsLeft == 0 ? 0 : UINT64_C(0xFFFFFFFFFFFFFFFF) );
100100
101101    if ( bitCount > m_bitsLeft )
102102    {
r244869r244870
175175    m_bufferEnd    = m_buffer + newBufferSize;
176176}
177177
178#endif // -- WRITE_BIT_STREAM_H__
No newline at end of file
178#endif // -- WRITE_BIT_STREAM_H__
trunk/3rdparty/bgfx/3rdparty/ocornut-imgui/imconfig.h
r244869r244870
1414//---- Define assertion handler. Defaults to calling assert().
1515//#define IM_ASSERT(_EXPR)  MyAssert(_EXPR)
1616
17//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
17//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows.
18//#define IMGUI_API __declspec( dllexport )
19//#define IMGUI_API __declspec( dllimport )
20
21//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
1822//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
23//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS
1924
2025//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
2126//#define IMGUI_INCLUDE_IMGUI_USER_INL
r244869r244870
3641
3742//---- Freely implement extra functions within the ImGui:: namespace.
3843//---- Declare helpers or widgets implemented in imgui_user.inl or elsewhere, so end-user doesn't need to include multiple files.
39//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
44//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers.
4045/*
4146namespace ImGui
4247{
trunk/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
r244869r244870
1// ImGui library v1.32 wip
1// ImGui library v1.35
22// See ImGui::ShowTestWindow() for sample code.
33// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
44// Get latest version at https://github.com/ocornut/imgui
r244869r244870
99 Index
1010 - MISSION STATEMENT
1111 - END-USER GUIDE
12 - PROGRAMMER GUIDE
13 - API BREAKING CHANGES
14 - TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS
12 - PROGRAMMER GUIDE (read me!)
13 - API BREAKING CHANGES (read me when you update!)
14 - FREQUENTLY ASKED QUESTIONS (FAQ) & TROUBLESHOOTING (read me!)
1515 - ISSUES & TODO-LIST
1616 - CODE
1717 - SAMPLE CODE
r244869r244870
2727 - minimize screen real-estate usage
2828 - minimize setup and maintenance
2929 - minimize state storage on user side
30 - portable, minimize dependencies, run on target (consoles, etc.)
30 - portable, minimize dependencies, run on target (consoles, phones, etc.)
3131 - efficient runtime (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything)
32 - read about immediate-mode GUI principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html
32 - read about immediate-mode gui principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html
3333
3434 Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes:
3535 - doesn't look fancy, doesn't animate
3636 - limited layout features, intricate layouts are typically crafted in code
37 - occasionally use statically sized buffers for string manipulations - won't crash, but some long text may be clipped
37 - occasionally uses statically sized buffers for string manipulations - won't crash, but some long text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction.
3838
3939
4040 END-USER GUIDE
r244869r244870
6363 PROGRAMMER GUIDE
6464 ================
6565
66 - your code creates the UI, if your code doesn't run the UI is gone! == dynamic UI, no construction step, less data retention on your side, no state duplication, less sync, less errors.
67 - call and read ImGui::ShowTestWindow() for user-side sample code
66 - read the FAQ below this section!
67 - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs.
68 - call and read ImGui::ShowTestWindow() for sample code demonstrating most features.
6869 - see examples/ folder for standalone sample applications.
6970 - customization: use the style editor or PushStyleColor/PushStyleVar to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme).
7071
71
7272 - getting started:
7373   - initialisation: call ImGui::GetIO() and fill the 'Settings' data.
7474   - every frame:
r244869r244870
9696        // TODO: store your texture pointer/identifier in 'io.Fonts->TexID'
9797
9898        // Application main loop
99        for (;;)
99        while (true)
100100        {
101101            // 1) get low-level input
102102            // e.g. on Win32, GetKeyboardState(), or poll your events, etc.
r244869r244870
129129 Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
130130 Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
131131
132 - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth
133 - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond), kept inline redirection function.
134 - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once.
135 - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now.
132136 - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior
133137 - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
134138 - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
r244869r244870
164168 - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes
165169
166170
167 TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS
168 ============================================
171 FREQUENTLY ASKED QUESTIONS (FAQ) & TROUBLESHOOTING
172 ==================================================
169173
170174 If text or lines are blurry when integrating ImGui in your engine:
175
171176   - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
172177
173 If you are confused about the meaning or use of ID in ImGui:
174   - many widgets requires state to be carried over multiple frames (most typically ImGui often wants remember what is the "active" widget).
175     to do so they need an unique ID. unique ID are typically derived from a string label, an indice or a pointer.
176     when you call Button("OK") the button shows "OK" and also use "OK" as an ID.
178 A primer on the meaning and use of ID in ImGui:
179
180   - widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget).
181     to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer.
182
183       Button("OK");        // Label = "OK",     ID = hash of "OK"
184       Button("Cancel");    // Label = "Cancel", ID = hash of "Cancel"
185
177186   - ID are uniquely scoped within Windows so no conflict can happen if you have two buttons called "OK" in two different Windows.
178     within a same Window, use PushID() / PopID() to easily create scopes and avoid ID conflicts.
179     so if you have a loop creating "multiple" items, you can use PushID() / PopID() with the index of each item, or their pointer, etc.
180     some functions like TreeNode() implicitly creates a scope for you by calling PushID()
181   - when dealing with trees, ID are important because you want to preserve the opened/closed state of tree nodes.
182     depending on your use cases you may want to use strings, indices or pointers as ID. experiment and see what makes more sense!
183      e.g. When displaying a single object that may change over time, using a static string as ID will preserve your node open/closed state when the targeted object change
184      e.g. When displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state per object
185   - when passing a label you can optionally specify extra unique ID information within the same string using "##". This helps solving the simpler collision cases.
186      e.g. "Label" display "Label" and uses "Label" as ID
187      e.g. "Label##Foobar" display "Label" and uses "Label##Foobar" as ID
188      e.g. "##Foobar" display an empty label and uses "##Foobar" as ID
189   - read articles about immediate-mode ui principles (see web links) to understand the requirement and use of ID.
190187
188   - when passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases.
189     use "##" to pass a complement to the ID that won't be visible to the end-user:
190
191       Button("Play##0");   // Label = "Play",   ID = hash of "Play##0"
192       Button("Play##1");   // Label = "Play",   ID = hash of "Play##1" (different from above)
193
194     use "###" to pass a label that isn't part of ID. You can use that to change labels while preserving a constant ID.
195
196       Button("Hello###ID"; // Label = "Hello",  ID = hash of "ID"
197       Button("World###ID"; // Label = "World",  ID = hash of "ID" (same as above)
198
199   - use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window:
200
201       Button("Click");     // Label = "Click",  ID = hash of "Click"
202       PushID("node");
203       Button("Click");     // Label = "Click",  ID = hash of "node" and "Click"
204       for (int i = 0; i < 100; i++)
205       {
206          PushID(i);
207          Button("Click");  // Label = "Click",  ID = hash of "node" and i and "label"
208          PopID();
209       }
210       PopID();
211       PushID(my_ptr);
212       Button("Click");     // Label = "Click",  ID = hash of ptr and "Click"
213       PopID();
214
215     so if you have a loop creating multiple items, you can use PushID() / PopID() with the index of each item, or their pointer, etc.
216     some functions like TreeNode() implicitly creates a scope for you by calling PushID().
217
218   - when working with trees, ID are used to preserve the opened/closed state of tree nodes.
219     depending on your use cases you may want to use strings, indices or pointers as ID.
220      e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change.
221      e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense!
222
191223 If you want to load a different font than the default (ProggyClean.ttf, size 13)
192224
193225     io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
r244869r244870
204236
205237     io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese());  // Load Japanese characters
206238     io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
239     io.ImeWindowHandle = MY_HWND;      // To input using Microsoft IME, give ImGui the hwnd of your application
207240
208 If you want to input Japanese/Chinese/Korean in the text input widget:
209
210    - when loading the font, pass a range that contains the characters you need, e.g.: io.Fonts->GetGlyphRangesJapanese()
211    - to have the Microsoft IME cursor appears at the right location in the screen, setup a handler for the io.ImeSetInputScreenPosFn function:
212
213        #include <Windows.h>
214        #include <Imm.h>
215        static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
216        {
217          // Notify OS Input Method Editor of text input position
218          HWND hwnd = glfwGetWin32Window(window);
219          if (HIMC himc = ImmGetContext(hwnd))
220          {
221            COMPOSITIONFORM cf;
222            cf.ptCurrentPos.x = x;
223            cf.ptCurrentPos.y = y;
224            cf.dwStyle = CFS_FORCE_POSITION;
225            ImmSetCompositionWindow(himc, &cf);
226          }
227        }
228
229        // Set pointer to handler in ImGuiIO structure
230        io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
231
232241 - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
233242 - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
234243 - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window.
r244869r244870
254263 - main: IsItemHovered() returns true even if mouse is active on another widget (e.g. dragging outside of sliders). Maybe not a sensible default? Add parameter or alternate function?
255264 - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
256265 - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
257 - scrollbar: use relative mouse movement when first-clicking inside of scroll grab box.
258 - scrollbar: make the grab visible and a minimum size for long scroll regions
259266!- input number: very large int not reliably supported because of int<>float conversions.
260267 - input number: optional range min/max for Input*() functions
261268 - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
r244869r244870
268275 - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills)
269276 - columns: columns header to act as button (~sort op) and allow resize/reorder
270277 - columns: user specify columns size
278 - columns: tree node example, removing the last NextColumn() makes a padding difference (it should not)
271279 - combo: turn child handling code into pop up helper
272280 - combo: contents should extends to fit label if combo widget is small
273281 - listbox: multiple selection
r244869r244870
281289 - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
282290 - file selection widget -> build the tool in our codebase to improve model-dialog idioms
283291 - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
284 - slider: initial absolute click is imprecise. change to relative movement slider? hide mouse cursor, allow more precise input using less screen-space.
285 - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather ineficient right now.
292 - slider: initial absolute click is imprecise. change to relative movement slider? hide mouse cursor, allow more precise input using less screen-space. same as scrollbar.
293 - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now.
286294 - text edit: centered text for slider as input text so it matches typical positioning.
287295 - text edit: flag to disable live update of the user buffer.
288296 - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text?
r244869r244870
293301 ! style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost.
294302 - style: checkbox: padding for "active" color should be a multiplier of the
295303 - style: colorbox not always square?
304 - text: simple markup language for color change?
296305 - log: LogButtons() options for specifying depth and/or hiding depth slider
297306 - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
298307 - log: be able to right-click and log a window or tree-node into tty/file/clipboard / generalized context menu?
r244869r244870
340349#pragma clang diagnostic ignored "-Wformat-nonliteral"      // warning : format string is not a string literal              // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
341350#pragma clang diagnostic ignored "-Wexit-time-destructors"  // warning : declaration requires an exit-time destructor       // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
342351#pragma clang diagnostic ignored "-Wglobal-constructors"    // warning : declaration requires a global destructor           // similar to above, not sure what the exact difference it.
343#pragma clang diagnostic ignored "-Wsign-conversion"        // warning : implicit conversion chanjges signedness            //
344#elif defined(__GNUC__)
345#pragma GCC diagnostic ignored "-Wtype-limits"
346#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
347#pragma GCC diagnostic ignored "-Wunused-function"
352#pragma clang diagnostic ignored "-Wsign-conversion"        // warning : implicit conversion changes signedness             //
348353#endif
354#ifdef __GNUC__
355#pragma GCC diagnostic ignored "-Wunused-function"          // warning: 'xxxx' defined but not used
356#endif
349357
350358//-------------------------------------------------------------------------
351359// STB libraries implementation
r244869r244870
384392#endif
385393#include "stb_truetype.h"
386394
387#define STB_TEXTEDIT_STRING ImGuiTextEditState
388#define STB_TEXTEDIT_CHARTYPE ImWchar
395#define STB_TEXTEDIT_STRING    ImGuiTextEditState
396#define STB_TEXTEDIT_CHARTYPE  ImWchar
389397#include "stb_textedit.h"
390398
391399#ifdef __clang__
r244869r244870
401409// Forward Declarations
402410//-------------------------------------------------------------------------
403411
412struct ImGuiColMod;
413struct ImGuiStyleMod;
404414struct ImGuiAabb;
415struct ImGuiDrawContext;
416struct ImGuiTextEditState;
417struct ImGuiIniData;
418struct ImGuiState;
419struct ImGuiWindow;
405420
406421static bool         ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false);
407422static void         LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);
r244869r244870
413428static void         RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false);
414429
415430static void         SetFont(ImFont* font);
416static bool         ItemAdd(const ImGuiAabb& aabb, const ImGuiID* id);
431static bool         ItemAdd(const ImGuiAabb& bb, const ImGuiID* id);
417432static void         ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL);
418static void         ItemSize(const ImGuiAabb& aabb, ImVec2* adjust_start_offset = NULL);
433static void         ItemSize(const ImGuiAabb& bb, ImVec2* adjust_start_offset = NULL);
419434static void         PushColumnClipRect(int column_index = -1);
420static bool         IsClipped(const ImGuiAabb& aabb);
435static bool         IsClipped(const ImGuiAabb& bb);
421436
422static bool         IsMouseHoveringBox(const ImGuiAabb& box);
437static bool         IsMouseHoveringBox(const ImGuiAabb& bb);
423438static bool         IsKeyPressedMap(ImGuiKey key, bool repeat = true);
424439
440static void         Scrollbar(ImGuiWindow* window);
425441static bool         CloseWindowButton(bool* p_opened = NULL);
426442static void         FocusWindow(ImGuiWindow* window);
427443static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs);
r244869r244870
436452static size_t       ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args);
437453
438454// Helpers: Misc
439static ImU32        ImCrc32(const void* data, size_t data_size, ImU32 seed);
455static ImU32        ImHash(const void* data, size_t data_size, ImU32 seed);
440456static bool         ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes = 0);
441static int          ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
457static inline int   ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
458static inline bool  ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; }
442459
443460// Helpers: UTF-8 <> wchar
444461static int          ImTextCharToUtf8(char* buf, size_t buf_size, unsigned int in_char);                                // return output UTF-8 bytes count
445462static ptrdiff_t    ImTextStrToUtf8(char* buf, size_t buf_size, const ImWchar* in_text, const ImWchar* in_text_end);   // return output UTF-8 bytes count
446463static int          ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end);          // return input UTF-8 bytes count
447static ptrdiff_t    ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end);    // return input UTF-8 bytes count
464static ptrdiff_t    ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL);   // return input UTF-8 bytes count
448465static int          ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end);                            // return number of UTF-8 code-points (NOT bytes count)
449static int          ImTextCountUtf8BytesFromWchar(const ImWchar* in_text, const ImWchar* in_text_end);                 // return number of bytes to express string as UTF-8 code-points
466static int          ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end);                   // return number of bytes to express string as UTF-8 code-points
450467
451468//-----------------------------------------------------------------------------
452469// Platform dependent default implementations
r244869r244870
454471
455472static const char*  GetClipboardTextFn_DefaultImpl();
456473static void         SetClipboardTextFn_DefaultImpl(const char* text);
474static void         ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
457475
458476//-----------------------------------------------------------------------------
459477// Texture Atlas data
r244869r244870
486504    WindowFillAlphaDefault  = 0.70f;            // Default alpha of window background, if not specified in ImGui::Begin()
487505    TreeNodeSpacing         = 22.0f;            // Horizontal spacing when entering a tree node
488506    ColumnsMinSpacing       = 6.0f;             // Minimum horizontal spacing between two columns
489    ScrollBarWidth          = 16.0f;            // Width of the vertical scroll bar
507    ScrollbarWidth          = 16.0f;            // Width of the vertical scrollbar
508    GrabMinSize             = 10.0f;            // Minimum width/height of a slider or scrollbar grab
490509
491510    Colors[ImGuiCol_Text]                   = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
492511    Colors[ImGuiCol_WindowBg]               = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
r244869r244870
529548    Colors[ImGuiCol_TooltipBg]              = ImVec4(0.05f, 0.05f, 0.10f, 0.90f);
530549}
531550
532// Statically allocated font atlas. This is merely a maneuver to keep its definition at the bottom of the .H file.
533// Because we cannot new() at this point (before users may define IO.MemAllocFn)
551// Statically allocated font atlas. This is merely a maneuver to keep ImFontAtlas definition at the bottom of the .h file (otherwise it'd be inside ImGuiIO)
552// Also we wouldn't be able to new() one at this point, before users may define IO.MemAllocFn.
534553static ImFontAtlas GDefaultFontAtlas;
535554
536555ImGuiIO::ImGuiIO()
r244869r244870
557576    MemFreeFn = free;
558577    GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;   // Platform dependent default implementations
559578    SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
560    ImeSetInputScreenPosFn = NULL;
579    ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
561580}
562581
563582// Pass in translated ASCII characters for text input.
564583// - with glfw you can get those from the callback set in glfwSetCharCallback()
565// - on Windows you can get those using ToAscii+keyboard state, or via the VM_CHAR message
584// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
566585void ImGuiIO::AddInputCharacter(ImWchar c)
567586{
568587    const size_t n = ImStrlenW(InputCharacters);
r244869r244870
588607#define IM_INT_MAX 2147483647
589608#endif
590609
591// Play it nice with Windows users. Notepad in 2014 still doesn't display text data with Unix-style \n.
610// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n.
592611#ifdef _MSC_VER
593612#define STR_NEWLINE "\r\n"
594613#else
r244869r244870
647666static size_t ImStrlenW(const ImWchar* str)
648667{
649668    size_t n = 0;
650    while (*str++)
651        n++;
669    while (*str++) n++;
652670    return n;
653671}
654672
r244869r244870
675693}
676694
677695// Pass data_size==0 for zero-terminated string
678static ImU32 ImCrc32(const void* data, size_t data_size, ImU32 seed = 0)
696// Try to replace with FNV1a hash?
697static ImU32 ImHash(const void* data, size_t data_size, ImU32 seed = 0)
679698{
680699    static ImU32 crc32_lut[256] = { 0 };
681700    if (!crc32_lut[1])
r244869r244870
689708            crc32_lut[i] = crc;
690709        }
691710    }
692    ImU32 crc = ~seed;
711
712    seed = ~seed;
713    ImU32 crc = seed;
693714    const unsigned char* current = (const unsigned char*)data;
694715
695716    if (data_size > 0)
r244869r244870
702723    {
703724        // Zero-terminated string
704725        while (unsigned char c = *current++)
726        {
727            // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed.
728            // Because this syntax is rarely used we are optimizing for the common case.
729            // - If we reach ### in the string we discard the hash so far and reset to the seed.
730            // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller.
731            if (c == '#' && current[0] == '#' && current[1] == '#')
732                crc = seed;
733
705734            crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
735        }
706736    }
707737    return ~crc;
708738}
r244869r244870
841871    ImVec2      PreviousValue;
842872};
843873
844struct ImGuiAabb    // 2D axis aligned bounding-box
874struct ImGuiAabb        // 2D axis aligned bounding-box
845875{
846876    ImVec2      Min;
847877    ImVec2      Max;
r244869r244870
887917    ImVector<float>         TextWrapPos;
888918    ImGuiColorEditMode      ColorEditMode;
889919    ImGuiStorage*           StateStorage;
890    int                     OpenNextNode;        // FIXME: Reformulate this feature like SetNextWindowCollapsed() API
891920
892921    float                   ColumnsStartX;       // Start position from left of window (increased by TreePush/TreePop, etc.)
893922    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.
r244869r244870
898927    float                   ColumnsCellMaxY;
899928    bool                    ColumnsShowBorders;
900929    ImGuiID                 ColumnsSetID;
930    ImVector<float>         ColumnsOffsetsT;     // Columns offset normalized 0.0 (far left) -> 1.0 (far right)
901931
902932    ImGuiDrawContext()
903933    {
r244869r244870
909939        LastItemAabb = ImGuiAabb(0.0f,0.0f,0.0f,0.0f);
910940        LastItemHovered = false;
911941        StateStorage = NULL;
912        OpenNextNode = -1;
913942
914943        ColumnsStartX = 0.0f;
915944        ColumnsOffsetX = 0.0f;
r244869r244870
925954// Internal state of the currently focused/edited text input box
926955struct ImGuiTextEditState
927956{
957    ImGuiID             Id;                             // widget id owning the text state
928958    ImWchar             Text[1024];                     // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
929    char                InitialText[1024*3+1];          // backup of end-user buffer at the time of focus (in UTF-8, unconverted)
930    size_t              BufSize;                        // end-user buffer size, <= 1024 (or increase above)
959    char                InitialText[1024*4+1];          // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
960    int                 CurLenA, CurLenW;               // we need to maintain our buffer length in both UTF-8 and wchar format.
961    size_t              BufSizeA;                       // end-user buffer size, <= 1024 (or increase above)
931962    float               Width;                          // widget width
932963    float               ScrollX;
933964    STB_TexteditState   StbState;
934965    float               CursorAnim;
935    ImVec2              LastCursorPos;                  // Cursor position in screen space to be used by IME callback.
966    ImVec2              InputCursorScreenPos;           // Cursor position in screen space to be used by IME callback.
936967    bool                SelectedAllMouseLock;
937968    ImFont*             Font;
938969    float               FontSize;
r244869r244870
954985    static void             RenderTextScrolledClipped(ImFont* font, float font_size, const char* text, ImVec2 pos_base, float width, float scroll_x);
955986};
956987
988// Data saved in imgui.ini file
957989struct ImGuiIniData
958990{
959991    char*   Name;
992    ImGuiID ID;
960993    ImVec2  Pos;
961994    ImVec2  Size;
962995    bool    Collapsed;
r244869r244870
965998    ~ImGuiIniData() { if (Name) { ImGui::MemFree(Name); Name = NULL; } }
966999};
9671000
1001// Main state for ImGui
9681002struct ImGuiState
9691003{
9701004    bool                    Initialized;
r244869r244870
9871021    ImGuiID                 ActiveId;
9881022    ImGuiID                 ActiveIdPreviousFrame;
9891023    bool                    ActiveIdIsAlive;
1024    bool                    ActiveIdIsFocusedOnly;              // Set only by active widget. Denote focus but no active interaction.
1025    ImGuiWindow*            MovedWindow;                        // Track the child window we clicked on to move a window. Only valid if ActiveID is the "#MOVE" identifier of a window.
9901026    float                   SettingsDirtyTimer;
9911027    ImVector<ImGuiIniData*> Settings;
9921028    ImVector<ImGuiColMod>   ColorModifiers;
9931029    ImVector<ImGuiStyleMod> StyleModifiers;
9941030    ImVector<ImFont*>       FontStack;
1031
9951032    ImVec2                  SetNextWindowPosVal;
996    ImGuiSetCondition       SetNextWindowPosCond;
1033    ImGuiSetCond            SetNextWindowPosCond;
9971034    ImVec2                  SetNextWindowSizeVal;
998    ImGuiSetCondition       SetNextWindowSizeCond;
1035    ImGuiSetCond            SetNextWindowSizeCond;
9991036    bool                    SetNextWindowCollapsedVal;
1000    ImGuiSetCondition       SetNextWindowCollapsedCond;
1037    ImGuiSetCond            SetNextWindowCollapsedCond;
1038    bool                    SetNextWindowFocus;
1039    bool                    SetNextTreeNodeOpenedVal;
1040    ImGuiSetCond            SetNextTreeNodeOpenedCond;
10011041
10021042    // Render
10031043    ImVector<ImDrawList*>   RenderDrawLists;
r244869r244870
10081048    ImGuiID                 SliderAsInputTextId;
10091049    ImGuiStorage            ColorEditModeStorage;               // for user selection
10101050    ImGuiID                 ActiveComboID;
1051    float                   ScrollbarClickDeltaToGrabCenter;    // distance between mouse and center of grab box, normalized in parent space
10111052    char                    Tooltip[1024];
10121053    char*                   PrivateClipboard;                   // if no custom clipboard handler is defined
10131054
r244869r244870
10181059    int                     LogStartDepth;
10191060    int                     LogAutoExpandMaxDepth;
10201061
1062    // Misc
1063    float                   FramerateSecPerFrame[120];          // calculate estimate of framerate for user
1064    int                     FramerateSecPerFrameIdx;
1065    float                   FramerateSecPerFrameAccum;
1066
10211067    ImGuiState()
10221068    {
10231069        Initialized = false;
1070        Font = NULL;
1071        FontSize = 0.0f;
1072        FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
1073
10241074        Time = 0.0f;
10251075        FrameCount = 0;
10261076        FrameCountRendered = -1;
r244869r244870
10281078        FocusedWindow = NULL;
10291079        HoveredWindow = NULL;
10301080        HoveredRootWindow = NULL;
1081        HoveredId = 0;
1082        ActiveId = 0;
1083        ActiveIdPreviousFrame = 0;
10311084        ActiveIdIsAlive = false;
1085        ActiveIdIsFocusedOnly = false;
1086        MovedWindow = NULL;
10321087        SettingsDirtyTimer = 0.0f;
1088
10331089        SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
10341090        SetNextWindowPosCond = 0;
10351091        SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
10361092        SetNextWindowSizeCond = 0;
10371093        SetNextWindowCollapsedVal = false;
10381094        SetNextWindowCollapsedCond = 0;
1095        SetNextWindowFocus = false;
1096        SetNextTreeNodeOpenedVal = false;
1097        SetNextTreeNodeOpenedCond = 0;
1098
10391099        SliderAsInputTextId = 0;
10401100        ActiveComboID = 0;
1101        ScrollbarClickDeltaToGrabCenter = 0.0f;
10411102        memset(Tooltip, 0, sizeof(Tooltip));
10421103        PrivateClipboard = NULL;
1104
10431105        LogEnabled = false;
10441106        LogFile = NULL;
1107        LogClipboard = NULL;
10451108        LogStartDepth = 0;
10461109        LogAutoExpandMaxDepth = 2;
1047        LogClipboard = NULL;
1110
1111        memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
1112        FramerateSecPerFrameIdx = 0;
1113        FramerateSecPerFrameAccum = 0.0f;
10481114    }
10491115};
10501116
r244869r244870
10601126    ImVec2                  Pos;                                // Position rounded-up to nearest pixel
10611127    ImVec2                  Size;                               // Current size (==SizeFull or collapsed title bar size)
10621128    ImVec2                  SizeFull;                           // Size when non collapsed
1063    ImVec2                  SizeContentsFit;                    // Size of contents (extents reach by the drawing cursor) - may not fit within Size.
1129    ImVec2                  SizeContents;                       // Size of contents (== extents reach of the drawing cursor) from previous frame
1130    ImVec2                  SizeContentsCurrent;                // Size of contents, currently extending
10641131    float                   ScrollY;
10651132    float                   NextScrollY;
10661133    bool                    ScrollbarY;
r244869r244870
10701137    bool                    SkipItems;                          // == Visible && !Collapsed
10711138    int                     AutoFitFrames;
10721139    bool                    AutoFitOnlyGrows;
1073    int                     SetWindowPosAllowFlags;             // bit ImGuiSetCondition_*** specify if SetWindowPos() call is allowed with this particular flag.
1074    int                     SetWindowSizeAllowFlags;            // bit ImGuiSetCondition_*** specify if SetWindowSize() call is allowed with this particular flag.
1075    int                     SetWindowCollapsedAllowFlags;       // bit ImGuiSetCondition_*** specify if SetWindowCollapsed() call is allowed with this particular flag.
1140    int                     SetWindowPosAllowFlags;             // bit ImGuiSetCond_*** specify if SetWindowPos() call is allowed with this particular flag.
1141    int                     SetWindowSizeAllowFlags;            // bit ImGuiSetCond_*** specify if SetWindowSize() call is allowed with this particular flag.
1142    int                     SetWindowCollapsedAllowFlags;       // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call is allowed with this particular flag.
10761143
10771144    ImGuiDrawContext        DC;
10781145    ImVector<ImGuiID>       IDStack;
10791146    ImVector<ImVec4>        ClipRectStack;                      // Scissoring / clipping rectangle. x1, y1, x2, y2.
1147    ImGuiAabb               ClippedAabb;                        // = ClipRectStack.front() after setup in Begin()
10801148    int                     LastFrameDrawn;
10811149    float                   ItemWidthDefault;
10821150    ImGuiStorage            StateStorage;
r244869r244870
11091177    ImVec2      CursorPos() const                       { return DC.CursorPos; }
11101178    float       TitleBarHeight() const                  { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui->Style.FramePadding.y * 2.0f; }
11111179    ImGuiAabb   TitleBarAabb() const                    { return ImGuiAabb(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); }
1112    ImVec2      WindowPadding() const                   { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders)) ? ImVec2(1,1) : GImGui->Style.WindowPadding; }
1180    ImVec2      WindowPadding() const                   { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders)) ? ImVec2(0,0) : GImGui->Style.WindowPadding; }
11131181    ImU32       Color(ImGuiCol idx, float a=1.f) const  { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * a; return ImGui::ColorConvertFloat4ToU32(c); }
11141182    ImU32       Color(const ImVec4& col) const          { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
11151183};
11161184
1117static ImGuiWindow* GetCurrentWindow()
1185static inline ImGuiWindow* GetCurrentWindow()
11181186{
11191187    ImGuiState& g = *GImGui;
11201188    IM_ASSERT(g.CurrentWindow != NULL);    // ImGui::NewFrame() hasn't been called yet?
r244869r244870
11221190    return g.CurrentWindow;
11231191}
11241192
1193static inline ImGuiWindow* GetParentWindow()
1194{
1195    ImGuiState& g = *GImGui;
1196    IM_ASSERT(g.CurrentWindowStack.size() >= 2);
1197    return g.CurrentWindowStack[g.CurrentWindowStack.size() - 2];
1198}
1199
11251200static void SetActiveId(ImGuiID id)
11261201{
11271202    ImGuiState& g = *GImGui;
11281203    g.ActiveId = id;
1204    g.ActiveIdIsFocusedOnly = false;
11291205}
11301206
11311207static void RegisterAliveId(const ImGuiID& id)
r244869r244870
12511327//-----------------------------------------------------------------------------
12521328
12531329// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
1254ImGuiTextFilter::ImGuiTextFilter()
1330ImGuiTextFilter::ImGuiTextFilter(const char* default_filter)
12551331{
1256    InputBuf[0] = 0;
1257    CountGrep = 0;
1332    if (default_filter)
1333    {
1334        ImFormatString(InputBuf, IM_ARRAYSIZE(InputBuf), "%s", default_filter);
1335        Build();
1336    }
1337    else
1338    {
1339        InputBuf[0] = 0;
1340        CountGrep = 0;
1341    }
12581342}
12591343
12601344void ImGuiTextFilter::Draw(const char* label, float width)
12611345{
1262    ImGuiWindow* window = GetCurrentWindow();
1263    if (width < 0.0f)
1264    {
1265        ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
1266        width = ImMax(window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x - (label_size.x + GImGui->Style.ItemSpacing.x*4), 10.0f);
1267    }
1268    ImGui::PushItemWidth(width);
1346    if (width > 0.0f)
1347        ImGui::PushItemWidth(width);
12691348    ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf));
1270    ImGui::PopItemWidth();
1349    if (width > 0.0f)
1350        ImGui::PopItemWidth();
12711351    Build();
12721352}
12731353
r244869r244870
13831463ImGuiWindow::ImGuiWindow(const char* name)
13841464{
13851465    Name = ImStrdup(name);
1386    ID = GetID(name);
1466    ID = ImHash(name, 0);
13871467    IDStack.push_back(ID);
13881468
1469    Flags = 0;
13891470    PosFloat = Pos = ImVec2(0.0f, 0.0f);
13901471    Size = SizeFull = ImVec2(0.0f, 0.0f);
1391    SizeContentsFit = ImVec2(0.0f, 0.0f);
1472    SizeContents = SizeContentsCurrent = ImVec2(0.0f, 0.0f);
13921473    ScrollY = 0.0f;
13931474    NextScrollY = 0.0f;
13941475    ScrollbarY = false;
r244869r244870
13981479    SkipItems = false;
13991480    AutoFitFrames = -1;
14001481    AutoFitOnlyGrows = false;
1401    SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCondition_Always | ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver;
1482    SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver;
14021483
14031484    LastFrameDrawn = -1;
14041485    ItemWidthDefault = 0.0f;
r244869r244870
14121493
14131494    DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
14141495    new(DrawList) ImDrawList();
1496    RootWindow = NULL;
14151497
14161498    FocusIdxAllCounter = FocusIdxTabCounter = -1;
14171499    FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX;
r244869r244870
14291511
14301512ImGuiID ImGuiWindow::GetID(const char* str)
14311513{
1432    const ImGuiID seed = IDStack.empty() ? 0 : IDStack.back();
1433    const ImGuiID id = ImCrc32(str, 0, seed);
1514    ImGuiID seed = IDStack.back();
1515    const ImGuiID id = ImHash(str, 0, seed);
14341516    RegisterAliveId(id);
14351517    return id;
14361518}
14371519
14381520ImGuiID ImGuiWindow::GetID(const void* ptr)
14391521{
1440    const ImGuiID seed = IDStack.empty() ? 0 : IDStack.back();
1441    const ImGuiID id = ImCrc32(&ptr, sizeof(void*), seed);
1522    ImGuiID seed = IDStack.back();
1523    const ImGuiID id = ImHash(&ptr, sizeof(void*), seed);
14421524    RegisterAliveId(id);
14431525    return id;
14441526}
r244869r244870
15101592static ImGuiIniData* FindWindowSettings(const char* name)
15111593{
15121594    ImGuiState& g = *GImGui;
1595    ImGuiID id = ImHash(name, 0);
15131596    for (size_t i = 0; i != g.Settings.size(); i++)
15141597    {
15151598        ImGuiIniData* ini = g.Settings[i];
1516        if (ImStricmp(ini->Name, name) == 0)
1599        if (ini->ID == id)
15171600            return ini;
15181601    }
15191602    return NULL;
r244869r244870
15241607    ImGuiIniData* ini = (ImGuiIniData*)ImGui::MemAlloc(sizeof(ImGuiIniData));
15251608    new(ini) ImGuiIniData();
15261609    ini->Name = ImStrdup(name);
1610    ini->ID = ImHash(name, 0);
15271611    ini->Collapsed = false;
15281612    ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
15291613    ini->Size = ImVec2(0,0);
r244869r244870
16081692        const ImGuiIniData* settings = g.Settings[i];
16091693        if (settings->Pos.x == FLT_MAX)
16101694            continue;
1611        fprintf(f, "[%s]\n", settings->Name);
1695        const char* name = settings->Name;
1696        if (const char* p = strstr(name, "###"))  // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
1697            name = p;
1698        fprintf(f, "[%s]\n", name);
16121699        fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
16131700        fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
16141701        fprintf(f, "Collapsed=%d\n", settings->Collapsed);
r244869r244870
17151802    for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
17161803        g.IO.KeysDownTime[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownTime[i] < 0.0f ? 0.0f : g.IO.KeysDownTime[i] + g.IO.DeltaTime) : -1.0f;
17171804
1805    // Calculate frame-rate for the user, as a purely luxurious feature
1806    g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
1807    g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
1808    g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
1809    g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame));
1810
17181811    // Clear reference to active widget if the widget isn't alive anymore
17191812    g.HoveredId = 0;
17201813    if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
17211814        SetActiveId(0);
17221815    g.ActiveIdPreviousFrame = g.ActiveId;
17231816    g.ActiveIdIsAlive = false;
1817    if (!g.ActiveId)
1818        g.MovedWindow = NULL;
17241819
17251820    // Delay saving settings so we don't spam disk too much
17261821    if (g.SettingsDirtyTimer > 0.0f)
r244869r244870
17951890    }
17961891
17971892    // Mark all windows as not visible
1798    // Clear root windows at this point.
17991893    for (size_t i = 0; i != g.Windows.size(); i++)
18001894    {
18011895        ImGuiWindow* window = g.Windows[i];
18021896        window->Visible = false;
18031897        window->Accessed = false;
1804        window->RootWindow = NULL;
18051898    }
18061899
18071900    // No window should be open at the beginning of the frame.
r244869r244870
18091902    g.CurrentWindowStack.resize(0);
18101903
18111904    // Create implicit window - we will only render it if the user has added something to it.
1812    ImGui::Begin("Debug", NULL, ImVec2(400,400), -1.0f, ImGuiWindowFlags_NoSavedSettings);
1905    ImGui::Begin("Debug", NULL, ImVec2(400,400));
18131906}
18141907
18151908// NB: behaviour of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations.
r244869r244870
19322025            g.CurrentWindow->Visible = false;
19332026        ImGui::End();
19342027
1935        // Select window for move/focus when we're done with all our widgets (we only consider non-child windows here)
2028        // Select window for move/focus when we're done with all our widgets (we use the root window ID here)
19362029        if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredRootWindow != NULL && g.IO.MouseClicked[0])
2030        {
2031            IM_ASSERT(g.MovedWindow == NULL);
2032            g.MovedWindow = g.HoveredWindow;
19372033            SetActiveId(g.HoveredRootWindow->GetID("#MOVE"));
2034        }
19382035
19392036        // Sort the window list so that all child windows are after their parent
19402037        // We cannot do that on FocusWindow() because childs may not exist yet
r244869r244870
20102107static const char*  FindTextDisplayEnd(const char* text, const char* text_end = NULL)
20112108{
20122109    const char* text_display_end = text;
2013    while ((!text_end || text_display_end < text_end) && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
2110    if (!text_end)
2111        text_end = (const char*)-1;
2112    while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
20142113        text_display_end++;
20152114    return text_display_end;
20162115}
r244869r244870
22172316
22182317    if (shadow && (window->Flags & ImGuiWindowFlags_ShowBorders) != 0)
22192318        window->DrawList->AddTriangleFilled(a+ImVec2(2,2), b+ImVec2(2,2), c+ImVec2(2,2), window->Color(ImGuiCol_BorderShadow));
2220    window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Border));
2319    window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Text));
22212320}
22222321
22232322// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
r244869r244870
22942393            continue;
22952394        if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0)
22962395            continue;
2297        ImGuiAabb bb(window->Pos - g.Style.TouchExtraPadding, window->Pos + window->Size + g.Style.TouchExtraPadding);
2396
2397        // Using the clipped AABB so a child window will typically be clipped by its parent.
2398        ImGuiAabb bb(window->ClippedAabb.Min - g.Style.TouchExtraPadding, window->ClippedAabb.Max + g.Style.TouchExtraPadding);
22982399        if (bb.Contains(pos))
22992400            return window;
23002401    }
r244869r244870
23042405// Test if mouse cursor is hovering given aabb
23052406// NB- Box is clipped by our current clip setting
23062407// NB- Expand the aabb to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
2307static bool IsMouseHoveringBox(const ImGuiAabb& box)
2408static bool IsMouseHoveringBox(const ImGuiAabb& bb)
23082409{
23092410    ImGuiState& g = *GImGui;
23102411    ImGuiWindow* window = GetCurrentWindow();
23112412
23122413    // Clip
2313    ImGuiAabb box_clipped = box;
2414    ImGuiAabb box_clipped = bb;
23142415    if (!window->ClipRectStack.empty())
23152416    {
23162417        const ImVec4 clip_rect = window->ClipRectStack.back();
r244869r244870
24172518    return false;
24182519}
24192520
2521bool ImGui::IsAnyItemActive()
2522{
2523    ImGuiState& g = *GImGui;
2524    return g.ActiveId != 0;
2525}
2526
24202527ImVec2 ImGui::GetItemBoxMin()
24212528{
24222529    ImGuiWindow* window = GetCurrentWindow();
r244869r244870
24672574    ImGui::End();
24682575}
24692576
2470void ImGui::BeginChild(ImGuiID id, ImVec2 size, bool border, ImGuiWindowFlags extra_flags)
2577bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
24712578{
2472    char str_id[32];
2473    ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%x", id);
2474    ImGui::BeginChild(str_id, size, border, extra_flags);
2475}
2476
2477void ImGui::BeginChild(const char* str_id, ImVec2 size, bool border, ImGuiWindowFlags extra_flags)
2478{
24792579    ImGuiState& g = *GImGui;
24802580    ImGuiWindow* window = GetCurrentWindow();
24812581
r244869r244870
24832583
24842584    const ImVec2 content_max = window->Pos + ImGui::GetContentRegionMax();
24852585    const ImVec2 cursor_pos = window->Pos + ImGui::GetCursorPos();
2586    ImVec2 size = size_arg;
24862587    if (size.x <= 0.0f)
24872588    {
24882589        if (size.x == 0.0f)
r244869r244870
25032604    ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id);
25042605
25052606    const float alpha = 1.0f;
2506    ImGui::Begin(title, NULL, size, alpha, flags);
2607    bool ret = ImGui::Begin(title, NULL, size, alpha, flags);
25072608
25082609    if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
25092610        g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders;
2611
2612    return ret;
25102613}
25112614
2615bool ImGui::BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags extra_flags)
2616{
2617    char str_id[32];
2618    ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%x", id);
2619    bool ret = ImGui::BeginChild(str_id, size, border, extra_flags);
2620    return ret;
2621}
2622
25122623void ImGui::EndChild()
25132624{
25142625    ImGuiWindow* window = GetCurrentWindow();
r244869r244870
25282639            sz.y = 0;
25292640
25302641        ImGui::End();
2642
2643        window = GetCurrentWindow();
2644        ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + sz);
25312645        ItemSize(sz);
2646        ItemAdd(bb, NULL);
25322647    }
25332648}
25342649
r244869r244870
25512666
25522667static ImGuiWindow* FindWindowByName(const char* name)
25532668{
2554    // FIXME-OPT: Consider optimizing this (e.g. sorted hashes to window pointers)
2669    // FIXME-OPT: Store sorted hashes -> pointers.
25552670    ImGuiState& g = *GImGui;
2556    for (size_t i = 0; i != g.Windows.size(); i++)
2557        if (strcmp(g.Windows[i]->Name, name) == 0)
2671    ImGuiID id = ImHash(name, 0);
2672    for (size_t i = 0; i < g.Windows.size(); i++)
2673        if (g.Windows[i]->ID == id)
25582674            return g.Windows[i];
25592675    return NULL;
25602676}
r244869r244870
25872703        }
25882704        else
25892705        {
2590            window->SetWindowPosAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
2591            window->SetWindowSizeAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
2592            window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCondition_FirstUseEver;
2706            window->SetWindowPosAllowFlags &= ~ImGuiSetCond_FirstUseEver;
2707            window->SetWindowSizeAllowFlags &= ~ImGuiSetCond_FirstUseEver;
2708            window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCond_FirstUseEver;
25932709        }
25942710
25952711        if (settings->Pos.x != FLT_MAX)
r244869r244870
26082724}
26092725
26102726// Push a new ImGui window to add widgets to.
2611// - A default window called "Debug" is automatically stacked at the beginning of every frame.
2612// - This can be called multiple times during the frame with the same window name to append content to the same window.
2613// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). Note that you can use ## to append unique data that isn't displayed, e.g. "My window##1" will use "My window##1" as unique window ID but display "My window" to the user.
2727// - 'size' for a regular window denote the initial size for first-time creation (no saved data) and isn't that useful. Use SetNextWindowSize() prior to calling Begin() for more flexible window manipulation.
2728// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair.
2729// - Begin/End can be called multiple times during the frame with the same window name to append content.
2730// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file).
2731//   You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file.
26142732// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned.
26152733// - Passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
2616// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCondition_FirstUseEver) prior to calling Begin().
2617bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alpha, ImGuiWindowFlags flags)
2734// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin().
2735bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg_alpha, ImGuiWindowFlags flags)
26182736{
26192737    ImGuiState& g = *GImGui;
26202738    const ImGuiStyle& style = g.Style;
r244869r244870
26512769        ImGui::SetWindowCollapsed(g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond);
26522770        g.SetNextWindowCollapsedCond = 0;
26532771    }
2772    if (g.SetNextWindowFocus)
2773    {
2774        ImGui::SetWindowFocus();
2775        g.SetNextWindowFocus = false;
2776    }
26542777
26552778    // Find parent
26562779    ImGuiWindow* parent_window = (flags & ImGuiWindowFlags_ChildWindow) != 0 ? g.CurrentWindowStack[g.CurrentWindowStack.size()-2] : NULL;
26572780
2658    // Find root (if we are a child window)
2781    // Update known root window (if we are a child window, otherwise window == window->RootWindow)
26592782    size_t root_idx = g.CurrentWindowStack.size() - 1;
26602783    while (root_idx > 0)
26612784    {
r244869r244870
26662789    window->RootWindow = g.CurrentWindowStack[root_idx];
26672790
26682791    // Default alpha
2669    if (fill_alpha < 0.0f)
2670        fill_alpha = style.WindowFillAlphaDefault;
2792    if (bg_alpha < 0.0f)
2793        bg_alpha = style.WindowFillAlphaDefault;
26712794
26722795    // When reusing window again multiple times a frame, just append content (don't need to setup again)
26732796    const int current_frame = ImGui::GetFrameCount();
r244869r244870
26842807        window->LastFrameDrawn = current_frame;
26852808        window->ClipRectStack.resize(0);
26862809
2810        // Reset contents size for auto-fitting
2811        window->SizeContents = window->SizeContentsCurrent;
2812        window->SizeContentsCurrent = ImVec2(0.0f, 0.0f);
2813
26872814        if (flags & ImGuiWindowFlags_ChildWindow)
26882815        {
26892816            parent_window->DC.ChildWindows.push_back(window);
r244869r244870
27062833    // Setup and draw window
27072834    if (first_begin_of_the_frame)
27082835    {
2709        // Seed ID stack with our window pointer
2710        window->IDStack.resize(0);
2711        ImGui::PushID(window);
2836        // Reset ID stack
2837        window->IDStack.resize(1);
27122838
2713        // Move window (at the beginning of the frame to avoid input lag or sheering)
2839        // Move window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows.
27142840        const ImGuiID move_id = window->GetID("#MOVE");
27152841        RegisterAliveId(move_id);
27162842        if (g.ActiveId == move_id)
r244869r244870
27232849                    if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
27242850                        MarkSettingsDirty();
27252851                }
2726                FocusWindow(window);
2852                IM_ASSERT(g.MovedWindow != NULL);
2853                FocusWindow(g.MovedWindow);
27272854            }
27282855            else
27292856            {
27302857                SetActiveId(0);
2858                g.MovedWindow = NULL;   // Not strictly necessary but doing it for sanity.
27312859            }
27322860        }
27332861
r244869r244870
27772905        window->ScrollY = window->NextScrollY;
27782906        window->ScrollY = ImMax(window->ScrollY, 0.0f);
27792907        if (!window->Collapsed && !window->SkipItems)
2780            window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, (float)window->SizeContentsFit.y - window->SizeFull.y));
2908            window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y));
27812909        window->NextScrollY = window->ScrollY;
27822910
27832911        // At this point we don't have a clipping rectangle setup yet, so we can test and draw in title bar
r244869r244870
28172945            if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
28182946            {
28192947                // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose.
2820                const ImVec2 size_auto_fit = window->SizeContentsFit + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
2948                const ImVec2 size_auto_fit = window->SizeContents + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
28212949                window->SizeFull = size_auto_fit;
28222950            }
28232951            else
28242952            {
2825                const ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding));
2953                const ImVec2 size_auto_fit = ImClamp(window->SizeContents + style.AutoFitPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding));
28262954                if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
28272955                {
28282956                    // Don't continuously mark settings as dirty, the size of the window doesn't need to be stored.
r244869r244870
28422970                {
28432971                    // Manual resize grip
28442972                    const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR());
2845                    const ImGuiID resize_id = window->GetID("##RESIZE");
2973                    const ImGuiID resize_id = window->GetID("#RESIZE");
28462974                    bool hovered, held;
28472975                    ButtonBehaviour(resize_aabb, resize_id, &hovered, &held, true);
28482976                    resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
r244869r244870
28702998            }
28712999
28723000            // Scrollbar
2873            window->ScrollbarY = (window->SizeContentsFit.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar);
3001            window->ScrollbarY = (window->SizeContents.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar);
28743002
28753003            // Window background
2876            if (fill_alpha > 0.0f)
3004            if (bg_alpha > 0.0f)
28773005            {
28783006                if ((window->Flags & ImGuiWindowFlags_ComboBox) != 0)
2879                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, fill_alpha), window_rounding);
3007                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, bg_alpha), window_rounding);
28803008                else if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2881                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_TooltipBg, fill_alpha), window_rounding);
3009                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_TooltipBg, bg_alpha), window_rounding);
28823010                else if ((window->Flags & ImGuiWindowFlags_ChildWindow) != 0)
2883                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size-ImVec2(window->ScrollbarY?style.ScrollBarWidth:0.0f,0.0f), window->Color(ImGuiCol_ChildWindowBg, fill_alpha), window_rounding, window->ScrollbarY ? (1|8) : (0xF));
3011                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size-ImVec2(window->ScrollbarY?style.ScrollbarWidth:0.0f,0.0f), window->Color(ImGuiCol_ChildWindowBg, bg_alpha), window_rounding, window->ScrollbarY ? (1|8) : (0xF));
28843012                else
2885                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, fill_alpha), window_rounding);
3013                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, bg_alpha), window_rounding);
28863014            }
28873015
28883016            // Title bar
r244869r244870
29003028
29013029            // Scrollbar
29023030            if (window->ScrollbarY)
2903            {
2904                ImGuiAabb scrollbar_bb(window->Aabb().Max.x - style.ScrollBarWidth, title_bar_aabb.Max.y+1, window->Aabb().Max.x, window->Aabb().Max.y-1);
2905                //window->DrawList->AddLine(scrollbar_bb.GetTL(), scrollbar_bb.GetBL(), g.Colors[ImGuiCol_Border]);
2906                window->DrawList->AddRectFilled(scrollbar_bb.Min, scrollbar_bb.Max, window->Color(ImGuiCol_ScrollbarBg));
2907                scrollbar_bb.Expand(ImVec2(-3,-3));
3031                Scrollbar(window);
29083032
2909                const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContentsFit.y, window->Size.y));
2910                const float grab_size_y = scrollbar_bb.GetHeight() * grab_size_y_norm;
2911
2912                // Handle input right away (none of the code above is relying on scrolling position)
2913                bool held = false;
2914                bool hovered = false;
2915                if (grab_size_y_norm < 1.0f)
2916                {
2917                    const ImGuiID scrollbar_id = window->GetID("#SCROLLY");
2918                    ButtonBehaviour(scrollbar_bb, scrollbar_id, &hovered, &held, true);
2919                    if (held)
2920                    {
2921                        g.HoveredId = scrollbar_id;
2922                        const float pos_y_norm = ImSaturate((g.IO.MousePos.y - (scrollbar_bb.Min.y + grab_size_y*0.5f)) / (scrollbar_bb.GetHeight() - grab_size_y)) * (1.0f - grab_size_y_norm);
2923                        window->ScrollY = (float)(int)(pos_y_norm * window->SizeContentsFit.y);
2924                        window->NextScrollY = window->ScrollY;
2925                    }
2926                }
2927
2928                // Normalized height of the grab
2929                const float pos_y_norm = ImSaturate(window->ScrollY / ImMax(0.0f, window->SizeContentsFit.y));
2930                const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
2931                window->DrawList->AddRectFilled(
2932                    ImVec2(scrollbar_bb.Min.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y, pos_y_norm)),
2933                    ImVec2(scrollbar_bb.Max.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y, pos_y_norm + grab_size_y_norm)), grab_col);
2934            }
2935
29363033            // Render resize grip
29373034            // (after the input handling so we don't have a frame of latency)
29383035            if (!(window->Flags & ImGuiWindowFlags_NoResize))
r244869r244870
29753072        window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPos.y;
29763073        window->DC.TreeDepth = 0;
29773074        window->DC.StateStorage = &window->StateStorage;
2978        window->DC.OpenNextNode = -1;
29793075
2980        // Reset contents size for auto-fitting
2981        window->SizeContentsFit = ImVec2(0.0f, 0.0f);
29823076        if (window->AutoFitFrames > 0)
29833077            window->AutoFitFrames--;
29843078
r244869r244870
29993093            const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_aabb.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y);
30003094            RenderTextClipped(text_min, name, NULL, &text_size, text_max);
30013095        }
3096
3097        // Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
3098        window->ClippedAabb = window->Aabb();
3099        window->ClippedAabb.Clip(window->ClipRectStack.front());
30023100    }
30033101
30043102    // Inner clipping rectangle
r244869r244870
30063104    const ImGuiAabb title_bar_aabb = window->TitleBarAabb();
30073105    ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Aabb().Max.y-1.5f);
30083106    if (window->ScrollbarY)
3009        clip_rect.z -= style.ScrollBarWidth;
3107        clip_rect.z -= style.ScrollbarWidth;
30103108    PushClipRect(clip_rect);
30113109
30123110    // Clear 'accessed' flag last thing
r244869r244870
30183116    if (flags & ImGuiWindowFlags_ChildWindow)
30193117    {
30203118        IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0);
3119        window->Collapsed = parent_window && parent_window->Collapsed;
3120
30213121        const ImVec4 clip_rect_t = window->ClipRectStack.back();
3022        window->Collapsed = (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w);
3122        window->Collapsed |= (clip_rect_t.x >= clip_rect_t.z || clip_rect_t.y >= clip_rect_t.w);
30233123
30243124        // We also hide the window from rendering because we've already added its border to the command list.
30253125        // (we could perform the check earlier in the function but it is simpler at this point)
r244869r244870
30493149        ImGui::LogFinish();
30503150
30513151    // Pop
3052    // NB: we don't clear 'window->RootWindow' yet, it will be used then cleared in NewFrame()
3152    // NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin().
30533153    g.CurrentWindowStack.pop_back();
30543154    g.CurrentWindow = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
30553155}
30563156
3157// Vertical scrollbar
3158// The entire piece of code below is rather confusing because:
3159// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
3160// - We store values as ratio and in a form that allows the window content to change while we are holding on a scrollbar
3161static void Scrollbar(ImGuiWindow* window)
3162{
3163    ImGuiState& g = *GImGui;
3164    const ImGuiStyle& style = g.Style;
3165    const ImGuiID id = window->GetID("#SCROLLY");
3166
3167    // Render background
3168    ImGuiAabb bb(window->Aabb().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Aabb().Max.x, window->Aabb().Max.y-1);
3169    window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg));
3170    bb.Expand(ImVec2(-3,-3));
3171    const float scrollbar_height = bb.GetHeight();
3172
3173    // The grabable box size generally represent the amount visible (vs the total scrollable amount)
3174    // But we maintain a minimum size in pixel to allow for the user to still aim inside.
3175    const float grab_h_pixels = ImMax(style.GrabMinSize, scrollbar_height * ImSaturate(window->Size.y / ImMax(window->SizeContents.y, window->Size.y)));
3176    const float grab_h_norm = grab_h_pixels / scrollbar_height;
3177
3178    // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
3179    bool held = false;
3180    bool hovered = false;
3181    const bool previously_held = (g.ActiveId == id);
3182    ButtonBehaviour(bb, id, &hovered, &held, true);
3183
3184    const float scroll_max = ImMax(1.0f, window->SizeContents.y - window->Size.y);
3185    float scroll_ratio = ImSaturate(window->ScrollY / scroll_max);
3186    float grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height;
3187    if (held)
3188    {
3189        const float clicked_y_norm = ImSaturate((g.IO.MousePos.y - bb.Min.y) / scrollbar_height);     // Click position in scrollbar space (0.0f->1.0f)
3190        g.HoveredId = id;
3191
3192        bool seek_absolute = false;
3193        if (!previously_held)
3194        {
3195            // On initial click calculate the distance between mouse and the center of the grab
3196            if (clicked_y_norm >= grab_y_norm && clicked_y_norm <= grab_y_norm + grab_h_norm)
3197            {
3198                g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f;
3199            }
3200            else
3201            {
3202                seek_absolute = true;
3203                g.ScrollbarClickDeltaToGrabCenter = 0;
3204            }
3205        }
3206
3207        // Apply scroll
3208        const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm));
3209        window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y));
3210        window->NextScrollY = window->ScrollY;
3211
3212        // Update values for rendering
3213        scroll_ratio = ImSaturate(window->ScrollY / scroll_max);
3214        grab_y_norm = scroll_ratio * (scrollbar_height - grab_h_pixels) / scrollbar_height;
3215
3216        // Update distance to grab now that we have seeked and saturated
3217        if (seek_absolute)
3218            g.ScrollbarClickDeltaToGrabCenter = clicked_y_norm - grab_y_norm - grab_h_norm*0.5f;
3219    }
3220
3221    // Render
3222    const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
3223    window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_y_norm) + grab_h_pixels), grab_col);
3224}
3225
30573226// Moving window to front of display (which happens to be back of our sorted list)
30583227static void FocusWindow(ImGuiWindow* window)
30593228{
30603229    ImGuiState& g = *GImGui;
3230
3231    // Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing.
30613232    g.FocusedWindow = window;
30623233
3234    // And move its root window to the top of the pile
3235    if (window->RootWindow)
3236        window = window->RootWindow;
3237
30633238    if (g.Windows.back() == window)
30643239        return;
30653240
r244869r244870
31093284    g.Font = font;
31103285    g.FontSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale;
31113286    g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel;
3112    g.Font->FallbackGlyph = NULL;
3113    g.Font->FallbackGlyph = g.Font->FindGlyph(g.Font->FallbackChar);
31143287}
31153288
31163289void ImGui::PushFont(ImFont* font)
r244869r244870
32283401    ImGuiState& g = *GImGui;
32293402
32303403    ImVec2* pvar = GetStyleVarVec2Addr(idx);
3231    IM_ASSERT(pvar != NULL); // Called function with wrong-type? Varialble is not a ImVec2.
3404    IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2.
32323405    ImGuiStyleMod backup;
32333406    backup.Var = idx;
32343407    backup.PreviousValue = *pvar;
r244869r244870
33203493    return window->Pos;
33213494}
33223495
3323void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
3496static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond)
33243497{
3325    ImGuiWindow* window = GetCurrentWindow();
3326
33273498    // Test condition (NB: bit 0 is always true) and clear flags for next time
33283499    if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
33293500        return;
3330    window->SetWindowPosAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
3501    window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver);
33313502
33323503    // Set
33333504    const ImVec2 old_pos = window->Pos;
r244869r244870
33363507    window->DC.CursorPos += (window->Pos - old_pos);  // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
33373508}
33383509
3510void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCond cond)
3511{
3512    ImGuiWindow* window = GetCurrentWindow();
3513    SetWindowPos(window, pos, cond);
3514}
3515
3516void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond)
3517{
3518    ImGuiWindow* window = FindWindowByName(name);
3519    if (window)
3520        SetWindowPos(window, pos, cond);
3521}
3522
33393523ImVec2 ImGui::GetWindowSize()
33403524{
33413525    ImGuiWindow* window = GetCurrentWindow();
33423526    return window->Size;
33433527}
33443528
3345void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCondition cond)
3529static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond)
33463530{
3347    ImGuiWindow* window = GetCurrentWindow();
3348
33493531    // Test condition (NB: bit 0 is always true) and clear flags for next time
33503532    if (cond && (window->SetWindowSizeAllowFlags & cond) == 0)
33513533        return;
3352    window->SetWindowSizeAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
3534    window->SetWindowSizeAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver);
33533535
33543536    // Set
33553537    if (ImLengthSqr(size) > 0.00001f)
r244869r244870
33653547    }
33663548}
33673549
3368void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
3550void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCond cond)
33693551{
33703552    ImGuiWindow* window = GetCurrentWindow();
3553    SetWindowSize(window, size, cond);
3554}
33713555
3556void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond)
3557{
3558    ImGuiWindow* window = FindWindowByName(name);
3559    if (window)
3560        SetWindowSize(window, size, cond);
3561}
3562
3563static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond)
3564{
33723565    // Test condition (NB: bit 0 is always true) and clear flags for next time
33733566    if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0)
33743567        return;
3375    window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCondition_FirstUseThisSession | ImGuiSetCondition_FirstUseEver);
3568    window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver);
33763569
33773570    // Set
33783571    window->Collapsed = collapsed;
33793572}
33803573
3381void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond)
3574void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond)
33823575{
3576    ImGuiWindow* window = GetCurrentWindow();
3577    SetWindowCollapsed(window, collapsed, cond);
3578}
3579
3580bool ImGui::GetWindowCollapsed()
3581{
3582    ImGuiWindow* window = GetCurrentWindow();
3583    return window->Collapsed;
3584}
3585
3586void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond)
3587{
3588    ImGuiWindow* window = FindWindowByName(name);
3589    if (window)
3590        SetWindowCollapsed(window, collapsed, cond);
3591}
3592
3593void ImGui::SetWindowFocus()
3594{
3595    ImGuiWindow* window = GetCurrentWindow();
3596    FocusWindow(window);
3597}
3598
3599void ImGui::SetWindowFocus(const char* name)
3600{
3601    ImGuiWindow* window = FindWindowByName(name);
3602    if (window)
3603        FocusWindow(window);
3604}
3605
3606void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond)
3607{
33833608    ImGuiState& g = *GImGui;
33843609    g.SetNextWindowPosVal = pos;
3385    g.SetNextWindowPosCond = cond ? cond : ImGuiSetCondition_Always;
3610    g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always;
33863611}
33873612
3388void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond)
3613void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond)
33893614{
33903615    ImGuiState& g = *GImGui;
33913616    g.SetNextWindowSizeVal = size;
3392    g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCondition_Always;
3617    g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always;
33933618}
33943619
3395void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond)
3620void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond)
33963621{
33973622    ImGuiState& g = *GImGui;
33983623    g.SetNextWindowCollapsedVal = collapsed;
3399    g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCondition_Always;
3624    g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always;
34003625}
34013626
3627void ImGui::SetNextWindowFocus()
3628{
3629    ImGuiState& g = *GImGui;
3630    g.SetNextWindowFocus = true;
3631}
3632
34023633ImVec2 ImGui::GetContentRegionMax()
34033634{
34043635    ImGuiWindow* window = GetCurrentWindow();
3405    ImVec2 mx = window->Size - window->WindowPadding();
3636    ImVec2 window_padding = window->WindowPadding();
3637    ImVec2 mx = window->Size - window_padding;
34063638    if (window->DC.ColumnsCount != 1)
34073639    {
34083640        mx.x = ImGui::GetColumnOffset(window->DC.ColumnsCurrent + 1);
3409        mx.x -= GImGui->Style.WindowPadding.x;
3641        mx.x -= window_padding.x;
34103642    }
34113643    else
34123644    {
34133645        if (window->ScrollbarY)
3414            mx.x -= GImGui->Style.ScrollBarWidth;
3646            mx.x -= GImGui->Style.ScrollbarWidth;
34153647    }
34163648    return mx;
34173649}
r244869r244870
34273659    ImGuiWindow* window = GetCurrentWindow();
34283660    ImVec2 m = window->Size - window->WindowPadding();
34293661    if (window->ScrollbarY)
3430        m.x -= GImGui->Style.ScrollBarWidth;
3662        m.x -= GImGui->Style.ScrollbarWidth;
34313663    return m;
34323664}
34333665
r244869r244870
34903722{
34913723    ImGuiWindow* window = GetCurrentWindow();
34923724    window->DC.CursorPos = window->Pos + pos;
3493    window->SizeContentsFit = ImMax(window->SizeContentsFit, pos + ImVec2(0.0f, window->ScrollY));
3725    window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, pos + ImVec2(0.0f, window->ScrollY));
34943726}
34953727
34963728void ImGui::SetCursorPosX(float x)
34973729{
34983730    ImGuiWindow* window = GetCurrentWindow();
34993731    window->DC.CursorPos.x = window->Pos.x + x;
3500    window->SizeContentsFit.x = ImMax(window->SizeContentsFit.x, x);
3732    window->SizeContentsCurrent.x = ImMax(window->SizeContentsCurrent.x, x);
35013733}
35023734
35033735void ImGui::SetCursorPosY(float y)
35043736{
35053737    ImGuiWindow* window = GetCurrentWindow();
35063738    window->DC.CursorPos.y = window->Pos.y + y;
3507    window->SizeContentsFit.y = ImMax(window->SizeContentsFit.y, y + window->ScrollY);
3739    window->SizeContentsCurrent.y = ImMax(window->SizeContentsCurrent.y, y + window->ScrollY);
35083740}
35093741
35103742ImVec2 ImGui::GetCursorScreenPos()
r244869r244870
35193751    window->DC.CursorPos = screen_pos;
35203752}
35213753
3754float ImGui::GetScrollPosY()
3755{
3756    ImGuiWindow* window = GetCurrentWindow();
3757    return window->ScrollY;
3758}
3759
3760float ImGui::GetScrollMaxY()
3761{
3762    ImGuiWindow* window = GetCurrentWindow();
3763    return window->SizeContents.y - window->SizeFull.y;
3764}
3765
35223766void ImGui::SetScrollPosHere()
35233767{
35243768    ImGuiWindow* window = GetCurrentWindow();
r244869r244870
37203964    const char* value_text_begin = &buf[0];
37213965    const char* value_text_end = value_text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
37223966
3723    const ImVec2 text_size = CalcTextSize(label, NULL, true);
3724    const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, text_size.y));
3725    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (text_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), 0.0f) + text_size);
3967    const ImVec2 label_size = CalcTextSize(label, NULL, true);
3968    const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y));
3969    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), 0.0f) + label_size);
37263970    ItemSize(bb);
37273971    if (!ItemAdd(value_bb, NULL))
37283972        return;
r244869r244870
37463990    if (g.HoveredId == 0)
37473991    {
37483992        ImGuiWindow* window = GetCurrentWindow();
3749        const bool hovered = (g.HoveredRootWindow == window->RootWindow) && (g.ActiveId == 0 || g.ActiveId == id) && IsMouseHoveringBox(bb);
3750        return hovered;
3993        if (g.HoveredRootWindow == window->RootWindow)
3994        {
3995            bool hovered = (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringBox(bb);
3996            return hovered;
3997        }
37513998    }
37523999    return false;
37534000}
r244869r244870
38144061
38154062    const ImGuiStyle& style = g.Style;
38164063    const ImGuiID id = window->GetID(label);
3817    const ImVec2 text_size = CalcTextSize(label, NULL, true);
4064    const ImVec2 label_size = CalcTextSize(label, NULL, true);
38184065
3819    const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : text_size.x, size_arg.y != 0.0f ? size_arg.y : text_size.y);
4066    const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
38204067    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size + style.FramePadding*2.0f);
38214068    ItemSize(bb);
38224069    if (!ItemAdd(bb, &id))
r244869r244870
38294076    const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
38304077    RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
38314078
3832    const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f);  // Center (only applies if we explicitly gave a size bigger than the text size, which isn't the common path)
3833    RenderTextClipped(bb.Min + style.FramePadding + off, label, NULL, &text_size, bb.Max);                          // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path)
4079    const ImVec2 off = ImVec2(ImMax(0.0f, size.x - label_size.x) * 0.5f, ImMax(0.0f, size.y - label_size.y) * 0.5f); // Center (only applies if we explicitly gave a size bigger than the text size, which isn't the common path)
4080    RenderTextClipped(bb.Min + style.FramePadding + off, label, NULL, &label_size, bb.Max);                          // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path)
38344081
38354082    return pressed;
38364083}
r244869r244870
38454092
38464093    const ImGuiStyle& style = g.Style;
38474094    const ImGuiID id = window->GetID(label);
3848    const ImVec2 text_size = CalcTextSize(label, NULL, true);
4095    const ImVec2 label_size = CalcTextSize(label, NULL, true);
38494096
3850    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + text_size + ImVec2(style.FramePadding.x*2,0));
4097    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + label_size + ImVec2(style.FramePadding.x*2,0));
38514098    ItemSize(bb);
38524099    if (!ItemAdd(bb, &id))
38534100        return false;
r244869r244870
38884135{
38894136    ImGuiWindow* window = GetCurrentWindow();
38904137
3891    const ImGuiID id = window->GetID("##CLOSE");
4138    const ImGuiID id = window->GetID("#CLOSE");
38924139    const float size = window->TitleBarHeight() - 4.0f;
38934140    const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-3.0f-size,2.0f), window->Aabb().GetTR() + ImVec2(-3.0f,2.0f+size));
38944141
r244869r244870
40824329        LogToClipboard(g.LogAutoExpandMaxDepth);
40834330}
40844331
4085bool ImGui::CollapsingHeader(const char* label, const char* str_id, const bool display_frame, const bool default_open)
4332bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open)
40864333{
40874334    ImGuiState& g = *GImGui;
40884335    ImGuiWindow* window = GetCurrentWindow();
r244869r244870
40984345        label = str_id;
40994346    const ImGuiID id = window->GetID(str_id);
41004347
4101    // We only write to the tree storage if the user clicks
4348    // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions)
41024349    ImGuiStorage* storage = window->DC.StateStorage;
41034350    bool opened;
4104    if (window->DC.OpenNextNode != -1)
4351    if (g.SetNextTreeNodeOpenedCond != 0)
41054352    {
4106        opened = window->DC.OpenNextNode > 0;
4107        storage->SetInt(id, opened);
4108        window->DC.OpenNextNode = -1;
4353        if (g.SetNextTreeNodeOpenedCond & ImGuiSetCond_Always)
4354        {
4355            opened = g.SetNextTreeNodeOpenedVal;
4356            storage->SetInt(id, opened);
4357        }
4358        else
4359        {
4360            // We treat ImGuiSetCondition_Once and ImGuiSetCondition_FirstUseEver the same because tree node state are not saved persistently.
4361            const int stored_value = storage->GetInt(id, -1);
4362            if (stored_value == -1)
4363            {
4364                opened = g.SetNextTreeNodeOpenedVal;
4365                storage->SetInt(id, opened);
4366            }
4367            else
4368            {
4369                opened = stored_value != 0;
4370            }
4371        }
4372        g.SetNextTreeNodeOpenedCond = 0;
41094373    }
41104374    else
41114375    {
r244869r244870
41144378
41154379    // Framed header expand a little outside the default padding
41164380    const ImVec2 window_padding = window->WindowPadding();
4117    const ImVec2 text_size = CalcTextSize(label, NULL, true);
4381    const ImVec2 label_size = CalcTextSize(label, NULL, true);
41184382    const ImVec2 pos_min = window->DC.CursorPos;
41194383    const ImVec2 pos_max = window->Pos + GetContentRegionMax();
4120    ImGuiAabb bb = ImGuiAabb(pos_min, ImVec2(pos_max.x, pos_min.y + text_size.y));
4384    ImGuiAabb bb = ImGuiAabb(pos_min, ImVec2(pos_max.x, pos_min.y + label_size.y));
41214385    if (display_frame)
41224386    {
41234387        bb.Min.x -= window_padding.x*0.5f - 1;
r244869r244870
41254389        bb.Max.y += style.FramePadding.y * 2;
41264390    }
41274391
4128    const ImGuiAabb text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + text_size);
4392    const ImGuiAabb text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + label_size);
41294393    ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y));  // NB: we don't provide our width so that it doesn't get feed back into AutoFit
41304394
41314395    // When logging is enabled, if automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behaviour).
41324396    // NB- If we are above max depth we still allow manually opened nodes to be logged.
4133    if (!display_frame)
4134        if (g.LogEnabled && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
4135            opened = true;
4397    if (g.LogEnabled && !display_frame && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
4398        opened = true;
41364399
41374400    if (!ItemAdd(bb, &id))
41384401        return opened;
r244869r244870
41794442    return opened;
41804443}
41814444
4445void ImGui::Bullet()
4446{
4447    ImGuiState& g = *GImGui;
4448    ImGuiWindow* window = GetCurrentWindow();
4449    if (window->SkipItems)
4450        return;
4451
4452    const ImGuiStyle& style = g.Style;
4453    const float line_height = window->FontSize();
4454    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height, line_height));
4455    ItemSize(bb);
4456    if (!ItemAdd(bb, NULL))
4457        return;
4458
4459    // Render
4460    const float bullet_size = line_height*0.15f;
4461    window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text));
4462
4463    // Stay on same line
4464    ImGui::SameLine(0, -1);
4465}
4466
41824467// Text with a little bullet aligned to the typical tree node.
41834468void ImGui::BulletTextV(const char* fmt, va_list args)
41844469{
r244869r244870
41874472    if (window->SkipItems)
41884473        return;
41894474
4190    const ImGuiStyle& style = g.Style;
4191
41924475    static char buf[1024];
41934476    const char* text_begin = buf;
41944477    const char* text_end = text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
41954478
4479    const ImGuiStyle& style = g.Style;
41964480    const float line_height = window->FontSize();
4197    const ImVec2 text_size = CalcTextSize(text_begin, text_end, true);
4198    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (text_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + text_size);  // Empty text doesn't add padding
4481    const ImVec2 label_size = CalcTextSize(text_begin, text_end, true);
4482    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (label_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + label_size);  // Empty text doesn't add padding
41994483    ItemSize(bb);
42004484    if (!ItemAdd(bb, NULL))
42014485        return;
r244869r244870
42754559    return TreeNode(str_label_id, "%s", str_label_id);
42764560}
42774561
4278void ImGui::OpenNextNode(bool open)
4562void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond)
42794563{
4280    ImGuiWindow* window = GetCurrentWindow();
4281    window->DC.OpenNextNode = open ? 1 : 0;
4564    ImGuiState& g = *GImGui;
4565    g.SetNextTreeNodeOpenedVal = opened;
4566    g.SetNextTreeNodeOpenedCond = cond ? cond : ImGuiSetCond_Always;
42824567}
42834568
42844569void ImGui::PushID(const char* str_id)
r244869r244870
43224607// NB: only call right after InputText because we are using its InitialValue storage
43234608static void ApplyNumericalTextInput(const char* buf, float *v)
43244609{
4325    while (*buf == ' ' || *buf == '\t')
4610    while (ImCharIsSpace(*buf))
43264611        buf++;
43274612
43284613    // We don't support '-' op because it would conflict with inputing negative value.
r244869r244870
43314616    if (op == '+' || op == '*' || op == '/')
43324617    {
43334618        buf++;
4334        while (*buf == ' ' || *buf == '\t')
4619        while (ImCharIsSpace(*buf))
43354620            buf++;
43364621    }
43374622    else
r244869r244870
43954680        }
43964681    }
43974682
4398    const ImVec2 text_size = CalcTextSize(label, NULL, true);
4399    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
4683    const ImVec2 label_size = CalcTextSize(label, NULL, true);
4684    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
44004685    const ImGuiAabb slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
4401    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(text_size.x > 0.0f ? style.ItemInnerSpacing.x + text_size.x : 0.0f, 0.0f));
4686    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
44024687
44034688    // NB- we don't call ItemSize() yet becausae we may turn into a text edit box later in the function
44044689    if (!ItemAdd(slider_bb, &id))
r244869r244870
44144699    const float grab_size_in_units = 1.0f;                                                              // In 'v' units. Probably needs to be parametrized, based on a 'v_step' value? decimal precision?
44154700    float grab_size_in_pixels;
44164701    if (decimal_precision > 0 || is_unbound)
4417        grab_size_in_pixels = 10.0f;
4702        grab_size_in_pixels = style.GrabMinSize;
44184703    else
4419        grab_size_in_pixels = ImMax(grab_size_in_units * (w / (v_max-v_min+1.0f)), 8.0f);               // Integer sliders
4704        grab_size_in_pixels = ImMax(grab_size_in_units * (w / (v_max-v_min+1.0f)), style.GrabMinSize);  // Integer sliders
44204705    const float slider_effective_w = slider_bb.GetWidth() - grab_size_in_pixels;
44214706    const float slider_effective_x1 = slider_bb.Min.x + grab_size_in_pixels*0.5f;
44224707    const float slider_effective_x2 = slider_bb.Max.x - grab_size_in_pixels*0.5f;
r244869r244870
44714756        if (g.SliderAsInputTextId == 0)
44724757        {
44734758            // First frame
4474            IM_ASSERT(g.ActiveId == id);    // InputText ID should match the Slider ID (else we'd need to store them both which is also possible)
4759            IM_ASSERT(g.ActiveId == id);    // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible)
44754760            g.SliderAsInputTextId = g.ActiveId;
4476            SetActiveId(id);
44774761            g.HoveredId = id;
44784762        }
4479        else
4763        else if (g.ActiveId != g.SliderAsInputTextId)
44804764        {
4481            if (g.ActiveId == g.SliderAsInputTextId)
4482                SetActiveId(id);
4483            else
4484            {
4485                SetActiveId(0);
4486                g.SliderAsInputTextId = 0;
4487            }
4765            // Release
4766            g.SliderAsInputTextId = 0;
44884767        }
44894768        if (value_changed)
44904769        {
r244869r244870
45794858
45804859    // Draw value using user-provided display format so user can add prefix/suffix/decorations to the value.
45814860    char value_buf[64];
4582    ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
4583    RenderText(ImVec2(slider_bb.GetCenter().x-CalcTextSize(value_buf, NULL, true).x*0.5f, frame_bb.Min.y + style.FramePadding.y), value_buf);
4861    char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
4862    const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true);
4863    RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, slider_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max);
45844864
45854865    RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label);
45864866
r244869r244870
47215001
47225002    const ImGuiStyle& style = g.Style;
47235003
4724    const ImVec2 text_size = ImGui::CalcTextSize(label, NULL, true);
5004    const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
47255005    if (graph_size.x == 0.0f)
47265006        graph_size.x = ImGui::CalcItemWidth();
47275007    if (graph_size.y == 0.0f)
4728        graph_size.y = text_size.y;
5008        graph_size.y = label_size.y;
47295009
47305010    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y) + style.FramePadding*2.0f);
47315011    const ImGuiAabb graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
4732    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(text_size.x > 0.0f ? style.ItemInnerSpacing.x + text_size.x : 0.0f, 0));
5012    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0));
47335013    ItemSize(bb);
47345014    if (!ItemAdd(bb, NULL))
47355015        return;
r244869r244870
48545134
48555135    const ImGuiStyle& style = g.Style;
48565136    const ImGuiID id = window->GetID(label);
4857    const ImVec2 text_size = CalcTextSize(label, NULL, true);
5137    const ImVec2 label_size = CalcTextSize(label, NULL, true);
48585138
4859    const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(text_size.y + style.FramePadding.y*2, text_size.y + style.FramePadding.y*2));
5139    const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2));
48605140    ItemSize(check_bb);
48615141
48625142    ImGuiAabb total_bb = check_bb;
4863    if (text_size.x > 0)
5143    if (label_size.x > 0)
48645144        SameLine(0, (int)style.ItemInnerSpacing.x);
4865    const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + text_size);
4866    if (text_size.x > 0)
5145    const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size);
5146    if (label_size.x > 0)
48675147    {
48685148        ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()));
48695149        total_bb = ImGuiAabb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));
r244869r244870
49125192
49135193    const ImGuiStyle& style = g.Style;
49145194    const ImGuiID id = window->GetID(label);
5195    const ImVec2 label_size = CalcTextSize(label, NULL, true);
49155196
4916    const ImVec2 text_size = CalcTextSize(label, NULL, true);
4917
4918    const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(text_size.y + style.FramePadding.y*2-1, text_size.y + style.FramePadding.y*2-1));
5197    const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1));
49195198    ItemSize(check_bb);
49205199
49215200    ImGuiAabb total_bb = check_bb;
4922    if (text_size.x > 0)
5201    if (label_size.x > 0)
49235202        SameLine(0, (int)style.ItemInnerSpacing.x);
4924    const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + text_size);
4925    if (text_size.x > 0)
5203    const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size);
5204    if (label_size.x > 0)
49265205    {
49275206        ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()));
49285207        total_bb.Add(text_bb);
r244869r244870
49885267    r->num_chars = (int)(text_remaining - (obj->Text + line_start_idx));
49895268}
49905269
4991static bool is_white(unsigned int c)                                                              { return c==0 || c==' ' || c=='\t' || c=='\r' || c=='\n'; }
49925270static bool is_separator(unsigned int c)                                                          { return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
4993#define STB_TEXTEDIT_IS_SPACE(CH)                                                                 ( is_white((unsigned int)CH) || is_separator((unsigned int)CH) )
4994static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)                    { ImWchar* dst = obj->Text+pos; const ImWchar* src = obj->Text+pos+n; while (ImWchar c = *src++) *dst++ = c; *dst = '\0'; }
5271#define STB_TEXTEDIT_IS_SPACE(CH)                                                                 ( ImCharIsSpace((unsigned int)CH) || is_separator((unsigned int)CH) )
5272static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)
5273{
5274    ImWchar* dst = obj->Text + pos;
5275
5276    // We maintain our buffer length in both UTF-8 and wchar formats
5277    obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n);
5278    obj->CurLenW -= n;
5279
5280    // Offset remaining text
5281    const ImWchar* src = obj->Text + pos + n;
5282    while (ImWchar c = *src++)
5283        *dst++ = c;
5284    *dst = '\0';
5285}
5286
49955287static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len)
49965288{
4997    const size_t text_len = ImStrlenW(obj->Text);
4998    if ((size_t)new_text_len + text_len + 1 >= obj->BufSize)
5289    const size_t text_len = obj->CurLenW;
5290    if ((size_t)new_text_len + text_len + 1 > IM_ARRAYSIZE(obj->Text))
49995291        return false;
50005292
5293    const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len);
5294    if ((size_t)new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA)
5295        return false;
5296
50015297    if (pos != (int)text_len)
50025298        memmove(obj->Text + (size_t)pos + new_text_len, obj->Text + (size_t)pos, (text_len - (size_t)pos) * sizeof(ImWchar));
50035299    memcpy(obj->Text + (size_t)pos, new_text, (size_t)new_text_len * sizeof(ImWchar));
5004    obj->Text[text_len + (size_t)new_text_len] = '\0';
50055300
5301    obj->CurLenW += new_text_len;
5302    obj->CurLenA += new_text_len_utf8;
5303    obj->Text[obj->CurLenW] = '\0';
5304
50065305    return true;
50075306}
50085307
r244869r244870
50965395    const char* text_start = GetTextPointerClippedA(font, font_size, buf, scroll_x, NULL);
50975396    const char* text_end = GetTextPointerClippedA(font, font_size, text_start, width, &text_size);
50985397
5398    // We need to test for the possibility of malformed UTF-8 (instead of just text_end[0] != 0)
5399    unsigned int text_end_char = 0;
5400    ImTextCharFromUtf8(&text_end_char, text_end, NULL);
5401
50995402    // Draw a little clip symbol if we've got text on either left or right of the box
51005403    const char symbol_c = '~';
51015404    const float symbol_w = font_size*0.40f;     // FIXME: compute correct width
51025405    const float clip_begin = (text_start > buf && text_start < text_end) ? symbol_w : 0.0f;
5103    const float clip_end = (text_end[0] != '\0' && text_end > text_start) ? symbol_w : 0.0f;
5406    const float clip_end = (text_end_char != 0 && text_end > text_start) ? symbol_w : 0.0f;
51045407
51055408    // Draw text
51065409    RenderText(pos+ImVec2(clip_begin,0), text_start+(clip_begin>0.0f?1:0), text_end-(clip_end>0.0f?1:0), false);
r244869r244870
51225425
51235426    const ImGuiStyle& style = g.Style;
51245427    const float w = ImGui::CalcItemWidth();
5125    const ImVec2 text_size = CalcTextSize(label, NULL, true);
5126    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
5428    const ImVec2 label_size = CalcTextSize(label, NULL, true);
5429    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
51275430
51285431    ImGui::PushID(label);
51295432    const float button_sz = window->FontSize();
r244869r244870
51635466
51645467    ImGui::PopID();
51655468
5166    if (text_size.x > 0)
5469    if (label_size.x > 0)
51675470    {
51685471        ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
5169        ItemSize(text_size);
5472        ItemSize(label_size);
51705473        RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
51715474    }
51725475
r244869r244870
52225525    SelectionStart = SelectionEnd = CursorPos;
52235526}
52245527
5225static bool InputTextFilterCharacter(ImWchar c, ImGuiInputTextFlags flags)
5528// Return false to discard a character.
5529static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)
52265530{
5531    unsigned int c = *p_char;
5532
52275533    if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF)))
5228        return true;
5534        return false;
52295535
52305536    if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys.
5231        return true;
5537        return false;
52325538
5233    if (flags & ImGuiInputTextFlags_CharsDecimal)
5234        if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
5235            return true;
5539    if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank))
5540    {
5541        if (flags & ImGuiInputTextFlags_CharsDecimal)
5542            if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
5543                return false;
52365544
5237    if (flags & ImGuiInputTextFlags_CharsHexadecimal)
5238        if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
5239            return true;
5545        if (flags & ImGuiInputTextFlags_CharsHexadecimal)
5546            if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
5547                return false;
52405548
5241    return false;
5549        if (flags & ImGuiInputTextFlags_CharsUppercase)
5550            if (c >= 'a' && c <= 'z')
5551                *p_char = (c += (unsigned int)('A'-'a'));
5552
5553        if (flags & ImGuiInputTextFlags_CharsNoBlank)
5554            if (ImCharIsSpace(c))
5555                return false;
5556    }
5557
5558    if (flags & ImGuiInputTextFlags_CallbackCharFilter)
5559    {
5560        ImGuiTextEditCallbackData callback_data;
5561        memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData));
5562        callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter;
5563        callback_data.EventChar = c;
5564        callback_data.Flags = flags;
5565        callback_data.UserData = user_data;
5566        if (callback(&callback_data) != 0)
5567            return false;
5568        *p_char = callback_data.EventChar;
5569        if (!callback_data.EventChar)
5570            return false;
5571    }
5572
5573    return true;
52425574}
52435575
52445576// Edit a string of text
5245bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, void (*callback)(ImGuiTextEditCallbackData*), void* user_data)
5577bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)
52465578{
52475579    ImGuiState& g = *GImGui;
52485580    ImGuiWindow* window = GetCurrentWindow();
r244869r244870
52555587    const ImGuiID id = window->GetID(label);
52565588    const float w = ImGui::CalcItemWidth();
52575589
5258    const ImVec2 text_size = CalcTextSize(label, NULL, true);
5259    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
5260    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(text_size.x > 0.0f ? (style.ItemInnerSpacing.x + text_size.x) : 0.0f, 0.0f));
5590    const ImVec2 label_size = CalcTextSize(label, NULL, true);
5591    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
5592    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f));
52615593    ItemSize(bb);
52625594    if (!ItemAdd(frame_bb, &id))
52635595        return false;
r244869r244870
52675599
52685600    const bool is_ctrl_down = io.KeyCtrl;
52695601    const bool is_shift_down = io.KeyShift;
5270    const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id, (flags & ImGuiInputTextFlags_CallbackCompletion) == 0);    // Using completion callback disable keyboard tabbing
5271    //const bool align_center = (bool)(flags & ImGuiInputTextFlags_AlignCenter);    // FIXME: Unsupported
5602    const bool focus_requested = window->FocusItemRegister(g.ActiveId == id, (flags & ImGuiInputTextFlags_CallbackCompletion) == 0);    // Using completion callback disable keyboard tabbing
5603    const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent);
5604    const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code;
52725605
52735606    const bool hovered = IsHovered(frame_bb, id);
52745607    if (hovered)
52755608        g.HoveredId = id;
5609    const bool user_clicked = hovered && io.MouseClicked[0];
52765610
52775611    bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0;
5278    if (tab_focus_requested || (hovered && io.MouseClicked[0]))
5612    if (focus_requested || user_clicked)
52795613    {
52805614        if (g.ActiveId != id)
52815615        {
52825616            // Start edition
52835617            // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar)
5618            // From the moment we focused we are ignoring the content of 'buf'
52845619            ImFormatString(edit_state.InitialText, IM_ARRAYSIZE(edit_state.InitialText), "%s", buf);
5285            ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), buf, NULL);
5286            edit_state.ScrollX = 0.0f;
5620            const char* buf_end = NULL;
5621            edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), buf, NULL, &buf_end);
5622            edit_state.CurLenA = buf_end - buf; // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
52875623            edit_state.Width = w;
5288            stb_textedit_initialize_state(&edit_state.StbState, true);
5624            edit_state.InputCursorScreenPos = ImVec2(-1.f,-1.f);
52895625            edit_state.CursorAnimReset();
5290            edit_state.LastCursorPos = ImVec2(-1.f,-1.f);
52915626
5292            if (tab_focus_requested || is_ctrl_down)
5627            if (edit_state.Id != id)
5628            {
5629                edit_state.Id = id;
5630                edit_state.ScrollX = 0.0f;
5631                stb_textedit_initialize_state(&edit_state.StbState, true);
5632                if (focus_requested_by_code)
5633                    select_all = true;
5634            }
5635            else
5636            {
5637                // Recycle existing cursor/selection/undo stack but clamp position
5638                // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
5639                edit_state.StbState.cursor = ImMin(edit_state.StbState.cursor, edit_state.CurLenW);
5640                edit_state.StbState.select_start = ImMin(edit_state.StbState.select_start, edit_state.CurLenW);
5641                edit_state.StbState.select_end = ImMin(edit_state.StbState.select_end, edit_state.CurLenW);
5642            }
5643            if (focus_requested_by_tab || (user_clicked && is_ctrl_down))
52935644                select_all = true;
52945645        }
52955646        SetActiveId(id);
r244869r244870
53045655        }
53055656    }
53065657
5658    // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
5659    // Down the line we should have a cleaner concept of focused vs active in the library.
5660    if (g.ActiveId == id)
5661        g.ActiveIdIsFocusedOnly = !io.MouseDown[0];
5662
53075663    bool value_changed = false;
53085664    bool cancel_edit = false;
53095665    bool enter_pressed = false;
r244869r244870
53115667    if (g.ActiveId == id)
53125668    {
53135669        // Edit in progress
5314        edit_state.BufSize = buf_size < IM_ARRAYSIZE(edit_state.Text) ? buf_size : IM_ARRAYSIZE(edit_state.Text);
5670        edit_state.BufSizeA = buf_size;
53155671        edit_state.Font = window->Font();
53165672        edit_state.FontSize = window->FontSize();
53175673
r244869r244870
53435699            // Process text input (before we check for Return because using some IME will effectively send a Return?)
53445700            for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
53455701            {
5346                const ImWchar c = g.IO.InputCharacters[n];
5702                unsigned int c = (unsigned int)g.IO.InputCharacters[n];
53475703                if (c)
53485704                {
53495705                    // Insert character if they pass filtering
5350                    if (InputTextFilterCharacter(c, flags))
5706                    if (!InputTextFilterCharacter(&c, flags, callback, user_data))
53515707                        continue;
5352                    edit_state.OnKeyPressed(c);
5708                    edit_state.OnKeyPressed((int)c);
53535709                }
53545710            }
53555711
r244869r244870
53795735            if (g.IO.SetClipboardTextFn)
53805736            {
53815737                const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0;
5382                const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : (int)ImStrlenW(edit_state.Text);
5738                const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW;
53835739                ImTextStrToUtf8(text_tmp_utf8, IM_ARRAYSIZE(text_tmp_utf8), edit_state.Text+ib, edit_state.Text+ie);
53845740                g.IO.SetClipboardTextFn(text_tmp_utf8);
53855741            }
r244869r244870
53955751                if (const char* clipboard = g.IO.GetClipboardTextFn())
53965752                {
53975753                    // Remove new-line from pasted buffer
5398                    size_t clipboard_len = strlen(clipboard);
5754                    const size_t clipboard_len = strlen(clipboard);
53995755                    ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar));
54005756                    int clipboard_filtered_len = 0;
54015757                    for (const char* s = clipboard; *s; )
54025758                    {
54035759                        unsigned int c;
5404                        const int bytes_count = ImTextCharFromUtf8(&c, s, NULL);
5405                        if (bytes_count <= 0)
5760                        s += ImTextCharFromUtf8(&c, s, NULL);
5761                        if (c == 0)
54065762                            break;
5407                        s += bytes_count;
54085763                        if (c >= 0x10000)
54095764                            continue;
5410                        if (InputTextFilterCharacter((ImWchar)c, flags))
5765                        if (!InputTextFilterCharacter(&c, flags, callback, user_data))
54115766                            continue;
54125767                        clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c;
54135768                    }
r244869r244870
54425797                IM_ASSERT(callback != NULL);
54435798
54445799                // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment.
5800                ImGuiInputTextFlags event_flag = 0;
54455801                ImGuiKey event_key = ImGuiKey_COUNT;
54465802                if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab))
5803                {
5804                    event_flag = ImGuiInputTextFlags_CallbackCompletion;
54475805                    event_key = ImGuiKey_Tab;
5806                }
54485807                else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow))
5808                {
5809                    event_flag = ImGuiInputTextFlags_CallbackHistory;
54495810                    event_key = ImGuiKey_UpArrow;
5811                }
54505812                else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow))
5813                {
5814                    event_flag = ImGuiInputTextFlags_CallbackHistory;
54515815                    event_key = ImGuiKey_DownArrow;
5816                }
54525817
54535818                if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0)
54545819                {
54555820                    ImGuiTextEditCallbackData callback_data;
5821                    callback_data.EventFlag = event_flag;
54565822                    callback_data.EventKey = event_key;
54575823                    callback_data.Buf = text_tmp_utf8;
5458                    callback_data.BufSize = edit_state.BufSize;
5824                    callback_data.BufSize = edit_state.BufSizeA;
54595825                    callback_data.BufDirty = false;
54605826                    callback_data.Flags = flags;
54615827                    callback_data.UserData = user_data;
54625828
54635829                    // We have to convert from position from wchar to UTF-8 positions
5464                    const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.cursor);
5465                    const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.select_start);
5466                    const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.select_end);
5830                    const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.cursor);
5831                    const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_start);
5832                    const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(edit_state.Text, edit_state.Text + edit_state.StbState.select_end);
54675833
54685834                    // Call user code
54695835                    callback(&callback_data);
54705836
54715837                    // Read back what user may have modified
54725838                    IM_ASSERT(callback_data.Buf == text_tmp_utf8);             // Invalid to modify those fields
5473                    IM_ASSERT(callback_data.BufSize == edit_state.BufSize);
5839                    IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA);
54745840                    IM_ASSERT(callback_data.Flags == flags);
54755841                    if (callback_data.CursorPos != utf8_cursor_pos)            edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos);
54765842                    if (callback_data.SelectionStart != utf8_selection_start)  edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart);
r244869r244870
55095875        }
55105876    }
55115877
5512    // FIXME: 'align_center' unsupported
55135878    ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w, (g.ActiveId == id) ? edit_state.ScrollX : 0.0f);
55145879
55155880    if (g.ActiveId == id)
r244869r244870
55205885        if (g.InputTextState.CursorIsVisible())
55215886            window->DrawList->AddRect(cursor_pos - font_off_up + ImVec2(0,2), cursor_pos + font_off_dn - ImVec2(0,3), window->Color(ImGuiCol_Text));
55225887
5523        // Notify OS of text input position
5524        if (io.ImeSetInputScreenPosFn && ImLengthSqr(edit_state.LastCursorPos - cursor_pos) > 0.0001f)
5888        // Notify OS of text input position for advanced IME
5889        if (io.ImeSetInputScreenPosFn && ImLengthSqr(edit_state.InputCursorScreenPos - cursor_pos) > 0.0001f)
55255890            io.ImeSetInputScreenPosFn((int)cursor_pos.x - 1, (int)(cursor_pos.y - window->FontSize()));   // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.
55265891
5527        edit_state.LastCursorPos = cursor_pos;
5892        edit_state.InputCursorScreenPos = cursor_pos;
55285893    }
55295894
5530    RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
5895    if (label_size.x > 0)
5896        RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
55315897
55325898    if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0)
55335899        return enter_pressed;
r244869r244870
56466012    const ImGuiID id = window->GetID(label);
56476013    const float w = ImGui::CalcItemWidth();
56486014
5649    const ImVec2 text_size = CalcTextSize(label, NULL, true);
5650    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
5651    ItemSize(frame_bb);
6015    const ImVec2 label_size = CalcTextSize(label, NULL, true);
6016    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f);
6017    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0));
6018    ItemSize(bb);
56526019    if (!ItemAdd(frame_bb, &id))
56536020        return false;
56546021
5655    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + text_size.x,0));
56566022    const float arrow_size = (window->FontSize() + style.FramePadding.x * 2.0f);
56576023    const bool hovered = IsHovered(frame_bb, id);
56586024
r244869r244870
56696035            RenderTextClipped(frame_bb.Min + style.FramePadding, item_text, NULL, NULL, value_bb.Max);
56706036    }
56716037
5672    // Empty text doesn't add padding
5673    if (text_size.x > 0)
5674    {
5675        ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
5676        ImGui::TextUnformatted(label, FindTextDisplayEnd(label));
5677    }
6038    if (label_size.x > 0)
6039        RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
56786040
56796041    ImGui::PushID((int)id);
56806042    bool menu_toggled = false;
r244869r244870
56986060
56996061        const ImVec2 backup_pos = ImGui::GetCursorPos();
57006062        const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x;
5701        const float popup_height = (text_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + style.WindowPadding.y;
6063        const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + style.WindowPadding.y;
57026064        const ImGuiAabb popup_aabb(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height));
57036065        ImGui::SetCursorPos(popup_aabb.Min - window->Pos);
57046066
r244869r244870
57526114
57536115    const ImGuiStyle& style = g.Style;
57546116    const ImGuiID id = window->GetID(label);
5755    const ImVec2 text_size = CalcTextSize(label, NULL, true);
6117    const ImVec2 label_size = CalcTextSize(label, NULL, true);
57566118
57576119    const float w = window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x;
5758    const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : text_size.y);
6120    const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y);
57596121    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size);
57606122    ItemSize(bb);
57616123
r244869r244870
57836145    }
57846146
57856147    //const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f);
5786    RenderTextClipped(bb.Min, label, NULL, &text_size, bb_with_spacing.Max);
6148    RenderTextClipped(bb.Min, label, NULL, &label_size, bb_with_spacing.Max);
57876149
57886150    return pressed;
57896151}
r244869r244870
58036165bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
58046166{
58056167    ImGuiWindow* window = GetCurrentWindow();
5806    if (window->SkipItems)
5807        return false;
58086168
58096169    const ImGuiStyle& style = ImGui::GetStyle();
58106170    const ImGuiID id = ImGui::GetID(label);
r244869r244870
58166176    size.y = (size_arg.y != 0.0f) ? size_arg.y : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y;
58176177    const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
58186178    const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
6179    const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
6180    window->DC.LastItemAabb = bb;
58196181
58206182    if (label_size.x > 0)
58216183        RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
r244869r244870
58426204
58436205void ImGui::ListBoxFooter()
58446206{
6207    ImGuiWindow* parent_window = GetParentWindow();
6208    const ImGuiAabb bb = parent_window->DC.LastItemAabb;
6209
58456210    ImGui::EndChildFrame();
6211
6212    parent_window->DC.CursorPos = bb.Min;
6213    ItemSize(bb, NULL);
58466214}
58476215
58486216bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items)
r244869r244870
58536221
58546222bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
58556223{
6224    ImGuiWindow* window = GetCurrentWindow();
6225    if (window->SkipItems)
6226        return false;
6227
58566228    if (!ImGui::ListBoxHeader(label, items_count, height_in_items))
58576229        return false;
58586230
r244869r244870
58866258        return false;
58876259
58886260    const ImGuiStyle& style = g.Style;
5889    const ImGuiID id = window->GetID("##colorbutton");
6261    const ImGuiID id = window->GetID("#colorbutton");
58906262    const float square_size = window->FontSize();
58916263    const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2)));
58926264    ItemSize(bb);
r244869r244870
60066378            value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal);
60076379            ImGui::PopItemWidth();
60086380            char* p = buf;
6009            while (*p == '#' || *p == ' ' || *p == '\t')
6381            while (*p == '#' || ImCharIsSpace(*p))
60106382                p++;
60116383
60126384            // Treat at unsigned (%X is unsigned)
r244869r244870
60946466    window->DrawList->AddLine(bb.Min, bb.Max, window->Color(ImGuiCol_Border));
60956467
60966468    if (window->DC.ColumnsCount > 1)
6469    {
60976470        PushColumnClipRect();
6471        window->DC.ColumnsCellMinY = window->DC.CursorPos.y;
6472    }
60986473}
60996474
61006475// A little vertical spacing.
r244869r244870
61236498    window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
61246499    window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));
61256500
6126    window->SizeContentsFit = ImMax(window->SizeContentsFit, ImVec2(window->DC.CursorPosPrevLine.x, window->DC.CursorPos.y) - window->Pos + ImVec2(0.0f, window->ScrollY));
6501    window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, ImVec2(window->DC.CursorPosPrevLine.x - window->Pos.x, window->DC.CursorPos.y + window->ScrollY - window->Pos.y));
61276502
61286503    window->DC.PrevLineHeight = line_height;
61296504    window->DC.CurrentLineHeight = 0.0f;
61306505}
61316506
6132static void ItemSize(const ImGuiAabb& aabb, ImVec2* adjust_start_offset)
6507static void ItemSize(const ImGuiAabb& bb, ImVec2* adjust_start_offset)
61336508{
6134    ItemSize(aabb.GetSize(), adjust_start_offset);
6509    ItemSize(bb.GetSize(), adjust_start_offset);
61356510}
61366511
61376512static bool IsClipped(const ImGuiAabb& bb)
r244869r244870
61606535        window->DC.LastItemHovered = false;
61616536        return false;
61626537    }
6163    window->DC.LastItemHovered = IsMouseHoveringBox(bb);     // this is a sensible default but widgets are free to override it after calling ItemAdd()
6538
6539    // This is a sensible default, but widgets are free to override it after calling ItemAdd()
6540    const bool hovered = IsMouseHoveringBox(bb);
6541    //const bool hovered = (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly) && IsMouseHoveringBox(bb);  // matching the behaviour of IsHovered(), not always what the user wants?
6542    window->DC.LastItemHovered = hovered;
61646543    return true;
61656544}
61666545
r244869r244870
62256604    }
62266605}
62276606
6228// FIMXE-OPT: This is called too often. We need to cache offset for active columns set.
6607int ImGui::GetColumnIndex()
6608{
6609    ImGuiWindow* window = GetCurrentWindow();
6610    return window->DC.ColumnsCurrent;
6611}
6612
6613int ImGui::GetColumnsCount()
6614{
6615    ImGuiWindow* window = GetCurrentWindow();
6616    return window->DC.ColumnsCount;
6617}
6618
62296619float ImGui::GetColumnOffset(int column_index)
62306620{
62316621    ImGuiState& g = *GImGui;
r244869r244870
62336623    if (column_index < 0)
62346624        column_index = window->DC.ColumnsCurrent;
62356625
6236    const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
6237    RegisterAliveId(column_id);
6238    const float default_t = column_index / (float)window->DC.ColumnsCount;
6239    const float t = window->StateStorage.GetFloat(column_id, default_t);      // Cheaply store our floating point value inside the integer (could store an union into the map?)
6626    // Read from cache
6627    IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size());
6628    const float t = window->DC.ColumnsOffsetsT[column_index];
62406629
6241    const float offset = window->DC.ColumnsStartX + t * (window->Size.x - g.Style.ScrollBarWidth - window->DC.ColumnsStartX);
6630    const float min_x = window->DC.ColumnsStartX;
6631    const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x;
6632    const float offset = min_x + t * (max_x - min_x);
62426633    return offset;
62436634}
62446635
r244869r244870
62496640    if (column_index < 0)
62506641        column_index = window->DC.ColumnsCurrent;
62516642
6643    IM_ASSERT(column_index < (int)window->DC.ColumnsOffsetsT.size());
62526644    const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
6253    const float t = (offset - window->DC.ColumnsStartX) / (window->Size.x - g.Style.ScrollBarWidth - window->DC.ColumnsStartX);
6254    window->StateStorage.SetFloat(column_id, t);
6645
6646    const float min_x = window->DC.ColumnsStartX;
6647    const float max_x = window->Size.x - (g.Style.ScrollbarWidth);// - window->WindowPadding().x;
6648    const float t = (offset - min_x) / (max_x - min_x);
6649    window->DC.StateStorage->SetFloat(column_id, t);
6650    window->DC.ColumnsOffsetsT[column_index] = t;
62556651}
62566652
62576653float ImGui::GetColumnWidth(int column_index)
r244869r244870
62796675{
62806676    ImGuiState& g = *GImGui;
62816677    ImGuiWindow* window = GetCurrentWindow();
6282    if (window->SkipItems)
6283        return;
62846678
62856679    if (window->DC.ColumnsCount != 1)
62866680    {
r244869r244870
62946688    }
62956689
62966690    // Draw columns borders and handle resize at the time of "closing" a columns set
6297    if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders)
6691    if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders && !window->SkipItems)
62986692    {
62996693        const float y1 = window->DC.ColumnsStartPos.y;
63006694        const float y2 = window->DC.CursorPos.y;
r244869r244870
63386732
63396733    if (window->DC.ColumnsCount != 1)
63406734    {
6735        // Cache column offsets
6736        window->DC.ColumnsOffsetsT.resize((size_t)columns_count + 1);
6737        for (int column_index = 0; column_index < columns_count + 1; column_index++)
6738        {
6739            const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(column_index);
6740            RegisterAliveId(column_id);
6741            const float default_t = column_index / (float)window->DC.ColumnsCount;
6742            const float t = window->DC.StateStorage->GetFloat(column_id, default_t);      // Cheaply store our floating point value inside the integer (could store an union into the map?)
6743            window->DC.ColumnsOffsetsT[column_index] = t;
6744        }
6745
63416746        PushColumnClipRect();
63426747        ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f);
63436748    }
6749    else
6750    {
6751        window->DC.ColumnsOffsetsT.resize(2);
6752        window->DC.ColumnsOffsetsT[0] = 0.0f;
6753        window->DC.ColumnsOffsetsT[1] = 1.0f;
6754    }
63446755}
63456756
63466757void ImGui::TreePush(const char* str_id)
r244869r244870
71467557    TexUvWhitePixel = ImVec2((TexExtraDataPos.x + 0.5f) / TexWidth, (TexExtraDataPos.y + 0.5f) / TexHeight);
71477558
71487559    // Draw a mouse cursor into texture
7149    // Because our font uses an alpha texture, we have to spread the cursor in 2 parts (black/white) which will be rendered separately.
7560    // Because our font uses a single color channel, we have to spread the cursor in 2 layers (black/white) which will be rendered separately.
71507561    const char cursor_pixels[] =
71517562    {
71527563        "X           "
r244869r244870
71957606    DisplayOffset = ImVec2(-0.5f, 0.5f);
71967607    ContainerAtlas = NULL;
71977608    Glyphs.clear();
7609    FallbackGlyph = NULL;
7610    FallbackXAdvance = 0.0f;
7611    IndexXAdvance.clear();
71987612    IndexLookup.clear();
7199    FallbackGlyph = NULL;
72007613}
72017614
72027615// Retrieve list of range (2 int per range, values are inclusive)
r244869r244870
72157628    static const ImWchar ranges[] =
72167629    {
72177630        0x0020, 0x00FF, // Basic Latin + Latin Supplement
7218        0x3040, 0x309F, // Hiragana, Katakana
7631        0x3000, 0x30FF, // Punctuations, Hiragana, Katakana
7632        0x31F0, 0x31FF, // Katakana Phonetic Extensions
72197633        0xFF00, 0xFFEF, // Half-width characters
72207634        0x4e00, 0x9FAF, // CJK Ideograms
72217635        0,
r244869r244870
72637677        109,2,18,23,0,0,9,61,3,0,28,41,77,27,19,17,81,5,2,14,5,83,57,252,14,154,263,14,20,8,13,6,57,39,38,
72647678    };
72657679    static int ranges_unpacked = false;
7266    static ImWchar ranges[6 + 1 + IM_ARRAYSIZE(offsets_from_0x4E00)*2] =
7680    static ImWchar ranges[8 + IM_ARRAYSIZE(offsets_from_0x4E00)*2 + 1] =
72677681    {
72687682        0x0020, 0x00FF, // Basic Latin + Latin Supplement
7269        0x3040, 0x309F, // Hiragana, Katakana
7683        0x3000, 0x30FF, // Punctuations, Hiragana, Katakana
7684        0x31F0, 0x31FF, // Katakana Phonetic Extensions
72707685        0xFF00, 0xFFEF, // Half-width characters
7271        0,
72727686    };
72737687    if (!ranges_unpacked)
72747688    {
72757689        // Unpack
72767690        int codepoint = 0x4e00;
7277        ImWchar* dst = &ranges[6];
7691        ImWchar* dst = &ranges[8];
72787692        for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2)
72797693            dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1));
72807694        dst[0] = 0;
r244869r244870
72897703    for (size_t i = 0; i != Glyphs.size(); i++)
72907704        max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
72917705
7706    IndexXAdvance.clear();
7707    IndexXAdvance.resize((size_t)max_codepoint + 1);
72927708    IndexLookup.clear();
72937709    IndexLookup.resize((size_t)max_codepoint + 1);
7294    for (size_t i = 0; i < IndexLookup.size(); i++)
7710    for (size_t i = 0; i < (size_t)max_codepoint + 1; i++)
7711    {
7712        IndexXAdvance[i] = -1.0f;
72957713        IndexLookup[i] = -1;
7714    }
72967715    for (size_t i = 0; i < Glyphs.size(); i++)
7297        IndexLookup[(int)Glyphs[i].Codepoint] = (int)i;
7716    {
7717        const size_t codepoint = (int)Glyphs[i].Codepoint;
7718        IndexXAdvance[codepoint] = Glyphs[i].XAdvance;
7719        IndexLookup[codepoint] = (int)i;
7720    }
72987721
72997722    // Create a glyph to handle TAB
73007723    // FIXME: Needs proper TAB handling but it needs to be contextualized (can arbitrary say that each string starts at "column 0"
7301    if (const ImFont::Glyph* space_glyph = FindGlyph((unsigned short)' '))
7724    if (FindGlyph((unsigned short)' '))
73027725    {
7303        Glyphs.resize(Glyphs.size() + 1);
7726        if (Glyphs.back().Codepoint != '\t')   // So we can call this function multiple times
7727            Glyphs.resize(Glyphs.size() + 1);
73047728        ImFont::Glyph& tab_glyph = Glyphs.back();
7305        tab_glyph = *space_glyph;
7729        tab_glyph = *FindGlyph((unsigned short)' ');
73067730        tab_glyph.Codepoint = '\t';
73077731        tab_glyph.XAdvance *= 4;
7308        IndexLookup[(int)tab_glyph.Codepoint] = (int)(Glyphs.size()-1);
7732        IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance;
7733        IndexLookup[(size_t)tab_glyph.Codepoint] = (int)(Glyphs.size()-1);
73097734    }
7735
7736    FallbackGlyph = NULL;
7737    FallbackGlyph = FindGlyph(FallbackChar);
7738    FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f;
7739    for (size_t i = 0; i < (size_t)max_codepoint + 1; i++)
7740        if (IndexXAdvance[i] < 0.0f)
7741            IndexXAdvance[i] = FallbackXAdvance;
73107742}
73117743
7744void ImFont::SetFallbackChar(ImWchar c)
7745{
7746    FallbackChar = c;
7747    BuildLookupTable();
7748}
7749
73127750const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const
73137751{
73147752    if (c < (int)IndexLookup.size())
r244869r244870
73227760
73237761// Convert UTF-8 to 32-bits character, process single character input.
73247762// Based on stb_from_utf8() from github.com/nothings/stb/
7763// We handle UTF-8 decoding error by skipping forward.
73257764static int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
73267765{
7327    if (*in_text != 0)
7766    unsigned int c = (unsigned int)-1;
7767    const unsigned char* str = (const unsigned char*)in_text;
7768    if (!(*str & 0x80))
73287769    {
7329        unsigned int c = (unsigned int)-1;
7330        const unsigned char* str = (const unsigned char*)in_text;
7331        if (!(*str & 0x80))
7332        {
7333            c = (unsigned int)(*str++);
7334            *out_char = c;
7335            return 1;
7336        }
7337        if ((*str & 0xe0) == 0xc0)
7338        {
7339            if (in_text_end && in_text_end - (const char*)str < 2) return -1;
7340            if (*str < 0xc2) return -1;
7341            c = (unsigned int)((*str++ & 0x1f) << 6);
7342            if ((*str & 0xc0) != 0x80) return -1;
7343            c += (*str++ & 0x3f);
7344            *out_char = c;
7345            return 2;
7346        }
7347        if ((*str & 0xf0) == 0xe0)
7348        {
7349            if (in_text_end && in_text_end - (const char*)str < 3) return -1;
7350            if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return -1;
7351            if (*str == 0xed && str[1] > 0x9f) return -1; // str[1] < 0x80 is checked below
7352            c = (unsigned int)((*str++ & 0x0f) << 12);
7353            if ((*str & 0xc0) != 0x80) return -1;
7354            c += (unsigned int)((*str++ & 0x3f) << 6);
7355            if ((*str & 0xc0) != 0x80) return -1;
7356            c += (*str++ & 0x3f);
7357            *out_char = c;
7358            return 3;
7359        }
7360        if ((*str & 0xf8) == 0xf0)
7361        {
7362            if (in_text_end && in_text_end - (const char*)str < 4) return -1;
7363            if (*str > 0xf4) return -1;
7364            if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return -1;
7365            if (*str == 0xf4 && str[1] > 0x8f) return -1; // str[1] < 0x80 is checked below
7366            c = (unsigned int)((*str++ & 0x07) << 18);
7367            if ((*str & 0xc0) != 0x80) return -1;
7368            c += (unsigned int)((*str++ & 0x3f) << 12);
7369            if ((*str & 0xc0) != 0x80) return -1;
7370            c += (unsigned int)((*str++ & 0x3f) << 6);
7371            if ((*str & 0xc0) != 0x80) return -1;
7372            c += (*str++ & 0x3f);
7373            // utf-8 encodings of values used in surrogate pairs are invalid
7374            if ((c & 0xFFFFF800) == 0xD800) return -1;
7375            *out_char = c;
7376            return 4;
7377        }
7770        c = (unsigned int)(*str++);
7771        *out_char = c;
7772        return 1;
73787773    }
7774    if ((*str & 0xe0) == 0xc0)
7775    {
7776        *out_char = 0;
7777        if (in_text_end && in_text_end - (const char*)str < 2) return 0;
7778        if (*str < 0xc2) return 0;
7779        c = (unsigned int)((*str++ & 0x1f) << 6);
7780        if ((*str & 0xc0) != 0x80) return 0;
7781        c += (*str++ & 0x3f);
7782        *out_char = c;
7783        return 2;
7784    }
7785    if ((*str & 0xf0) == 0xe0)
7786    {
7787        *out_char = 0;
7788        if (in_text_end && in_text_end - (const char*)str < 3) return 0;
7789        if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 0;
7790        if (*str == 0xed && str[1] > 0x9f) return 0; // str[1] < 0x80 is checked below
7791        c = (unsigned int)((*str++ & 0x0f) << 12);
7792        if ((*str & 0xc0) != 0x80) return 0;
7793        c += (unsigned int)((*str++ & 0x3f) << 6);
7794        if ((*str & 0xc0) != 0x80) return 0;
7795        c += (*str++ & 0x3f);
7796        *out_char = c;
7797        return 3;
7798    }
7799    if ((*str & 0xf8) == 0xf0)
7800    {
7801        *out_char = 0;
7802        if (in_text_end && in_text_end - (const char*)str < 4) return 0;
7803        if (*str > 0xf4) return 0;
7804        if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 0;
7805        if (*str == 0xf4 && str[1] > 0x8f) return 0; // str[1] < 0x80 is checked below
7806        c = (unsigned int)((*str++ & 0x07) << 18);
7807        if ((*str & 0xc0) != 0x80) return 0;
7808        c += (unsigned int)((*str++ & 0x3f) << 12);
7809        if ((*str & 0xc0) != 0x80) return 0;
7810        c += (unsigned int)((*str++ & 0x3f) << 6);
7811        if ((*str & 0xc0) != 0x80) return 0;
7812        c += (*str++ & 0x3f);
7813        // utf-8 encodings of values used in surrogate pairs are invalid
7814        if ((c & 0xFFFFF800) == 0xD800) return 0;
7815        *out_char = c;
7816        return 4;
7817    }
73797818    *out_char = 0;
73807819    return 0;
73817820}
73827821
7383static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end)
7822static ptrdiff_t ImTextStrFromUtf8(ImWchar* buf, size_t buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining)
73847823{
73857824    ImWchar* buf_out = buf;
73867825    ImWchar* buf_end = buf + buf_size;
r244869r244870
73887827    {
73897828        unsigned int c;
73907829        in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
7830        if (c == 0)
7831            break;
73917832        if (c < 0x10000)    // FIXME: Losing characters that don't fit in 2 bytes
73927833            *buf_out++ = (ImWchar)c;
73937834    }
73947835    *buf_out = 0;
7836    if (in_text_remaining)
7837        *in_text_remaining = in_text;
73957838    return buf_out - buf;
73967839}
73977840
r244869r244870
74027845    {
74037846        unsigned int c;
74047847        in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
7848        if (c == 0)
7849            break;
74057850        if (c < 0x10000)
74067851            char_count++;
74077852    }
r244869r244870
74667911    return buf_out - buf;
74677912}
74687913
7469static int ImTextCountUtf8BytesFromWchar(const ImWchar* in_text, const ImWchar* in_text_end)
7914static int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end)
74707915{
74717916    int bytes_count = 0;
74727917    while ((!in_text_end || in_text < in_text_end) && *in_text)
r244869r244870
75067951    const char* s = text;
75077952    while (s < text_end)
75087953    {
7509        unsigned int c;
7510        const int bytes_count = ImTextCharFromUtf8(&c, s, text_end);
7511        const char* next_s = s + (bytes_count > 0 ? bytes_count : 1);
7954        unsigned int c = (unsigned int)*s;
7955        const char* next_s;
7956        if (c < 0x80)
7957            next_s = s + 1;
7958        else
7959            next_s = s + ImTextCharFromUtf8(&c, s, text_end);
7960        if (c == 0)
7961            break;
75127962
75137963        if (c == '\n')
75147964        {
r244869r244870
75187968            continue;
75197969        }
75207970
7521        float char_width = 0.0f;
7522        if (const Glyph* glyph = FindGlyph((unsigned short)c))
7523            char_width = glyph->XAdvance * scale;
7524
7525        if (c == ' ' || c == '\t')
7971        const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
7972        if (ImCharIsSpace(c))
75267973        {
75277974            if (inside_word)
75287975            {
r244869r244870
76048051                while (s < text_end)
76058052                {
76068053                    const char c = *s;
7607                    if (c == ' ' || c == '\t') { s++; } else if (c == '\n') { s++; break; } else { break; }
8054                    if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
76088055                }
76098056                continue;
76108057            }
76118058        }
76128059
76138060        // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte)
7614        unsigned int c;
7615        const int bytes_count = ImTextCharFromUtf8(&c, s, text_end);
7616        s += bytes_count > 0 ? bytes_count : 1;
8061        unsigned int c = (unsigned int)*s;
8062        if (c < 0x80)
8063        {
8064            s += 1;
8065        }
8066        else
8067        {
8068            s += ImTextCharFromUtf8(&c, s, text_end);
8069            if (c == 0)
8070                break;
8071        }
76178072
76188073        if (c == '\n')
76198074        {
r244869r244870
76238078            continue;
76248079        }
76258080
7626        float char_width = 0.0f;
7627        if (const Glyph* glyph = FindGlyph((unsigned short)c))
7628            char_width = glyph->XAdvance * scale;
7629
8081        const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
76308082        if (line_width + char_width >= max_width)
76318083            break;
76328084
r244869r244870
76708122            continue;
76718123        }
76728124
7673        float char_width = 0.0f;
7674        if (const Glyph* glyph = FindGlyph((unsigned short)c))
7675            char_width = glyph->XAdvance * scale;
7676
8125        const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance;
76778126        if (line_width + char_width >= max_width)
76788127            break;
76798128
r244869r244870
77408189                while (s < text_end)
77418190                {
77428191                    const char c = *s;
7743                    if (c == ' ' || c == '\t') { s++; } else if (c == '\n') { s++; break; } else { break; }
8192                    if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
77448193                }
77458194                continue;
77468195            }
77478196        }
77488197
77498198        // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte)
7750        unsigned int c;
7751        const int bytes_count = ImTextCharFromUtf8(&c, s, text_end);
7752        s += bytes_count > 0 ? bytes_count : 1;
8199        unsigned int c = (unsigned int)*s;
8200        if (c < 0x80)
8201        {
8202            s += 1;
8203        }
8204        else
8205        {
8206            s += ImTextCharFromUtf8(&c, s, text_end);
8207            if (c == 0)
8208                break;
8209        }
77538210
77548211        if (c == '\n')
77558212        {
r244869r244870
78318288
78328289#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS)
78338290
8291#ifndef _WINDOWS_
78348292#define WIN32_LEAN_AND_MEAN
78358293#include <windows.h>
8294#endif
78368295
78378296// Win32 API clipboard implementation
7838static const char* GetClipboardTextFn_DefaultImpl()
8297static const char* GetClipboardTextFn_DefaultImpl()
78398298{
78408299    static char* buf_local = NULL;
78418300    if (buf_local)
r244869r244870
78458304    }
78468305    if (!OpenClipboard(NULL))
78478306        return NULL;
7848    HANDLE buf_handle = GetClipboardData(CF_TEXT);
7849    if (buf_handle == NULL)
8307    HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT);
8308    if (wbuf_handle == NULL)
78508309        return NULL;
7851    if (char* buf_global = (char*)GlobalLock(buf_handle))
7852        buf_local = ImStrdup(buf_global);
7853    GlobalUnlock(buf_handle);
8310    if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle))
8311    {
8312        int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1;
8313        buf_local = (char*)ImGui::MemAlloc(buf_len * sizeof(char));
8314        ImTextStrToUtf8(buf_local, buf_len, wbuf_global, NULL);
8315    }
8316    GlobalUnlock(wbuf_handle);
78548317    CloseClipboard();
78558318    return buf_local;
78568319}
r244869r244870
78608323{
78618324    if (!OpenClipboard(NULL))
78628325        return;
7863    const char* text_end = text + strlen(text);
7864    const int buf_length = (int)(text_end - text) + 1;
7865    HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)buf_length * sizeof(char));
7866    if (buf_handle == NULL)
8326
8327    const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1;
8328    HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar));
8329    if (wbuf_handle == NULL)
78678330        return;
7868    char* buf_global = (char *)GlobalLock(buf_handle);
7869    memcpy(buf_global, text, (size_t)(text_end - text));
7870    buf_global[text_end - text] = 0;
7871    GlobalUnlock(buf_handle);
8331    ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle);
8332    ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL);
8333    GlobalUnlock(wbuf_handle);
78728334    EmptyClipboard();
7873    SetClipboardData(CF_TEXT, buf_handle);
8335    SetClipboardData(CF_UNICODETEXT, wbuf_handle);
78748336    CloseClipboard();
78758337}
78768338
78778339#else
78788340
78798341// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
7880static const char* GetClipboardTextFn_DefaultImpl()
8342static const char* GetClipboardTextFn_DefaultImpl()
78818343{
78828344    return GImGui->PrivateClipboard;
78838345}
r244869r244870
78998361
79008362#endif
79018363
8364#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)
8365
8366#ifndef _WINDOWS_
8367#define WIN32_LEAN_AND_MEAN
8368#include <windows.h>
8369#endif
8370#include <Imm.h>
8371#pragma comment(lib, "imm32")
8372
8373static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
8374{
8375    // Notify OS Input Method Editor of text input position
8376    if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle)
8377        if (HIMC himc = ImmGetContext(hwnd))
8378        {
8379            COMPOSITIONFORM cf;
8380            cf.ptCurrentPos.x = x;
8381            cf.ptCurrentPos.y = y;
8382            cf.dwStyle = CFS_FORCE_POSITION;
8383            ImmSetCompositionWindow(himc, &cf);
8384        }
8385}
8386
8387#else
8388
8389static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
8390{
8391}
8392
8393#endif
8394
79028395//-----------------------------------------------------------------------------
79038396// HELP
79048397//-----------------------------------------------------------------------------
r244869r244870
79578450        ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
79588451        ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
79598452        ImGui::SliderFloat("TreeNodeSpacing", &style.TreeNodeSpacing, 0.0f, 20.0f, "%.0f");
7960        ImGui::SliderFloat("ScrollBarWidth", &style.ScrollBarWidth, 0.0f, 20.0f, "%.0f");
8453        ImGui::SliderFloat("ScrollBarWidth", &style.ScrollbarWidth, 1.0f, 20.0f, "%.0f");
8454        ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f");
79618455        ImGui::TreePop();
79628456    }
79638457
r244869r244870
80288522static void ShowExampleAppLongText(bool* opened);
80298523static void ShowExampleAppAutoResize(bool* opened);
80308524static void ShowExampleAppFixedOverlay(bool* opened);
8525static void ShowExampleAppManipulatingWindowTitle(bool* opened);
80318526static void ShowExampleAppCustomRendering(bool* opened);
80328527
80338528// Demonstrate ImGui features (unfortunately this makes this function a little bloated!)
80348529void ImGui::ShowTestWindow(bool* opened)
80358530{
8531    // Examples apps
8532    static bool show_app_console = false;
8533    static bool show_app_long_text = false;
8534    static bool show_app_auto_resize = false;
8535    static bool show_app_fixed_overlay = false;
8536    static bool show_app_custom_rendering = false;
8537    static bool show_app_manipulating_window_title = false;
8538    if (show_app_console)
8539        ShowExampleAppConsole(&show_app_console);
8540    if (show_app_long_text)
8541        ShowExampleAppLongText(&show_app_long_text);
8542    if (show_app_auto_resize)
8543        ShowExampleAppAutoResize(&show_app_auto_resize);
8544    if (show_app_fixed_overlay)
8545        ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
8546    if (show_app_manipulating_window_title)
8547        ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title);
8548    if (show_app_custom_rendering)
8549        ShowExampleAppCustomRendering(&show_app_custom_rendering);
8550
80368551    static bool no_titlebar = false;
80378552    static bool no_border = true;
80388553    static bool no_resize = false;
80398554    static bool no_move = false;
80408555    static bool no_scrollbar = false;
80418556    static bool no_collapse = false;
8042    static float fill_alpha = 0.65f;
8557    static float bg_alpha = 0.65f;
80438558
80448559    // Demonstrate the various window flags. Typically you would just use the default.
80458560    ImGuiWindowFlags window_flags = 0;
r244869r244870
80498564    if (no_move)      window_flags |= ImGuiWindowFlags_NoMove;
80508565    if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
80518566    if (no_collapse)  window_flags |= ImGuiWindowFlags_NoCollapse;
8052    if (!ImGui::Begin("ImGui Test", opened, ImVec2(550,680), fill_alpha, window_flags))
8567    if (!ImGui::Begin("ImGui Test", opened, ImVec2(550,680), bg_alpha, window_flags))
80538568    {
80548569        // Early out if the window is collapsed, as an optimization.
80558570        ImGui::End();
80568571        return;
80578572    }
8058    ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
80598573
8574    ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);    // 2/3 of the space for widget and 1/3 for labels
8575    //ImGui::PushItemWidth(-140);                             // Right align, keep 140 pixels for labels
8576
80608577    ImGui::Text("ImGui says hello.");
80618578    //ImGui::Text("MousePos (%g, %g)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
80628579    //ImGui::Text("MouseWheel %d", ImGui::GetIO().MouseWheel);
r244869r244870
80788595        ImGui::Checkbox("no move", &no_move); ImGui::SameLine(150);
80798596        ImGui::Checkbox("no scrollbar", &no_scrollbar); ImGui::SameLine(300);
80808597        ImGui::Checkbox("no collapse", &no_collapse);
8081        ImGui::SliderFloat("fill alpha", &fill_alpha, 0.0f, 1.0f);
8598        ImGui::SliderFloat("bg alpha", &bg_alpha, 0.0f, 1.0f);
80828599
80838600        if (ImGui::TreeNode("Style"))
80848601        {
r244869r244870
81498666        {
81508667            ImGui::BulletText("Bullet point 1");
81518668            ImGui::BulletText("Bullet point 2\nOn multiple lines");
8152            ImGui::BulletText("Bullet point 3");
8669            ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)");
8670            ImGui::Bullet(); ImGui::SmallButton("Button 1");
8671            ImGui::Bullet(); ImGui::SmallButton("Button 2");
81538672            ImGui::TreePop();
81548673        }
81558674
r244869r244870
82918810            ImGui::TreePop();
82928811        }
82938812
8813        if (ImGui::TreeNode("Filtered Text Input"))
8814        {
8815            static char buf1[64] = ""; ImGui::InputText("default", buf1, 64);
8816            static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal);
8817            static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
8818            static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase);
8819            static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank);
8820            struct TextFilters { static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } };
8821            static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters);
8822            ImGui::TreePop();
8823        }
8824
82948825        static bool check = true;
82958826        ImGui::Checkbox("checkbox", &check);
82968827
r244869r244870
83928923        static int listbox_item_current = 1;
83938924        ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
83948925
8926        //static int listbox_item_current2 = 2;
83958927        //ImGui::PushItemWidth(-1);
83968928        //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
83978929        //ImGui::PopItemWidth();
r244869r244870
84558987        ImGui::SameLine();
84568988        ImGui::Checkbox("Rich", &c4);
84578989
8458        // SliderFloat
8990        // Various
84598991        static float f0=1.0f, f1=2.0f, f2=3.0f;
84608992        ImGui::PushItemWidth(80);
8993        const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" };
8994        static int item = -1;
8995        ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items));
8996        ImGui::SameLine();
84618997        ImGui::SliderFloat("X", &f0, 0.0f,5.0f);
84628998        ImGui::SameLine();
84638999        ImGui::SliderFloat("Y", &f1, 0.0f,5.0f);
84649000        ImGui::SameLine();
84659001        ImGui::SliderFloat("Z", &f2, 0.0f,5.0f);
9002        ImGui::PopItemWidth();
9003
9004        ImGui::PushItemWidth(80);
9005        ImGui::Text("Lists:");
9006        static int selection[4] = { 0, 1, 2, 3 };
9007        for (int i = 0; i < 4; i++)
9008        {
9009            if (i > 0) ImGui::SameLine();
9010            ImGui::PushID(i);
9011            ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items));
9012            ImGui::PopID();
9013            //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i);
9014        }
9015        ImGui::PopItemWidth();
84669016    }
84679017
84689018    if (ImGui::CollapsingHeader("Child regions"))
r244869r244870
85059055
85069056    if (ImGui::CollapsingHeader("Columns"))
85079057    {
8508        ImGui::Columns(4, "data", true);
9058        // Basic columns
9059        ImGui::Text("Basic:");
9060        ImGui::Columns(4, "mycolumns");
85099061        ImGui::Text("ID"); ImGui::NextColumn();
85109062        ImGui::Text("Name"); ImGui::NextColumn();
85119063        ImGui::Text("Path"); ImGui::NextColumn();
85129064        ImGui::Text("Flags"); ImGui::NextColumn();
85139065        ImGui::Separator();
9066        const char* names[3] = { "Robert", "Stephanie", "C64" };
9067        const char* paths[3] = { "/path/robert", "/path/stephanie", "/path/computer" };
9068        for (int i = 0; i < 3; i++)
9069        {
9070            ImGui::Text("%04d", i); ImGui::NextColumn();
9071            ImGui::Text(names[i]); ImGui::NextColumn();
9072            ImGui::Text(paths[i]); ImGui::NextColumn();
9073            ImGui::Text("...."); ImGui::NextColumn();
9074        }
9075        ImGui::Columns(1);
85149076
8515        ImGui::Text("0000"); ImGui::NextColumn();
8516        ImGui::Text("Robert"); ImGui::NextColumn();
8517        ImGui::Text("/path/robert"); ImGui::NextColumn();
8518        ImGui::Text("...."); ImGui::NextColumn();
9077        ImGui::Separator();
9078        ImGui::Spacing();
85199079
8520        ImGui::Text("0001"); ImGui::NextColumn();
8521        ImGui::Text("Stephanie"); ImGui::NextColumn();
8522        ImGui::Text("/path/stephanie"); ImGui::NextColumn();
8523        ImGui::Text("line 1"); ImGui::Text("line 2"); ImGui::NextColumn(); // two lines, two items
8524
8525        ImGui::Text("0002"); ImGui::NextColumn();
8526        ImGui::Text("C64"); ImGui::NextColumn();
8527        ImGui::Text("/path/computer"); ImGui::NextColumn();
8528        ImGui::Text("...."); ImGui::NextColumn();
9080        // Scrolling columns
9081      /*
9082        ImGui::Text("Scrolling:");
9083        ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y));
9084        ImGui::Columns(3);
9085        ImGui::Text("ID"); ImGui::NextColumn();
9086        ImGui::Text("Name"); ImGui::NextColumn();
9087        ImGui::Text("Path"); ImGui::NextColumn();
85299088        ImGui::Columns(1);
9089        ImGui::Separator();
9090        ImGui::EndChild();
9091        ImGui::BeginChild("##scrollingregion", ImVec2(0, 60));
9092        ImGui::Columns(3);
9093        for (int i = 0; i < 10; i++)
9094        {
9095            ImGui::Text("%04d", i); ImGui::NextColumn();
9096            ImGui::Text("Foobar"); ImGui::NextColumn();
9097            ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn();
9098        }
9099        ImGui::Columns(1);
9100        ImGui::EndChild();
85309101
85319102        ImGui::Separator();
9103        ImGui::Spacing();
9104      */
85329105
9106        // Create multiple items in a same cell before switching to next column
9107        ImGui::Text("Mixed items:");
85339108        ImGui::Columns(3, "mixed");
9109        ImGui::Separator();
85349110
8535        // Create multiple items in a same cell because switching to next column
85369111        static int e = 0;
85379112        ImGui::Text("Hello");
85389113        ImGui::Button("Banana");
r244869r244870
85429117        ImGui::Text("ImGui");
85439118        ImGui::Button("Apple");
85449119        ImGui::RadioButton("radio b", &e, 1);
9120        static float foo = 1.0f;
9121        ImGui::InputFloat("red", &foo, 0.05f, 0, 3);
85459122        ImGui::Text("An extra line here.");
85469123        ImGui::NextColumn();
85479124
85489125        ImGui::Text("World!");
85499126        ImGui::Button("Corniflower");
85509127        ImGui::RadioButton("radio c", &e, 2);
9128        static float bar = 1.0f;
9129        ImGui::InputFloat("blue", &bar, 0.05f, 0, 3);
85519130        ImGui::NextColumn();
85529131
85539132        if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn();
85549133        if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn();
85559134        if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn();
8556
85579135        ImGui::Columns(1);
85589136
85599137        ImGui::Separator();
9138        ImGui::Spacing();
85609139
8561        ImGui::Columns(2, "multiple components");
8562        static float foo = 1.0f;
8563        ImGui::InputFloat("red", &foo, 0.05f, 0, 3); ImGui::NextColumn();
8564        static float bar = 1.0f;
8565        ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); ImGui::NextColumn();
9140        // Tree items
9141        ImGui::Text("Tree items:");
9142        ImGui::Columns(2, "tree items");
9143        ImGui::Separator();
9144        if (ImGui::TreeNode("Hello")) { ImGui::BulletText("World"); ImGui::TreePop(); } ImGui::NextColumn();
9145        if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Monde"); ImGui::TreePop(); } ImGui::NextColumn();
85669146        ImGui::Columns(1);
85679147
85689148        ImGui::Separator();
9149        ImGui::Spacing();
85699150
8570        ImGui::Columns(2, "tree items");
8571        if (ImGui::TreeNode("Hello")) { ImGui::BulletText("World"); ImGui::TreePop(); } ImGui::NextColumn();
8572        if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Monde"); ImGui::TreePop(); }
8573        ImGui::Columns(1);
9151        // Word-wrapping
9152        ImGui::Text("Word-wrapping:");
9153        ImGui::Columns(2, "word-wrapping");
85749154        ImGui::Separator();
8575
8576        ImGui::Columns(2, "word wrapping");
85779155        ImGui::TextWrapped("The quick brown fox jumps over the lazy dog.");
85789156        ImGui::Text("Hello Left");
85799157        ImGui::NextColumn();
r244869r244870
85829160        ImGui::Columns(1);
85839161
85849162        ImGui::Separator();
9163        ImGui::Spacing();
85859164
85869165        if (ImGui::TreeNode("Inside a tree.."))
85879166        {
85889167            if (ImGui::TreeNode("node 1 (with borders)"))
85899168            {
85909169                ImGui::Columns(4);
8591                ImGui::Text("aaa"); ImGui::NextColumn();
8592                ImGui::Text("bbb"); ImGui::NextColumn();
8593                ImGui::Text("ccc"); ImGui::NextColumn();
8594                ImGui::Text("ddd"); ImGui::NextColumn();
8595                ImGui::Text("eee"); ImGui::NextColumn();
8596                ImGui::Text("fff"); ImGui::NextColumn();
8597                ImGui::Text("ggg"); ImGui::NextColumn();
8598                ImGui::Text("hhh"); ImGui::NextColumn();
9170                for (int i = 0; i < 8; i++)
9171                {
9172                    ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i);
9173                    ImGui::NextColumn();
9174                }
85999175                ImGui::Columns(1);
86009176                ImGui::TreePop();
86019177            }
86029178            if (ImGui::TreeNode("node 2 (without borders)"))
86039179            {
86049180                ImGui::Columns(4, NULL, false);
8605                ImGui::Text("aaa"); ImGui::NextColumn();
8606                ImGui::Text("bbb"); ImGui::NextColumn();
8607                ImGui::Text("ccc"); ImGui::NextColumn();
8608                ImGui::Text("ddd"); ImGui::NextColumn();
8609                ImGui::Text("eee"); ImGui::NextColumn();
8610                ImGui::Text("fff"); ImGui::NextColumn();
8611                ImGui::Text("ggg"); ImGui::NextColumn();
8612                ImGui::Text("hhh"); ImGui::NextColumn();
9181                for (int i = 0; i < 8; i++)
9182                {
9183                    ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i);
9184                    ImGui::NextColumn();
9185                }
86139186                ImGui::Columns(1);
86149187                ImGui::TreePop();
86159188            }
r244869r244870
86749247                ImGui::Text("Item with focus: %d", has_focus);
86759248            else
86769249                ImGui::Text("Item with focus: <none>");
9250            ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code.");
86779251            ImGui::TreePop();
86789252        }
86799253    }
86809254
8681    static bool show_app_console = false;
8682    static bool show_app_long_text = false;
8683    static bool show_app_auto_resize = false;
8684    static bool show_app_fixed_overlay = false;
8685    static bool show_app_custom_rendering = false;
86869255    if (ImGui::CollapsingHeader("App Examples"))
86879256    {
86889257        ImGui::Checkbox("Console", &show_app_console);
86899258        ImGui::Checkbox("Long text display", &show_app_long_text);
86909259        ImGui::Checkbox("Auto-resizing window", &show_app_auto_resize);
86919260        ImGui::Checkbox("Simple overlay", &show_app_fixed_overlay);
9261        ImGui::Checkbox("Manipulating window title", &show_app_manipulating_window_title);
86929262        ImGui::Checkbox("Custom rendering", &show_app_custom_rendering);
86939263    }
8694    if (show_app_console)
8695        ShowExampleAppConsole(&show_app_console);
8696    if (show_app_long_text)
8697        ShowExampleAppLongText(&show_app_long_text);
8698    if (show_app_auto_resize)
8699        ShowExampleAppAutoResize(&show_app_auto_resize);
8700    if (show_app_fixed_overlay)
8701        ShowExampleAppFixedOverlay(&show_app_fixed_overlay);
8702    if (show_app_custom_rendering)
8703        ShowExampleAppCustomRendering(&show_app_custom_rendering);
87049264
87059265    ImGui::End();
87069266}
r244869r244870
87389298    ImGui::End();
87399299}
87409300
9301static void ShowExampleAppManipulatingWindowTitle(bool* /*opened*/)
9302{
9303    // By default, Windows are uniquely identified by their title.
9304    // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file!
9305
9306    // Using "##" to display same title but have unique identifier.
9307    ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver);
9308    ImGui::Begin("Same title as another window##1");
9309    ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique.");
9310    ImGui::End();
9311
9312    ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiSetCond_FirstUseEver);
9313    ImGui::Begin("Same title as another window##2");
9314    ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique.");
9315    ImGui::End();
9316
9317    // Using "###" to display a changing title but keep a static identifier "MyWindow"
9318    char buf[128];
9319    ImFormatString(buf, IM_ARRAYSIZE(buf), "Animated title %c %d###MyWindow", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand());
9320    ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiSetCond_FirstUseEver);
9321    ImGui::Begin(buf);
9322    ImGui::Text("This window has a changing title.");
9323    ImGui::End();
9324}
9325
87419326static void ShowExampleAppCustomRendering(bool* opened)
87429327{
9328    ImGui::SetNextWindowSize(ImVec2(300,350), ImGuiSetCond_FirstUseEver);
87439329    if (!ImGui::Begin("Example: Custom Rendering", opened))
87449330    {
87459331        ImGui::End();
r244869r244870
87549340    static ImVector<ImVec2> points;
87559341    static bool adding_line = false;
87569342    if (ImGui::Button("Clear")) points.clear();
8757    if (points.size() > 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) points.pop_back(); }
9343    if (points.size() >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
87589344    ImGui::Text("Left-click and drag to add lines");
87599345    ImGui::Text("Right-click to undo");
87609346
r244869r244870
88609446        if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.size()); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
88619447        if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine();
88629448        if (ImGui::SmallButton("Clear")) ClearLog();
9449        //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
9450
88639451        ImGui::Separator();
88649452
88659453        ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
r244869r244870
89459533        }
89469534    }
89479535
8948    static void TextEditCallbackStub(ImGuiTextEditCallbackData* data)
9536    static int TextEditCallbackStub(ImGuiTextEditCallbackData* data)
89499537    {
89509538        ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
8951        console->TextEditCallback(data);
9539        return console->TextEditCallback(data);
89529540    }
89539541
8954    void    TextEditCallback(ImGuiTextEditCallbackData* data)
9542    int     TextEditCallback(ImGuiTextEditCallbackData* data)
89559543    {
89569544        //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd);
8957        switch (data->EventKey)
9545        switch (data->EventFlag)
89589546        {
8959        case ImGuiKey_Tab:
9547        case ImGuiInputTextFlags_CallbackCompletion:
89609548            {
89619549                // Example of TEXT COMPLETION
89629550
r244869r244870
89669554                while (word_start > data->Buf)
89679555                {
89689556                    const char c = word_start[-1];
8969                    if (c == ' ' || c == '\t' || c == ',' || c == ';')
9557                    if (ImCharIsSpace(c) || c == ',' || c == ';')
89709558                        break;
89719559                    word_start--;
89729560                }
r244869r244870
90219609
90229610                break;
90239611            }
9024        case ImGuiKey_UpArrow:
9025        case ImGuiKey_DownArrow:
9612        case ImGuiInputTextFlags_CallbackHistory:
90269613            {
90279614                // Example of HISTORY
90289615                const int prev_history_pos = HistoryPos;
r244869r244870
90499636                }
90509637            }
90519638        }
9639        return 0;
90529640    }
90539641};
90549642
trunk/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
r244869r244870
1// ImGui library v1.32 wip
1// ImGui library v1.35
22// See .cpp file for documentation.
33// See ImGui::ShowTestWindow() for sample code.
44// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
r244869r244870
66
77#pragma once
88
9struct ImDrawCmd;
10struct ImDrawList;
11struct ImFont;
12struct ImFontAtlas;
13struct ImGuiAabb;
14struct ImGuiIO;
15struct ImGuiStorage;
16struct ImGuiStyle;
17struct ImGuiWindow;
18
19#include "imconfig.h"
9#include "imconfig.h"       // User-editable configuration file
2010#include <float.h>          // FLT_MAX
2111#include <stdarg.h>         // va_list
2212#include <stddef.h>         // ptrdiff_t
2313#include <stdlib.h>         // NULL, malloc
2414#include <string.h>         // memset, memmove
2515
16// Define assertion handler.
2617#ifndef IM_ASSERT
2718#include <assert.h>
2819#define IM_ASSERT(_EXPR)    assert(_EXPR)
2920#endif
3021
22// Define attributes of all API symbols declarations, e.g. for DLL under Windows.
3123#ifndef IMGUI_API
3224#define IMGUI_API
3325#endif
3426
27// Forward declarations
28struct ImDrawCmd;
29struct ImDrawList;
30struct ImFont;
31struct ImFontAtlas;
32struct ImGuiIO;
33struct ImGuiStorage;
34struct ImGuiStyle;
35
3536typedef unsigned int ImU32;
3637typedef unsigned short ImWchar;     // character for display
3738typedef void* ImTextureID;          // user data to refer to a texture (e.g. store your texture handle/id)
r244869r244870
4142typedef int ImGuiKey;               // enum ImGuiKey_
4243typedef int ImGuiColorEditMode;     // enum ImGuiColorEditMode_
4344typedef int ImGuiWindowFlags;       // enum ImGuiWindowFlags_
44typedef int ImGuiSetCondition;      // enum ImGuiSetCondition_
45typedef int ImGuiSetCond;           // enum ImGuiSetCondition_
4546typedef int ImGuiInputTextFlags;    // enum ImGuiInputTextFlags_
46struct ImGuiTextEditCallbackData;   // for advanced uses of InputText()
47struct ImGuiTextEditCallbackData;   // for advanced uses of InputText()
48typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
4749
4850struct ImVec2
4951{
r244869r244870
7476    IMGUI_API void        MemFree(void* ptr);
7577}
7678
77// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
79// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
7880// Use '#define ImVector std::vector' if you want to use the STL type or your own type.
7981// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need.
8082#ifndef ImVector
r244869r244870
115117    inline void                 swap(ImVector<T>& rhs)          { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
116118
117119    inline void                 resize(size_t new_size)         { if (new_size > Capacity) reserve(new_size); Size = new_size; }
118    inline void                 reserve(size_t new_capacity)
119    {
120    inline void                 reserve(size_t new_capacity)   
121    {
120122        if (new_capacity <= Capacity) return;
121123        T* new_data = (value_type*)ImGui::MemAlloc(new_capacity * sizeof(value_type));
122124        memcpy(new_data, Data, Size * sizeof(value_type));
123125        ImGui::MemFree(Data);
124126        Data = new_data;
125        Capacity = new_capacity;
127        Capacity = new_capacity;
126128    }
127129
128130    inline void                 push_back(const value_type& v)  { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }
r244869r244870
141143// - struct ImDrawList                  // Draw command list
142144// - struct ImFont                      // TTF font loader, bake glyphs into bitmap
143145
144// ImGui End-user API
146// ImGui end-user API
145147// In a namespace so that user can add extra functions (e.g. Value() helpers for your vector or common types)
146148namespace ImGui
147149{
r244869r244870
156158    IMGUI_API void          ShowTestWindow(bool* open = NULL);
157159
158160    // Window
159    IMGUI_API bool          Begin(const char* name = "Debug", bool* p_opened = NULL, ImVec2 size = ImVec2(0,0), float fill_alpha = -1.0f, ImGuiWindowFlags flags = 0);// return false when window is collapsed, so you can early out in your code. passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
161    // See implementation in .cpp for details
162    IMGUI_API bool          Begin(const char* name = "Debug", bool* p_opened = NULL, const ImVec2& initial_size = ImVec2(0,0), float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code. passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
160163    IMGUI_API void          End();
161    IMGUI_API void          BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);                         // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
162    IMGUI_API void          BeginChild(ImGuiID id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);                                 // "
164    IMGUI_API bool          BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);            // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
165    IMGUI_API bool          BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);                    // "
163166    IMGUI_API void          EndChild();
164167    IMGUI_API bool          GetWindowIsFocused();
165168    IMGUI_API ImVec2        GetContentRegionMax();                                              // window or current column boundaries, in windows coordinates
r244869r244870
173176    IMGUI_API ImVec2        GetWindowSize();                                                    // get current window position.
174177    IMGUI_API float         GetWindowWidth();
175178    IMGUI_API bool          GetWindowCollapsed();
176    IMGUI_API void          SetNextWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0);    // set next window position - call before Begin().
177    IMGUI_API void          SetNextWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0);  // set next window size. set to ImVec2(0,0) to force an auto-fit.
178    IMGUI_API void          SetNextWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0); // set next window collapsed state.
179    IMGUI_API void          SetWindowPos(const ImVec2& pos, ImGuiSetCondition cond = 0);        // set current window position - call within Begin()/End(). may incur tearing.
180    IMGUI_API void          SetWindowSize(const ImVec2& size, ImGuiSetCondition cond = 0);      // set current window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing.
181    IMGUI_API void          SetWindowCollapsed(bool collapsed, ImGuiSetCondition cond = 0);     // set current window collapsed state.
182179
180    IMGUI_API void          SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0);         // set next window position - call before Begin().
181    IMGUI_API void          SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0);       // set next window size. set to ImVec2(0,0) to force an auto-fit.
182    IMGUI_API void          SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0);      // set next window collapsed state.
183    IMGUI_API void          SetNextWindowFocus();                                               // set next window to be focused / front-most
184    IMGUI_API void          SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0);             // set current window position - call within Begin()/End(). may incur tearing.
185    IMGUI_API void          SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0);           // set current window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing.
186    IMGUI_API void          SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0);          // set current window collapsed state.
187    IMGUI_API void          SetWindowFocus();                                                   // set current window to be focused / front-most
188    IMGUI_API void          SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0);      // set named window position - call within Begin()/End(). may incur tearing.
189    IMGUI_API void          SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0);    // set named window size. set to ImVec2(0,0) to force an auto-fit. may incur tearing.
190    IMGUI_API void          SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0);   // set named window collapsed state.
191    IMGUI_API void          SetWindowFocus(const char* name);                                              // set named window to be focused / front-most
192
193    IMGUI_API float         GetScrollPosY();                                                    // get scrolling position (0..GetScrollMaxY())
194    IMGUI_API float         GetScrollMaxY();                                                    // get maximum scrolling position == ContentSize.Y - WindowSize.Y
183195    IMGUI_API void          SetScrollPosHere();                                                 // adjust scrolling position to center into the current cursor position.
184196    IMGUI_API void          SetKeyboardFocusHere(int offset = 0);                               // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget.
185197    IMGUI_API void          SetStateStorage(ImGuiStorage* tree);                                // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
r244869r244870
215227    IMGUI_API void          Spacing();
216228    IMGUI_API void          Columns(int count = 1, const char* id = NULL, bool border=true);    // setup number of columns
217229    IMGUI_API void          NextColumn();                                                       // next column
218    IMGUI_API float         GetColumnOffset(int column_index = -1);
219    IMGUI_API void          SetColumnOffset(int column_index, float offset);
220    IMGUI_API float         GetColumnWidth(int column_index = -1);
230    IMGUI_API int           GetColumnIndex();                                                   // get current column index
231    IMGUI_API float         GetColumnOffset(int column_index = -1);                             // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this.
232    IMGUI_API void          SetColumnOffset(int column_index, float offset_x);                  // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column.
233    IMGUI_API float         GetColumnWidth(int column_index = -1);                              // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset())
234    IMGUI_API int           GetColumnsCount();                                                  // number of columns (what was passed to Columns())
221235    IMGUI_API ImVec2        GetCursorPos();                                                     // cursor position is relative to window position
222236    IMGUI_API float         GetCursorPosX();                                                    // "
223237    IMGUI_API float         GetCursorPosY();                                                    // "
r244869r244870
231245    IMGUI_API float         GetTextLineHeightWithSpacing();                                     // spacing (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y
232246
233247    // ID scopes
234    // If you are creating repeated widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them.
235    // You can also use ## within your widget name to distinguish them from each others (see 'Programmer Guide')
248    // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them.
249    // You can also use "##extra" within your widget name to distinguish them from each others (see 'Programmer Guide')
236250    IMGUI_API void          PushID(const char* str_id);                                         // push identifier into the ID stack. IDs are hash of the *entire* stack!
237251    IMGUI_API void          PushID(const void* ptr_id);
238252    IMGUI_API void          PushID(const int int_id);
r244869r244870
248262    IMGUI_API void          TextWrapped(const char* fmt, ...);                                  // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();
249263    IMGUI_API void          TextWrappedV(const char* fmt, va_list args);
250264    IMGUI_API void          TextUnformatted(const char* text, const char* text_end = NULL);     // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text.
251    IMGUI_API void          LabelText(const char* label, const char* fmt, ...);                 // display text+label aligned the same way as value+label widgets
265    IMGUI_API void          LabelText(const char* label, const char* fmt, ...);                 // display text+label aligned the same way as value+label widgets
252266    IMGUI_API void          LabelTextV(const char* label, const char* fmt, va_list args);
267    IMGUI_API void          Bullet();
253268    IMGUI_API void          BulletText(const char* fmt, ...);
254269    IMGUI_API void          BulletTextV(const char* fmt, va_list args);
255270    IMGUI_API bool          Button(const char* label, const ImVec2& size = ImVec2(0,0), bool repeat_when_held = false);
r244869r244870
257272    IMGUI_API bool          InvisibleButton(const char* str_id, const ImVec2& size);
258273    IMGUI_API void          Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
259274    IMGUI_API bool          ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0),  const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,1), const ImVec4& tint_col = ImVec4(1,1,1,1));    // <0 frame_padding uses default frame padding settings. 0 for no paddnig.
260    IMGUI_API bool          CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
275    IMGUI_API bool          CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false);
261276    IMGUI_API bool          SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);     // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders.
262277    IMGUI_API bool          SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
263278    IMGUI_API bool          SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
r244869r244870
275290    IMGUI_API bool          CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
276291    IMGUI_API bool          RadioButton(const char* label, bool active);
277292    IMGUI_API bool          RadioButton(const char* label, int* v, int v_button);
278    IMGUI_API bool          InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, void (*callback)(ImGuiTextEditCallbackData*) = NULL, void* user_data = NULL);
293    IMGUI_API bool          InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
279294    IMGUI_API bool          InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
280295    IMGUI_API bool          InputFloat2(const char* label, float v[2], int decimal_precision = -1);
281296    IMGUI_API bool          InputFloat3(const char* label, float v[3], int decimal_precision = -1);
r244869r244870
288303    IMGUI_API bool          ColorEdit3(const char* label, float col[3]);
289304    IMGUI_API bool          ColorEdit4(const char* label, float col[4], bool show_alpha = true);
290305    IMGUI_API void          ColorEditMode(ImGuiColorEditMode mode);
306
307    // Trees
291308    IMGUI_API bool          TreeNode(const char* str_label_id);                                 // if returning 'true' the node is open and the user is responsible for calling TreePop
292309    IMGUI_API bool          TreeNode(const char* str_id, const char* fmt, ...);                 // "
293310    IMGUI_API bool          TreeNode(const void* ptr_id, const char* fmt, ...);                 // "
r244869r244870
296313    IMGUI_API void          TreePush(const char* str_id = NULL);                                // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose
297314    IMGUI_API void          TreePush(const void* ptr_id = NULL);                                // "
298315    IMGUI_API void          TreePop();
299    IMGUI_API void          OpenNextNode(bool open);                                            // force open/close the next TreeNode or CollapsingHeader
316    IMGUI_API void          SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0);          // set next tree node to be opened.
300317
301318    // Selectable / Lists
302319    IMGUI_API bool          Selectable(const char* label, bool selected, const ImVec2& size = ImVec2(0,0));
r244869r244870
326343    // Utilities
327344    IMGUI_API bool          IsItemHovered();                                                    // was the last item hovered by mouse?
328345    IMGUI_API bool          IsItemActive();                                                     // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false)
346    IMGUI_API bool          IsAnyItemActive();                                                  //
329347    IMGUI_API ImVec2        GetItemBoxMin();                                                    // get bounding box of last item
330348    IMGUI_API ImVec2        GetItemBoxMax();                                                    // get bounding box of last item
331349    IMGUI_API bool          IsClipped(const ImVec2& item_size);                                 // to perform coarse clipping on user's side (as an optimization)
r244869r244870
357375
358376    // Obsolete (will be removed)
359377    IMGUI_API void          GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
378    static inline void      OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); }
360379
361380} // namespace ImGui
362381
r244869r244870
367386    ImGuiWindowFlags_NoTitleBar             = 1 << 0,   // Disable title-bar
368387    ImGuiWindowFlags_NoResize               = 1 << 1,   // Disable user resizing with the lower-right grip
369388    ImGuiWindowFlags_NoMove                 = 1 << 2,   // Disable user moving the window
370    ImGuiWindowFlags_NoScrollbar            = 1 << 3,   // Disable scroll bar (window can still scroll with mouse or programatically)
389    ImGuiWindowFlags_NoScrollbar            = 1 << 3,   // Disable scrollbar (window can still scroll with mouse or programatically)
371390    ImGuiWindowFlags_NoScrollWithMouse      = 1 << 4,   // Disable user scrolling with mouse wheel
372391    ImGuiWindowFlags_NoCollapse             = 1 << 5,   // Disable user collapsing window by double-clicking on it
373392    ImGuiWindowFlags_AlwaysAutoResize       = 1 << 6,   // Resize every window to its content every frame
r244869r244870
387406    // Default: 0
388407    ImGuiInputTextFlags_CharsDecimal        = 1 << 0,   // Allow 0123456789.+-*/
389408    ImGuiInputTextFlags_CharsHexadecimal    = 1 << 1,   // Allow 0123456789ABCDEFabcdef
390    ImGuiInputTextFlags_AutoSelectAll       = 1 << 2,   // Select entire text when first taking focus
391    ImGuiInputTextFlags_EnterReturnsTrue    = 1 << 3,   // Return 'true' when Enter is pressed (as opposed to when the value was modified)
392    ImGuiInputTextFlags_CallbackCompletion  = 1 << 4,   // Call user function on pressing TAB (for completion handling)
393    ImGuiInputTextFlags_CallbackHistory     = 1 << 5,   // Call user function on pressing Up/Down arrows (for history handling)
394    ImGuiInputTextFlags_CallbackAlways      = 1 << 6    // Call user function every time
395    //ImGuiInputTextFlags_AlignCenter       = 1 << 6,
409    ImGuiInputTextFlags_CharsUppercase      = 1 << 2,   // Turn a..z into A..Z
410    ImGuiInputTextFlags_CharsNoBlank        = 1 << 3,   // Filter out spaces, tabs
411    ImGuiInputTextFlags_AutoSelectAll       = 1 << 4,   // Select entire text when first taking mouse focus
412    ImGuiInputTextFlags_EnterReturnsTrue    = 1 << 5,   // Return 'true' when Enter is pressed (as opposed to when the value was modified)
413    ImGuiInputTextFlags_CallbackCompletion  = 1 << 6,   // Call user function on pressing TAB (for completion handling)
414    ImGuiInputTextFlags_CallbackHistory     = 1 << 7,   // Call user function on pressing Up/Down arrows (for history handling)
415    ImGuiInputTextFlags_CallbackAlways      = 1 << 8,   // Call user function every time
416    ImGuiInputTextFlags_CallbackCharFilter  = 1 << 9    // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.
396417};
397418
398419// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
r244869r244870
488509    ImGuiColorEditMode_HEX = 2
489510};
490511
491// Condition flags for ImGui::SetWindow***() and SetNextWindow***() functions
492// Those functions treat 0 as a shortcut to ImGuiSetCondition_Always
493enum ImGuiSetCondition_
512// Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions
513// All those functions treat 0 as a shortcut to ImGuiSetCond_Always
514enum ImGuiSetCond_
494515{
495    ImGuiSetCondition_Always              = 1 << 0, // Set the variable
496    ImGuiSetCondition_FirstUseThisSession = 1 << 1, // Only set the variable on the first call for this window (once per session)
497    ImGuiSetCondition_FirstUseEver        = 1 << 2  // Only set the variable if the window doesn't exist in the .ini file
516    ImGuiSetCond_Always        = 1 << 0, // Set the variable
517    ImGuiSetCond_Once          = 1 << 1, // Only set the variable on the first call per runtime session
518    ImGuiSetCond_FirstUseEver  = 1 << 2  // Only set the variable if the window doesn't exist in the .ini file
498519};
499520
500521struct ImGuiStyle
r244869r244870
513534    float       WindowFillAlphaDefault;     // Default alpha of window background, if not specified in ImGui::Begin()
514535    float       TreeNodeSpacing;            // Horizontal spacing when entering a tree node
515536    float       ColumnsMinSpacing;          // Minimum horizontal spacing between two columns
516    float       ScrollBarWidth;             // Width of the vertical scroll bar
537    float       ScrollbarWidth;             // Width of the vertical scrollbar
538    float       GrabMinSize;                // Minimum width/height of a slider or scrollbar grab
517539    ImVec4      Colors[ImGuiCol_COUNT];
518540
519541    IMGUI_API ImGuiStyle();
r244869r244870
529551
530552    ImVec2        DisplaySize;              // <unset>              // Display size, in pixels. For clamping windows positions.
531553    float         DeltaTime;                // = 1.0f/60.0f         // Time elapsed since last frame, in seconds.
532    float         IniSavingRate;            // = 5.0f               // Maximum time between saving .ini file, in seconds.
554    float         IniSavingRate;            // = 5.0f               // Maximum time between saving positions/sizes to .ini file, in seconds.
533555    const char*   IniFilename;              // = "imgui.ini"        // Path to .ini file. NULL to disable .ini saving.
534556    const char*   LogFilename;              // = "imgui_log.txt"    // Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
535557    float         MouseDoubleClickTime;     // = 0.30f              // Time for a double-click, in seconds.
r244869r244870
547569    // User Functions
548570    //------------------------------------------------------------------
549571
550    // REQUIRED: rendering function.
572    // REQUIRED: rendering function.
551573    // See example code if you are unsure of how to implement this.
552    void        (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
574    void        (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);     
553575
554    // Optional: access OS clipboard (default to use native Win32 clipboard on Windows, otherwise use a ImGui private clipboard)
555    // Override to access OS clipboard on other architectures.
576    // Optional: access OS clipboard
577    // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
556578    const char* (*GetClipboardTextFn)();
557579    void        (*SetClipboardTextFn)(const char* text);
558580
559    // Optional: override memory allocations (default to posix malloc/free). MemFreeFn() may be called with a NULL pointer.
581    // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
582    // (default to posix malloc/free)
560583    void*       (*MemAllocFn)(size_t sz);
561584    void        (*MemFreeFn)(void* ptr);
562585
563    // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese inputs in Windows)
586    // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows)
587    // (default to use native imm32 api on Windows)
564588    void        (*ImeSetInputScreenPosFn)(int x, int y);
589    void*       ImeWindowHandle;            // (Windows) Set this to your HWND to get automatic IME cursor positioning.
565590
566591    //------------------------------------------------------------------
567592    // Input - Fill before calling NewFrame()
568593    //------------------------------------------------------------------
569594
570595    ImVec2      MousePos;                   // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
571    bool        MouseDown[5];               // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
572    float       MouseWheel;                 // Mouse wheel: 1 unit scrolls about 5 lines text.
596    bool        MouseDown[5];               // Mouse buttons. ImGui itself only uses button 0 (left button). Others buttons allows to track if mouse is being used by your application + available to user as a convenience via IsMouse** API.
597    float       MouseWheel;                 // Mouse wheel: 1 unit scrolls about 5 lines text.
573598    bool        MouseDrawCursor;            // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor).
574599    bool        KeyCtrl;                    // Keyboard modifier pressed: Control
575600    bool        KeyShift;                   // Keyboard modifier pressed: Shift
576    bool        KeysDown[512];              // Keyboard keys that are pressed (in whatever order user naturally has access to keyboard data)
601    bool        KeysDown[512];              // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data)
577602    ImWchar     InputCharacters[16+1];      // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
578603
579604    // Function
r244869r244870
585610
586611    bool        WantCaptureMouse;           // Mouse is hovering a window or widget is active (= ImGui will use your mouse input)
587612    bool        WantCaptureKeyboard;        // Widget is active (= ImGui will use your keyboard input)
613    float       Framerate;                  // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames
588614
589615    //------------------------------------------------------------------
590616    // [Internal] ImGui will maintain those fields for you
591617    //------------------------------------------------------------------
592618
593    ImVec2      MousePosPrev;               //
619    ImVec2      MousePosPrev;               // Previous mouse position
594620    ImVec2      MouseDelta;                 // Mouse delta. Note that this is zero if either current or previous position are negative to allow mouse enabling/disabling.
595621    bool        MouseClicked[5];            // Mouse button went from !Down to Down
596622    ImVec2      MouseClickedPos[5];         // Position at time of clicking
r244869r244870
646672    ImVector<TextRange> Filters;
647673    int                 CountGrep;
648674
649    ImGuiTextFilter();
675    ImGuiTextFilter(const char* default_filter = "");
650676    void Clear() { InputBuf[0] = 0; Build(); }
651677    void Draw(const char* label = "Filter (inc,-exc)", float width = -1.0f);    // Helper calling InputText+Build
652678    bool PassFilter(const char* val) const;
r244869r244870
680706// - You want to store custom debug data easily without adding or editing structures in your code.
681707struct ImGuiStorage
682708{
683    struct Pair
684    {
685        ImGuiID key;
686        union { int val_i; float val_f; void* val_p; };
687        Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
688        Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
689        Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }
709    struct Pair
710    {
711        ImGuiID key;
712        union { int val_i; float val_f; void* val_p; };       
713        Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
714        Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
715        Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }
690716    };
691717    ImVector<Pair>    Data;
692718
r244869r244870
701727    IMGUI_API void*   GetVoidPtr(ImGuiID key) const; // default_val is NULL
702728    IMGUI_API void    SetVoidPtr(ImGuiID key, void* val);
703729
704    // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.
730    // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.
705731    // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
706732    // - A typical use case where this is convenient:
707733    //      float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar;
r244869r244870
716742// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
717743struct ImGuiTextEditCallbackData
718744{
719    ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)        // Read-only
720    char*               Buf;            // Current text                     // Read-write (pointed data only)
721    size_t              BufSize;        //                                  // Read-only
722    bool                BufDirty;       // Set if you modify Buf directly   // Write
723    ImGuiInputTextFlags Flags;          // What user passed to InputText()  // Read-only
724    int                 CursorPos;      //                                  // Read-write
725    int                 SelectionStart; //                                  // Read-write (== to SelectionEnd when no selection)
726    int                 SelectionEnd;   //                                  // Read-write
727    void*               UserData;       // What user passed to InputText()
745    ImGuiInputTextFlags EventFlag;      // One of ImGuiInputTextFlags_Callback* // Read-only
746    ImGuiInputTextFlags Flags;          // What user passed to InputText()      // Read-only
747    void*               UserData;       // What user passed to InputText()      // Read-only
728748
749    // CharFilter event:
750    ImWchar             EventChar;      // Character input                      // Read-write (replace character or set to zero)
751
752    // Completion,History,Always events:
753    ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)            // Read-only
754    char*               Buf;            // Current text                         // Read-write (pointed data only)
755    size_t              BufSize;        //                                      // Read-only
756    bool                BufDirty;       // Set if you modify Buf directly       // Write
757    int                 CursorPos;      //                                      // Read-write
758    int                 SelectionStart; //                                      // Read-write (== to SelectionEnd when no selection)
759    int                 SelectionEnd;   //                                      // Read-write
760
729761    // NB: calling those function loses selection.
730762    void DeleteChars(int pos, int bytes_count);
731763    void InsertChars(int pos, const char* text, const char* text_end = NULL);
r244869r244870
740772    ImColor(int r, int g, int b, int a = 255)                       { Value.x = (float)r / 255.0f; Value.y = (float)g / 255.0f; Value.z = (float)b / 255.0f; Value.w = (float)a / 255.0f; }
741773    ImColor(float r, float g, float b, float a = 1.0f)              { Value.x = r; Value.y = g; Value.z = b; Value.w = a; }
742774    ImColor(const ImVec4& col)                                      { Value = col; }
743
744775    operator ImU32() const                                          { return ImGui::ColorConvertFloat4ToU32(Value); }
745776    operator ImVec4() const                                         { return Value; }
746777
r244869r244870
763794// It is up to you to decide if your rendering loop or the callback should be responsible for backup/restoring rendering state.
764795typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd);
765796
766// Typically, 1 command = 1 gpu draw call
797// Typically, 1 command = 1 gpu draw call (unless command is a callback)
767798struct ImDrawCmd
768799{
769800    unsigned int    vtx_count;                  // Number of vertices (multiple of 3) to be drawn as triangles. The vertices are stored in the callee ImDrawList's vtx_buffer[] array.
r244869r244870
802833
803834    // [Internal to ImGui]
804835    ImVector<ImVec4>        clip_rect_stack;    // [Internal]
805    ImVector<ImTextureID>   texture_id_stack;   // [Internal]
836    ImVector<ImTextureID>   texture_id_stack;   // [Internal]
806837    ImDrawVert*             vtx_write;          // [Internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much)
807838
808839    ImDrawList() { Clear(); }
r244869r244870
812843    IMGUI_API void  PushTextureID(const ImTextureID& texture_id);
813844    IMGUI_API void  PopTextureID();
814845
815    // Primitives
846    // Primitives   
816847    IMGUI_API void  AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
817848    IMGUI_API void  AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
818849    IMGUI_API void  AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
r244869r244870
897928    float               FontSize;           // <user set>      // Height of characters, set during loading (don't change after loading)
898929    float               Scale;              // = 1.0f          // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
899930    ImVec2              DisplayOffset;      // = (0.0f,0.0f)   // Offset font rendering by xx pixels
900    ImWchar             FallbackChar;       // = '?'           // Replacement glyph if one isn't found.
931    ImWchar             FallbackChar;       // = '?'           // Replacement glyph if one isn't found. Only set via SetFallbackChar()
901932
902933    // Members: Runtime data
903934    struct Glyph
r244869r244870
910941    };
911942    ImFontAtlas*        ContainerAtlas;     // What we has been loaded into
912943    ImVector<Glyph>     Glyphs;
944    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
945    float               FallbackXAdvance;   //
946    ImVector<float>     IndexXAdvance;      // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI)
913947    ImVector<int>       IndexLookup;        // Index glyphs by Unicode code-point
914    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
915948
916949    // Methods
917950    IMGUI_API ImFont();
r244869r244870
919952    IMGUI_API void                  Clear();
920953    IMGUI_API void                  BuildLookupTable();
921954    IMGUI_API const Glyph*          FindGlyph(unsigned short c) const;
955    IMGUI_API void                  SetFallbackChar(ImWchar c);
922956    IMGUI_API bool                  IsLoaded() const        { return ContainerAtlas != NULL; }
923957
924958    // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
trunk/3rdparty/bgfx/README.md
r244869r244870
7373focusing on racing games. 
7474![ios](http://www.dogbytegames.com/bgfx/offroadlegends2_bgfx_ipad2.jpg)
7575
76https://github.com/andr3wmac/Torque6 Torque 6 is an MIT licensed 3D engine
77loosely based on Torque2D. Being neither Torque2D or Torque3D it is the 6th
78derivative of the original Torque Engine.
79
80https://github.com/cgbystrom/twinkle GPU-accelerated UI framework powered by
81JavaScript for desktop/mobile apps. Idea is to combine the fast workflow and
82deployment model of web with the performance of native code and GPU acceleration.
83
7684Examples
7785--------
7886
trunk/3rdparty/bgfx/examples/common/entry/entry.cpp
r244869r244870
3434   }
3535#endif // ENTRY_CONFIG_IMPLEMENT_DEFAULT_ALLOCATOR
3636
37   char keyToAscii(Key::Enum _key, uint8_t _modifiers)
38   {
39      const bool isAscii = (Key::Key0 <= _key && _key <= Key::KeyZ)
40                    || (Key::Esc  <= _key && _key <= Key::Minus);
41      if (!isAscii)
42      {
43         return '\0';
44      }
45
46      const bool isNumber = (Key::Key0 <= _key && _key <= Key::Key9);
47      if (isNumber)
48      {
49         return '0' + (_key - Key::Key0);
50      }
51
52      const bool isChar = (Key::KeyA <= _key && _key <= Key::KeyZ);
53      if (isChar)
54      {
55         enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift };
56
57         const bool shift = !!(_modifiers&ShiftMask);
58         return (shift ? 'A' : 'a') + (_key - Key::KeyA);
59      }
60
61      switch (_key)
62      {
63      case Key::Esc:       { return 0x1b; } break;
64      case Key::Return:    { return 0x0d; } break;
65      case Key::Tab:       { return 0x09; } break;
66      case Key::Space:     { return 0xa0; } break;
67      case Key::Backspace: { return 0x08; } break;
68      case Key::Plus:      { return 0x2b; } break;
69      case Key::Minus:     { return 0x2d; } break;
70      default:        { return '\0'; } break;
71      }
72   }
73
3774   bool setOrToggle(uint32_t& _flags, const char* _name, uint32_t _bit, int _first, int _argc, char const* const* _argv)
3875   {
3976      if (0 == strcmp(_argv[_first], _name) )
trunk/3rdparty/bgfx/examples/common/entry/entry.h
r244869r244870
211211   void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height);
212212   void setWindowTitle(WindowHandle _handle, const char* _title);
213213   void toggleWindowFrame(WindowHandle _handle);
214   void toggleFullscreen(WindowHandle _handle);
214215   void setMouseLock(WindowHandle _handle, bool _lock);
215216
216217   struct WindowState
trunk/3rdparty/bgfx/examples/common/entry/entry_android.cpp
r244869r244870
440440      BX_UNUSED(_handle);
441441   }
442442
443   void toggleFullscreen(WindowHandle _handle)
444   {
445      BX_UNUSED(_handle);
446   }
447
443448   void setMouseLock(WindowHandle _handle, bool _lock)
444449   {
445450      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_asmjs.cpp
r244869r244870
5959      BX_UNUSED(_handle);
6060   }
6161
62   void toggleFullscreen(WindowHandle _handle)
63   {
64      BX_UNUSED(_handle);
65   }
66
6267   void setMouseLock(WindowHandle _handle, bool _lock)
6368   {
6469      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_ios.mm
r244869r244870
126126      BX_UNUSED(_handle);
127127   }
128128
129   void toggleFullscreen(WindowHandle _handle)
130   {
131      BX_UNUSED(_handle);
132   }
133
129134   void setMouseLock(WindowHandle _handle, bool _lock)
130135   {
131136      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_nacl.cpp
r244869r244870
9494      BX_UNUSED(_handle);
9595   }
9696
97   void toggleFullscreen(WindowHandle _handle)
98   {
99      BX_UNUSED(_handle);
100   }
101
97102   void setMouseLock(WindowHandle _handle, bool _lock)
98103   {
99104      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_osx.mm
r244869r244870
8181         , m_mx(0)
8282         , m_my(0)
8383         , m_scroll(0)
84         , m_style(0)
8485         , m_exit(false)
86         , m_fullscreen(false)
8587      {
8688         s_translateKey[27]             = Key::Esc;
8789         s_translateKey[13]             = Key::Return;
r244869r244870
138140         NSWindow* window = m_window[handle.idx];
139141         NSRect originalFrame = [window frame];
140142         NSPoint location = [window mouseLocationOutsideOfEventStream];
141         NSRect adjustFrame = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSTitledWindowMask];
143         NSRect adjustFrame = [window contentRectForFrameRect: originalFrame];
142144
143145         int x = location.x;
144146         int y = (int)adjustFrame.size.height - (int)location.y;
r244869r244870
246248               case NSLeftMouseDown:
247249               {
248250                  // TODO: remove!
249                  // Shift + Left Mouse Button acts as middle! This just a temporary solution!
251                  // Command + Left Mouse Button acts as middle! This just a temporary solution!
250252                  // This is becase the average OSX user doesn't have middle mouse click.
251                  MouseButton::Enum mb = ([event modifierFlags] & NSShiftKeyMask) ? MouseButton::Middle : MouseButton::Left;
253                  MouseButton::Enum mb = ([event modifierFlags] & NSCommandKeyMask) ? MouseButton::Middle : MouseButton::Left;
252254                  m_eventQueue.postMouseEvent(s_defaultWindow, m_mx, m_my, m_scroll, mb, true);
253255                  break;
254256               }
r244869r244870
306308                     {
307309                        m_eventQueue.postExitEvent();
308310                     }
309                     else if ( (Key::Key0 <= key && key <= Key::KeyZ)
310                          ||   (Key::Esc  <= key && key <= Key::Minus) )
311                     {
312                        m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar);
313                        return false;
314                     }
315311                     else
316312                     {
317                        m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true);
318                        return false;
313                        enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift };
314                        const bool nonShiftModifiers = (0 != (modifiers&(~ShiftMask) ) );
315                        const bool isCharPressed = (Key::Key0 <= key && key <= Key::KeyZ) || (Key::Esc <= key && key <= Key::Minus);
316                        const bool isText = isCharPressed && !nonShiftModifiers;
317                        if (isText)
318                        {
319                           m_eventQueue.postCharEvent(s_defaultWindow, 1, pressedChar);
320                           return false;
321                        }
322                        else
323                        {
324                           m_eventQueue.postKeyEvent(s_defaultWindow, key, modifiers, true);
325                           return false;
326                        }
319327                     }
320328                  }
321329
r244869r244870
354362         WindowHandle handle = { 0 };
355363         NSWindow* window = m_window[handle.idx];
356364         NSRect originalFrame = [window frame];
357         NSRect rect = [NSWindow contentRectForFrameRect: originalFrame styleMask: NSTitledWindowMask];
365         NSRect rect = [window contentRectForFrameRect: originalFrame];
358366         uint32_t width  = uint32_t(rect.size.width);
359367         uint32_t height = uint32_t(rect.size.height);
360368         m_eventQueue.postSizeEvent(handle, width, height);
r244869r244870
398406         [menubar addItem:appMenuItem];
399407         [NSApp setMainMenu:menubar];
400408
409         m_style = 0
410               | NSTitledWindowMask
411               | NSClosableWindowMask
412               | NSMiniaturizableWindowMask
413               | NSResizableWindowMask
414               ;
415
416         NSRect screenRect = [[NSScreen mainScreen] frame];
417         const float centerX = (screenRect.size.width  - (float)ENTRY_DEFAULT_WIDTH )*0.5f;
418         const float centerY = (screenRect.size.height - (float)ENTRY_DEFAULT_HEIGHT)*0.5f;
419
401420         m_windowAlloc.alloc();
402         NSRect rect = NSMakeRect(0, 0, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);
421         NSRect rect = NSMakeRect(centerX, centerY, (float)ENTRY_DEFAULT_WIDTH, (float)ENTRY_DEFAULT_HEIGHT);
403422         NSWindow* window = [[NSWindow alloc]
404423            initWithContentRect:rect
405            styleMask:0
406            |NSTitledWindowMask
407            |NSClosableWindowMask
408            |NSMiniaturizableWindowMask
409            |NSResizableWindowMask
424            styleMask:m_style
410425            backing:NSBackingStoreBuffered defer:NO
411426         ];
412427         NSString* appName = [[NSProcessInfo processInfo] processName];
413428         [window setTitle:appName];
414         [window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
415429         [window makeKeyAndOrderFront:window];
416430         [window setAcceptsMouseMovedEvents:YES];
417431         [window setBackgroundColor:[NSColor blackColor]];
418432         [[Window sharedDelegate] windowCreated:window];
419433
420434         m_window[0] = window;
435         m_windowFrame = [window frame];
421436
422437         bgfx::osxSetNSWindow(window);
423438
r244869r244870
448463         return 0;
449464      }
450465
466      bool isValid(WindowHandle _handle)
467      {
468         return m_windowAlloc.isValid(_handle.idx);
469      }
470
451471      EventQueue m_eventQueue;
452472
453473      bx::HandleAllocT<ENTRY_CONFIG_MAX_WINDOWS> m_windowAlloc;
454474      NSWindow* m_window[ENTRY_CONFIG_MAX_WINDOWS];
475      NSRect m_windowFrame;
455476
456477      float   m_scrollf;
457478      int32_t m_mx;
458479      int32_t m_my;
459480      int32_t m_scroll;
481      int32_t m_style;
460482      bool    m_exit;
483      bool    m_fullscreen;
461484   };
462485
463486   static Context s_ctx;
r244869r244870
486509
487510   void destroyWindow(WindowHandle _handle)
488511   {
489      BX_UNUSED(_handle);
512      if (s_ctx.isValid(_handle) )
513      {
514         dispatch_async(dispatch_get_main_queue()
515         , ^{
516            [s_ctx.m_window[_handle.idx] performClose: nil];
517         });
518      }
490519   }
491520
492521   void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
493522   {
494      BX_UNUSED(_handle, _x, _y);
523      if (s_ctx.isValid(_handle) )
524      {
525         NSWindow* window = s_ctx.m_window[_handle.idx];
526         NSScreen* screen = [window screen];
527
528         NSRect screenRect = [screen frame];
529         CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
530
531         NSPoint position = { float(_x), screenRect.size.height - menuBarHeight - float(_y) };
532
533         dispatch_async(dispatch_get_main_queue()
534         , ^{
535            [window setFrameTopLeftPoint: position];
536         });
537      }
495538   }
496539
497540   void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
498541   {
499      BX_UNUSED(_handle, _width, _height);
542      if (s_ctx.isValid(_handle) )
543      {
544         NSSize size = { float(_width), float(_height) };
545         dispatch_async(dispatch_get_main_queue()
546         , ^{
547            [s_ctx.m_window[_handle.idx] setContentSize: size];
548         });
549      }
500550   }
501551
502552   void setWindowTitle(WindowHandle _handle, const char* _title)
503553   {
504      BX_UNUSED(_handle, _title);
554      if (s_ctx.isValid(_handle) )
555      {
556         NSString* title = [[NSString alloc] initWithCString:_title encoding:1];
557         dispatch_async(dispatch_get_main_queue()
558         , ^{
559            [s_ctx.m_window[_handle.idx] setTitle: title];
560         });
561         [title release];
562      }
505563   }
506564
507565   void toggleWindowFrame(WindowHandle _handle)
508566   {
509      BX_UNUSED(_handle);
567      if (s_ctx.isValid(_handle) )
568      {
569         s_ctx.m_style ^= NSTitledWindowMask;
570         dispatch_async(dispatch_get_main_queue()
571         , ^{
572            [s_ctx.m_window[_handle.idx] setStyleMask: s_ctx.m_style];
573         });
574      }
510575   }
511576
577   void toggleFullscreen(WindowHandle _handle)
578   {
579      if (s_ctx.isValid(_handle) )
580      {
581         NSWindow* window = s_ctx.m_window[_handle.idx];
582         NSScreen* screen = [window screen];
583         NSRect screenRect = [screen frame];
584
585         if (!s_ctx.m_fullscreen)
586         {
587            [NSMenu setMenuBarVisible: false];
588            s_ctx.m_style &= ~NSTitledWindowMask;
589            dispatch_async(dispatch_get_main_queue()
590            , ^{
591               [window setStyleMask: s_ctx.m_style];
592               [window setFrame:screenRect display:YES];
593            });
594
595            s_ctx.m_fullscreen = true;
596         }
597         else
598         {
599            [NSMenu setMenuBarVisible: true];
600            s_ctx.m_style |= NSTitledWindowMask;
601            dispatch_async(dispatch_get_main_queue()
602            , ^{
603               [window setStyleMask: s_ctx.m_style];
604               [window setFrame:s_ctx.m_windowFrame display:YES];
605            });
606
607            s_ctx.m_fullscreen = false;
608         }
609      }
610   }
611
512612   void setMouseLock(WindowHandle _handle, bool _lock)
513613   {
514614      BX_UNUSED(_handle, _lock);
r244869r244870
610710   using namespace entry;
611711   s_ctx.windowDidResize();
612712}
713
613714@end
614715
615716int main(int _argc, char** _argv)
trunk/3rdparty/bgfx/examples/common/entry/entry_p.h
r244869r244870
5656
5757   int main(int _argc, char** _argv);
5858
59   char keyToAscii(Key::Enum _key, uint8_t _modifiers);
60
5961   struct Event
6062   {
6163      enum Enum
trunk/3rdparty/bgfx/examples/common/entry/entry_qnx.cpp
r244869r244870
5959      BX_UNUSED(_handle);
6060   }
6161
62   void toggleFullscreen(WindowHandle _handle)
63   {
64      BX_UNUSED(_handle);
65   }
66
6267   void setMouseLock(WindowHandle _handle, bool _lock)
6368   {
6469      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_sdl.cpp
r244869r244870
179179      SDL_USER_WINDOW_SET_POS,
180180      SDL_USER_WINDOW_SET_SIZE,
181181      SDL_USER_WINDOW_TOGGLE_FRAME,
182      SDL_USER_WINDOW_TOGGLE_FULL_SCREEN,
182183      SDL_USER_WINDOW_MOUSE_LOCK,
183184   };
184185
r244869r244870
191192      union { void* p; WindowHandle h; } cast;
192193      cast.h = _handle;
193194      uev.data1 = cast.p;
194     
195
195196      uev.data2 = _msg;
196197      uev.code = _code;
197198      SDL_PushEvent(&event);
r244869r244870
211212         , m_height(ENTRY_DEFAULT_HEIGHT)
212213         , m_aspectRatio(16.0f/9.0f)
213214         , m_mouseLock(false)
215         , m_fullscreen(false)
214216      {
215217         memset(s_translateKey, 0, sizeof(s_translateKey) );
216218         initTranslateKey(SDL_SCANCODE_ESCAPE,       Key::Esc);
r244869r244870
410412                  break;
411413
412414               case SDL_KEYDOWN:
415                  {
416                     const SDL_KeyboardEvent& kev = event.key;
417                     WindowHandle handle = findHandle(kev.windowID);
418                     if (isValid(handle) )
419                     {
420                        uint8_t modifiers = translateKeyModifiers(kev.keysym.mod);
421                        Key::Enum key = translateKey(kev.keysym.scancode);
422
423                        const uint8_t shiftMask = Modifier::LeftShift|Modifier::RightShift;
424                        const bool nonShiftModifiers = (0 != (modifiers&(~shiftMask) ) );
425                        const bool isCharPressed = (Key::Key0 <= key && key <= Key::KeyZ) || (Key::Esc <= key && key <= Key::Minus);
426                        const bool isText = isCharPressed && !nonShiftModifiers;
427
428                        if (isText)
429                        {
430                           uint8_t pressedChar[4];
431                           pressedChar[0] = keyToAscii(key, modifiers);
432                           m_eventQueue.postCharEvent(handle, 1, pressedChar);
433                        }
434                        else
435                        {
436                           m_eventQueue.postKeyEvent(handle, key, modifiers, kev.state == SDL_PRESSED);
437                        }
438                     }
439                  }
440                  break;
413441               case SDL_KEYUP:
414442                  {
415443                     const SDL_KeyboardEvent& kev = event.key;
r244869r244870
615643                        }
616644                        break;
617645
646                     case SDL_USER_WINDOW_TOGGLE_FULL_SCREEN:
647                        {
648                           WindowHandle handle = getWindowHandle(uev);
649                           m_fullscreen = !m_fullscreen;
650                           SDL_SetWindowFullscreen(m_window[handle.idx], m_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
651                        }
652                        break;
653
618654                     case SDL_USER_WINDOW_MOUSE_LOCK:
619655                        {
620656                           SDL_SetRelativeMouseMode(!!uev.code ? SDL_TRUE : SDL_FALSE);
r244869r244870
669705            m_width  = _width;
670706            m_height = _height;
671707
672            if (m_width < m_height)
673            {
674               float aspectRatio = 1.0f/m_aspectRatio;
675               m_width = bx::uint32_max(ENTRY_DEFAULT_WIDTH/4, m_width);
676               m_height = uint32_t(float(m_width)*aspectRatio);
677            }
678            else
679            {
680               float aspectRatio = m_aspectRatio;
681               m_height = bx::uint32_max(ENTRY_DEFAULT_HEIGHT/4, m_height);
682               m_width = uint32_t(float(m_height)*aspectRatio);
683            }
684
685708            SDL_SetWindowSize(m_window[_handle.idx], m_width, m_height);
686709            m_eventQueue.postSizeEvent(_handle, m_width, m_height);
687710         }
r244869r244870
723746      int32_t m_mx;
724747      int32_t m_my;
725748      bool m_mouseLock;
749      bool m_fullscreen;
726750   };
727751
728752   static Context s_ctx;
r244869r244870
805829      sdlPostEvent(SDL_USER_WINDOW_TOGGLE_FRAME, _handle);
806830   }
807831
832   void toggleFullscreen(WindowHandle _handle)
833   {
834      sdlPostEvent(SDL_USER_WINDOW_TOGGLE_FULL_SCREEN, _handle);
835   }
836
808837   void setMouseLock(WindowHandle _handle, bool _lock)
809838   {
810839      sdlPostEvent(SDL_USER_WINDOW_MOUSE_LOCK, _handle, NULL, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_windows.cpp
r244869r244870
10671067      PostMessage(s_ctx.m_hwnd[0], WM_USER_WINDOW_TOGGLE_FRAME, _handle.idx, 0);
10681068   }
10691069
1070   void toggleFullscreen(WindowHandle _handle)
1071   {
1072      BX_UNUSED(_handle);
1073   }
1074
10701075   void setMouseLock(WindowHandle _handle, bool _lock)
10711076   {
10721077      PostMessage(s_ctx.m_hwnd[0], WM_USER_WINDOW_MOUSE_LOCK, _handle.idx, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_winrt.cpp
r244869r244870
175175      BX_UNUSED(_handle);
176176   }
177177
178   void toggleFullscreen(WindowHandle _handle)
179   {
180      BX_UNUSED(_handle);
181   }
182
178183   void setMouseLock(WindowHandle _handle, bool _lock)
179184   {
180185      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/entry/entry_x11.cpp
r244869r244870
664664      BX_UNUSED(_handle);
665665   }
666666
667   void toggleFullscreen(WindowHandle _handle)
668   {
669      BX_UNUSED(_handle);
670   }
671
667672   void setMouseLock(WindowHandle _handle, bool _lock)
668673   {
669674      BX_UNUSED(_handle, _lock);
trunk/3rdparty/bgfx/examples/common/imgui/ocornut_imgui.cpp
r244869r244870
165165
166166      ImGui::NewFrame();
167167
168//      ImGui::ShowTestWindow();
168      ImGui::ShowTestWindow();
169169   }
170170
171171   void endFrame()
trunk/3rdparty/bgfx/scripts/bgfx.lua
r244869r244870
4646         }
4747      end
4848
49      if (_OPTIONS["vs"] == "vs2012-xp")
50      or (_OPTIONS["vs"] == "vs2013-xp") then
51         configuration { "vs201*" }
52            includedirs {
53               "$(DXSDK_DIR)/include",
54            }
55      end
56
4957      configuration { "Debug" }
5058         defines {
5159            "BGFX_CONFIG_DEBUG=1",
r244869r244870
6270            "$(DXSDK_DIR)/include",
6371         }
6472
65      if (_OPTIONS["vs"] == "vs2012-xp") or (_OPTIONS["vs"] == "vs2013-xp") then
66      configuration { "vs201*" }
67         includedirs {
68            "$(DXSDK_DIR)/include",
69         }
70      end
71
7273      configuration { "winphone8*"}
7374         linkoptions {
7475            "/ignore:4264" -- LNK4264: archiving object file compiled with /ZW into a static library; note that when authoring Windows Runtime types it is not recommended to link with a static library that contains Windows Runtime metadata
trunk/3rdparty/bx/include/bx/handlealloc.h
r244869r244870
6666         return invalid;
6767      }
6868
69      bool isValid(uint16_t _handle)
70      {
71         uint16_t* sparse = &m_handles[MaxHandlesT];
72         uint16_t index = sparse[_handle];
73
74         return (index < m_numHandles && m_handles[index] == _handle);
75      }
76
6977      void free(uint16_t _handle)
7078      {
7179         BX_CHECK(0 < m_numHandles, "Freeing invalid handle %d.", _handle);
r244869r244870
139147         return invalid;
140148      }
141149
150      bool isValid(uint16_t _handle)
151      {
152         uint16_t* sparse = &m_handles[m_maxHandles];
153         uint16_t index = sparse[_handle];
154
155         return (index < m_numHandles && m_handles[index] == _handle);
156      }
157
142158      void free(uint16_t _handle)
143159      {
144160         uint16_t* sparse = &m_handles[m_maxHandles];
trunk/3rdparty/genie/README.md
r244869r244870
1414Download (stable)
1515-----------------
1616
17   version 197 (commit 2b34cf0f0831d265b274d8e11a24bf6320d73d6e)
17   version 206 (commit e65d8143b1186496b9da03c6461a25402a2ee873)
1818
1919Linux: 
2020https://github.com/bkaradzic/bx/raw/master/tools/bin/linux/genie
r244869r244870
9696confusion for users who are not familiar with Premake, and they just need to
9797use Premake to generate project files for project they are interested in.
9898
99I've been using Premake for [a while](https://carbongames.com/2011/08/Premake/),
99I've been using Premake for [a while](https://web.archive.org/web/20120119020903/http://carbongames.com/2011/08/Premake),
100100I really like it's simplicity, and that it does one thing really well.
101101
102102I was considering replacing Premake with other build systems that also could
trunk/3rdparty/genie/src/actions/make/make_cpp.lua
r244869r244870
55--
66
77   premake.make.cpp = { }
8   premake.make.undefine = { }
89   local cpp = premake.make.cpp
910   local make = premake.make
1011
r244869r244870
173174      _p('  config=%s', _MAKE.esc(premake.getconfigname(prj.solution.configurations[1], platforms[1], true)))
174175      _p('endif')
175176      _p('')
176
177      for _, variable in ipairs(premake.make.undefine) do
178         _p('override undefine '.. variable)
179      end
180      _p('')
177181      _p('ifndef verbose')
178182      _p('  SILENT = @')
179183      _p('endif')
trunk/3rdparty/genie/src/host/premake.c
r244869r244870
359359      }
360360   }
361361
362   /* set error handler to get tracebacks in built-in scripts  */
363   lua_getglobal(L, "debug");
364   lua_getfield(L, -1, "traceback");
365   lua_remove(L, -2);
366   int ehpos = lua_gettop(L);
367   
362368   /* hand off control to the scripts */
363369   lua_getglobal(L, "_premake_main");
364   if (lua_pcall(L, 0, 1, 0) != OKAY)
370   if (lua_pcall(L, 0, 1, ehpos) != OKAY)
365371   {
366372      printf(ERROR_MESSAGE, lua_tostring(L, -1));
367373      return !OKAY;
trunk/3rdparty/genie/src/host/scripts.c
r244869r244870
179179   "ative(sln.location, prj.location)), _MAKE.esc(_MAKE.getmakefilename(prj, true)))\n_p('')\nend\n_p('clean:')\nfor _ ,prj in ipairs(sln.projects) do\n_p('\\t@${MAKE} --no-print-directory -C %s -f %s clean', _MAKE.esc(path.getrelative(sln.location, prj.location)), _MAKE.esc(_MAKE.getmakefilename(prj, true)))\nend\n_p('')\n_p('help:')\n_p(1,'@echo \"Usage: make [config=name] [target]\"')\n_p(1,'@echo \"\"')\n_p(1,'@echo \"CONFIGURATIONS:\"')\nlocal cfgpairs = { }\nfor _, platform in ipairs(platforms) do\nfor _, cfgname in ipairs(sln.configurations) do\n_p(1,'@echo \"   %s\"', premake.getconfigname(cfgname, platform, true))\nend\nend\n_p(1,'@echo \"\"')\n_p(1,'@echo \"TARGETS:\"')\n_p(1,'@echo \"   all (default)\"')\n_p(1,'@echo \"   clean\"')\nfor _, prj in ipairs(sln.projects) do\n_p(1,'@echo \"   %s\"', prj.name)\nend\n_p(1,'@echo \"\"')\n_p(1,'@echo \"For more information, see http://industriousone.com/premake/quick-start\"')\nend\n",
180180
181181   /* actions/make/make_cpp.lua */
182   "premake.make.cpp = { }\nlocal cpp = premake.make.cpp\nlocal make = premake.make\nfunction premake.make_cpp(prj)\nlocal cc = premake.gettool(prj)\nlocal platforms = premake.filterplatforms(prj.solution, cc.platforms, \"Native\")\npremake.gmake_cpp_header(prj, cc, platforms)\nfor _, platform in ipairs(platforms) do\nfor cfg in premake.eachconfig(prj, platform) do\npremake.gmake_cpp_config(prj, cfg, cc)\nend\nend\nlocal objdirs = {}\nfor _, file in ipairs(prj.files) do\nif path.iscppfile(file) then\nobjdirs[_MAKE.esc(path.getdirectory(path.trimdots(file)))] = 1\nend\nend\n_p('OBJDIRS := \\\\')\n_p('\\t$(OBJDIR) \\\\')\nfor dir, _ in pairs(objdirs) do\n_p('\\t$(OBJDIR)/%s \\\\', dir)\nend\n_p('')\n_p('RESOURCES := \\\\')\nfor _, file in ipairs(prj.files) do\nif path.isresourcefile(file) then\n_p('\\t$(OBJDIR)/%s.res \\\\', _MAKE.esc(path.getbasename(file)))\nend\nend\n_p('')\n_p('.PHONY: clean prebuild prelink')\n_p('')\nif os.is(\"MacOSX\") and prj.kind == \"WindowedApp\" then\n_p('all: $(TARGETDIR) $(OBJDIRS) pr"
183   "ebuild prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist')\nelse\n_p('all: $(TARGETDIR) $(OBJDIRS) prebuild prelink $(TARGET)')\nend\n_p('\\t@:')\n_p('')\nif (prj.kind == \"StaticLib\" and prj.options.ArchiveSplit) then\n_p('define max_args')\n_p('\\t$(eval _args:=)')\n_p('\\t$(foreach obj,$3,$(eval _args+=$(obj))$(if $(word $2,$(_args)),$1$(_args)$(EOL)$(eval _args:=)))')\n_p('\\t$(if $(_args),$1$(_args))')\n_p('endef')\n_p('')\n_p('define EOL')\n_p('')\n_p('')\n_p('endef')\n_p('')\nend\n_p('$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(RESOURCES)')\nif prj.kind == \"StaticLib\" then\nif prj.msgarchiving then\n_p('\\t@echo ' .. prj.msgarchiving)\nelse\n_p('\\t@echo Archiving %s', prj.name)\nend\nif (not prj.archivesplit_size) then \nprj.archivesplit_size=200\nend\nif (not prj.options.ArchiveSplit) then\n_p('\\t$(SILENT) $(LINKCMD) $(OBJECTS)')\nelse\n_p('\\t@$(call max_args,$(LINKCMD),'.. prj.archivesplit_size ..',$(OBJECTS))')\nend\nelse\nif prj.msglinking then\n_p('\\t@echo ' .. prj.msgl"
184   "inking)\nelse\n_p('\\t@echo Linking %s', prj.name)\nend\n_p('\\t$(SILENT) $(LINKCMD)')\nend\n_p('\\t$(POSTBUILDCMDS)')\n_p('')\n_p('$(TARGETDIR):')\npremake.make_mkdirrule(\"$(TARGETDIR)\")\n_p('$(OBJDIRS):')\nif (not prj.solution.messageskip) or (not table.contains(prj.solution.messageskip, \"SkipCreatingMessage\")) then\n_p('\\t@echo Creating $(OBJDIR)')\nend\n_p('\\t-$(call MKDIR,$(OBJDIR))')\nfor dir, _ in pairs(objdirs) do\n_p('\\t-$(call MKDIR,$(OBJDIR)/%s)', dir)\nend\n_p('')\nif os.is(\"MacOSX\") and prj.kind == \"WindowedApp\" then\n_p('$(dir $(TARGETDIR))PkgInfo:')\n_p('$(dir $(TARGETDIR))Info.plist:')\n_p('')\nend\n_p('clean:')\nif (not prj.solution.messageskip) or (not table.contains(prj.solution.messageskip, \"SkipCleaningMessage\")) then\n_p('\\t@echo Cleaning %s', prj.name)\nend\n_p('ifeq (posix,$(SHELLTYPE))')\n_p('\\t$(SILENT) rm -f  $(TARGET)')\n_p('\\t$(SILENT) rm -rf $(OBJDIR)')\n_p('else')\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(TARGET)) del $(subst /,\\\\\\\\,$(TARGET))')\n_p('\\t"
185   "$(SILENT) if exist $(subst /,\\\\\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\\\\\,$(OBJDIR))')\n_p('endif')\n_p('')\n_p('prebuild:')\n_p('\\t$(PREBUILDCMDS)')\n_p('')\n_p('prelink:')\n_p('\\t$(PRELINKCMDS)')\n_p('')\ncpp.pchrules(prj)\ncpp.fileRules(prj)\n_p('-include $(OBJECTS:%%.o=%%.d)')\n_p('ifneq (,$(PCH))')\n_p('  -include $(OBJDIR)/$(notdir $(PCH)).d')\n_p('endif')\nend\nfunction premake.gmake_cpp_header(prj, cc, platforms)\n_p('# %s project makefile autogenerated by GENie', premake.action.current().shortname)\n_p('ifndef config')\n_p('  config=%s', _MAKE.esc(premake.getconfigname(prj.solution.configurations[1], platforms[1], true)))\n_p('endif')\n_p('')\n_p('ifndef verbose')\n_p('  SILENT = @')\n_p('endif')\n_p('')\n_p('SHELLTYPE := msdos')\n_p('ifeq (,$(ComSpec)$(COMSPEC))')\n_p('  SHELLTYPE := posix')\n_p('endif')\n_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')\n_p('  SHELLTYPE := posix')\n_p('endif')\n_p('')\n_p('ifeq (posix,$(SHELLTYPE))')\n_p('  MKDIR = $(SILENT) mkdir -p \"$(1)\"')\n_p('  COPY  = $("
186   "SILENT) cp -fR \"$(1)\" \"$(2)\"')\n_p('else')\n_p('  MKDIR = $(SILENT) mkdir \"$(subst /,\\\\\\\\,$(1))\" 2> nul || exit 0')\n_p('  COPY  = $(SILENT) copy /Y \"$(subst /,\\\\\\\\,$(1))\" \"$(subst /,\\\\\\\\,$(2))\"')\n_p('endif')\n_p('')\n_p('CC  = %s', cc.cc)\n_p('CXX = %s', cc.cxx)\n_p('AR  = %s', cc.ar)\n_p('')\n_p('ifndef RESCOMP')\n_p('  ifdef WINDRES')\n_p('    RESCOMP = $(WINDRES)')\n_p('  else')\n_p('    RESCOMP = windres')\n_p('  endif')\n_p('endif')\n_p('')\nend\nfunction premake.gmake_cpp_config(prj, cfg, cc)\n_p('ifeq ($(config),%s)', _MAKE.esc(cfg.shortname))\ncpp.platformtools(cfg, cc)\n_p('  OBJDIR     = %s', _MAKE.esc(cfg.objectsdir))\n_p('  TARGETDIR  = %s', _MAKE.esc(cfg.buildtarget.directory))\n_p('  TARGET     = $(TARGETDIR)/%s', _MAKE.esc(cfg.buildtarget.name))\n_p('  DEFINES   +=%s', make.list(cc.getdefines(cfg.defines)))\n_p('  INCLUDES  +=%s', make.list(cc.getincludedirs(cfg.includedirs)))\ncpp.pchconfig(cfg)\ncpp.flags(cfg, cc)\ncpp.linker(cfg, cc)\n_p('  OBJECTS := \\\\')\nfor _, fi"
187   "le in ipairs(prj.files) do\nif path.iscppfile(file) then\nlocal excluded = false\nfor _, exclude in ipairs(cfg.excludes) do\nexcluded = (exclude == file)\nif (excluded) then break end\nend\nif excluded == false then\n_p('\\t$(OBJDIR)/%s.o \\\\'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n)\nend\nend\nend\n_p('')\n_p('  define PREBUILDCMDS')\nif #cfg.prebuildcommands > 0 then\n_p('\\t@echo Running pre-build commands')\n_p('\\t%s', table.implode(cfg.prebuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define PRELINKCMDS')\nif #cfg.prelinkcommands > 0 then\n_p('\\t@echo Running pre-link commands')\n_p('\\t%s', table.implode(cfg.prelinkcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define POSTBUILDCMDS')\nif #cfg.postbuildcommands > 0 then\n_p('\\t@echo Running post-build commands')\n_p('\\t%s', table.implode(cfg.postbuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\nmake.settings(cfg, cc)\n_p('endif')\n_p('')\nend\nfunction cpp.platformtools(cfg, cc)\nlocal platfor"
188   "m = cc.platforms[cfg.platform]\nif platform.cc then\n_p('  CC         = %s', platform.cc)\nend\nif platform.cxx then\n_p('  CXX        = %s', platform.cxx)\nend\nif platform.ar then\n_p('  AR         = %s', platform.ar)\nend\nend\nfunction cpp.flags(cfg, cc)\nif cfg.pchheader and not cfg.flags.NoPCH then\n_p('  FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p('  FORCE_INCLUDE += -include %s'\n,premake.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p('  ALL_CPPFLAGS  += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))\n_p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))\n_p('  ALL_OBJCFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg),"
189   " cfg.buildoptions, cfg.buildoptions_objc)))\n_p('  ALL_RESFLAGS  += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n        make.list(table.join(cc.getdefines(cfg.resdefines),\n                                cc.getincludedirs(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(cfg, cc)\n_p('  ALL_LDFLAGS   += $(LDFLAGS)%s', make.list(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions)))\n_p('  LDDEPS    +=%s', make.list(_MAKE.esc(premake.getlinks(cfg, \"siblings\", \"fullpath\"))))\n_p('  LIBS      += $(LDDEPS)%s', make.list(cc.getlinkflags(cfg)))\nif cfg.kind == \"StaticLib\" then\nif cfg.platform:startswith(\"Universal\") then\n_p('  LINKCMD    = libtool -o $(TARGET)')\nelse\nif cc.llvm then\n_p('  LINKCMD    = $(AR) rcs $(TARGET)')\nelse\n_p('  LINKCMD    = $(AR) -rcs $(TARGET)')\nend\nend\nelse\nlocal tool = iif(cfg.language == \"C\", \"CC\", \"CXX\")\n_p('  LINKCMD    = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', tool)\nend\nend\nfunction cpp.pchco"
190   "nfig(cfg)\nif not cfg.pchheader or cfg.flags.NoPCH then\nreturn\nend\nlocal pch = cfg.pchheader\nfor _, incdir in ipairs(cfg.includedirs) do\nlocal abspath = path.getabsolute(path.join(cfg.project.location, incdir))\nlocal testname = path.join(abspath, pch)\nif os.isfile(testname) then\npch = path.getrelative(cfg.location, testname)\nbreak\nend\nend\n_p('  PCH        = %s', _MAKE.esc(pch))\n_p('  GCH        = $(OBJDIR)/$(notdir $(PCH)).gch')\nend\nfunction cpp.pchrules(prj)\n_p('ifneq (,$(PCH))')\n_p('$(GCH): $(PCH)')\n_p('\\t@echo $(notdir $<)')\nlocal cmd = iif(prj.language == \"C\", \"$(CC) -x c-header $(ALL_CFLAGS)\", \"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")\n_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"', cmd)\n_p('endif')\n_p('')\nend\nfunction cpp.fileRules(prj)\nfor _, file in ipairs(prj.files or {}) do\nif path.iscppfile(file) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n, _MAKE.esc(file)\n)\nif (path.isobjcfile(fi"
191   "le) and prj.msgcompile_objc) then\n_p('\\t@echo ' .. prj.msgcompile_objc)\nelseif prj.msgcompile then\n_p('\\t@echo ' .. prj.msgcompile)\nelse\n_p('\\t@echo $(notdir $<)')\nend\nif (path.isobjcfile(file)) then\n_p('\\t$(SILENT) $(CXX) $(ALL_OBJCFLAGS) $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.o=%%.d) -c \"$<\"')\nelse\ncpp.buildcommand(path.iscfile(file) and not prj.options.ForceCPP, \"o\")\nend\n_p('')\nelseif (path.getextension(file) == \".rc\") then\n_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))\nif prj.msgresource then\n_p('\\t@echo ' .. prj.msgresource)\nelse\n_p('\\t@echo $(notdir $<)')\nend\n_p('\\t$(SILENT) $(RESCOMP) $< -O coff -o \"$@\" $(ALL_RESFLAGS)')\n_p('')\nend\nend\nend\nfunction cpp.buildcommand(iscfile, objext)\nlocal flags = iif(iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)')\n_p('\\t$(SILENT) %s $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.%s=%%.d) -c \"$<\"', flags, objext)\nend\n",
182   "premake.make.cpp = { }\npremake.make.undefine = { }\nlocal cpp = premake.make.cpp\nlocal make = premake.make\nfunction premake.make_cpp(prj)\nlocal cc = premake.gettool(prj)\nlocal platforms = premake.filterplatforms(prj.solution, cc.platforms, \"Native\")\npremake.gmake_cpp_header(prj, cc, platforms)\nfor _, platform in ipairs(platforms) do\nfor cfg in premake.eachconfig(prj, platform) do\npremake.gmake_cpp_config(prj, cfg, cc)\nend\nend\nlocal objdirs = {}\nfor _, file in ipairs(prj.files) do\nif path.iscppfile(file) then\nobjdirs[_MAKE.esc(path.getdirectory(path.trimdots(file)))] = 1\nend\nend\n_p('OBJDIRS := \\\\')\n_p('\\t$(OBJDIR) \\\\')\nfor dir, _ in pairs(objdirs) do\n_p('\\t$(OBJDIR)/%s \\\\', dir)\nend\n_p('')\n_p('RESOURCES := \\\\')\nfor _, file in ipairs(prj.files) do\nif path.isresourcefile(file) then\n_p('\\t$(OBJDIR)/%s.res \\\\', _MAKE.esc(path.getbasename(file)))\nend\nend\n_p('')\n_p('.PHONY: clean prebuild prelink')\n_p('')\nif os.is(\"MacOSX\") and prj.kind == \"WindowedApp\" then\n_p('al"
183   "l: $(TARGETDIR) $(OBJDIRS) prebuild prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist')\nelse\n_p('all: $(TARGETDIR) $(OBJDIRS) prebuild prelink $(TARGET)')\nend\n_p('\\t@:')\n_p('')\nif (prj.kind == \"StaticLib\" and prj.options.ArchiveSplit) then\n_p('define max_args')\n_p('\\t$(eval _args:=)')\n_p('\\t$(foreach obj,$3,$(eval _args+=$(obj))$(if $(word $2,$(_args)),$1$(_args)$(EOL)$(eval _args:=)))')\n_p('\\t$(if $(_args),$1$(_args))')\n_p('endef')\n_p('')\n_p('define EOL')\n_p('')\n_p('')\n_p('endef')\n_p('')\nend\n_p('$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(RESOURCES)')\nif prj.kind == \"StaticLib\" then\nif prj.msgarchiving then\n_p('\\t@echo ' .. prj.msgarchiving)\nelse\n_p('\\t@echo Archiving %s', prj.name)\nend\nif (not prj.archivesplit_size) then \nprj.archivesplit_size=200\nend\nif (not prj.options.ArchiveSplit) then\n_p('\\t$(SILENT) $(LINKCMD) $(OBJECTS)')\nelse\n_p('\\t@$(call max_args,$(LINKCMD),'.. prj.archivesplit_size ..',$(OBJECTS))')\nend\nelse\nif prj.msglinking the"
184   "n\n_p('\\t@echo ' .. prj.msglinking)\nelse\n_p('\\t@echo Linking %s', prj.name)\nend\n_p('\\t$(SILENT) $(LINKCMD)')\nend\n_p('\\t$(POSTBUILDCMDS)')\n_p('')\n_p('$(TARGETDIR):')\npremake.make_mkdirrule(\"$(TARGETDIR)\")\n_p('$(OBJDIRS):')\nif (not prj.solution.messageskip) or (not table.contains(prj.solution.messageskip, \"SkipCreatingMessage\")) then\n_p('\\t@echo Creating $(OBJDIR)')\nend\n_p('\\t-$(call MKDIR,$(OBJDIR))')\nfor dir, _ in pairs(objdirs) do\n_p('\\t-$(call MKDIR,$(OBJDIR)/%s)', dir)\nend\n_p('')\nif os.is(\"MacOSX\") and prj.kind == \"WindowedApp\" then\n_p('$(dir $(TARGETDIR))PkgInfo:')\n_p('$(dir $(TARGETDIR))Info.plist:')\n_p('')\nend\n_p('clean:')\nif (not prj.solution.messageskip) or (not table.contains(prj.solution.messageskip, \"SkipCleaningMessage\")) then\n_p('\\t@echo Cleaning %s', prj.name)\nend\n_p('ifeq (posix,$(SHELLTYPE))')\n_p('\\t$(SILENT) rm -f  $(TARGET)')\n_p('\\t$(SILENT) rm -rf $(OBJDIR)')\n_p('else')\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(TARGET)) del $(subst /,"
185   "\\\\\\\\,$(TARGET))')\n_p('\\t$(SILENT) if exist $(subst /,\\\\\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\\\\\,$(OBJDIR))')\n_p('endif')\n_p('')\n_p('prebuild:')\n_p('\\t$(PREBUILDCMDS)')\n_p('')\n_p('prelink:')\n_p('\\t$(PRELINKCMDS)')\n_p('')\ncpp.pchrules(prj)\ncpp.fileRules(prj)\n_p('-include $(OBJECTS:%%.o=%%.d)')\n_p('ifneq (,$(PCH))')\n_p('  -include $(OBJDIR)/$(notdir $(PCH)).d')\n_p('endif')\nend\nfunction premake.gmake_cpp_header(prj, cc, platforms)\n_p('# %s project makefile autogenerated by GENie', premake.action.current().shortname)\n_p('ifndef config')\n_p('  config=%s', _MAKE.esc(premake.getconfigname(prj.solution.configurations[1], platforms[1], true)))\n_p('endif')\n_p('')\nfor _, variable in ipairs(premake.make.undefine) do\n_p('override undefine '.. variable)\nend\n_p('')\n_p('ifndef verbose')\n_p('  SILENT = @')\n_p('endif')\n_p('')\n_p('SHELLTYPE := msdos')\n_p('ifeq (,$(ComSpec)$(COMSPEC))')\n_p('  SHELLTYPE := posix')\n_p('endif')\n_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')\n_p('  SHEL"
186   "LTYPE := posix')\n_p('endif')\n_p('')\n_p('ifeq (posix,$(SHELLTYPE))')\n_p('  MKDIR = $(SILENT) mkdir -p \"$(1)\"')\n_p('  COPY  = $(SILENT) cp -fR \"$(1)\" \"$(2)\"')\n_p('else')\n_p('  MKDIR = $(SILENT) mkdir \"$(subst /,\\\\\\\\,$(1))\" 2> nul || exit 0')\n_p('  COPY  = $(SILENT) copy /Y \"$(subst /,\\\\\\\\,$(1))\" \"$(subst /,\\\\\\\\,$(2))\"')\n_p('endif')\n_p('')\n_p('CC  = %s', cc.cc)\n_p('CXX = %s', cc.cxx)\n_p('AR  = %s', cc.ar)\n_p('')\n_p('ifndef RESCOMP')\n_p('  ifdef WINDRES')\n_p('    RESCOMP = $(WINDRES)')\n_p('  else')\n_p('    RESCOMP = windres')\n_p('  endif')\n_p('endif')\n_p('')\nend\nfunction premake.gmake_cpp_config(prj, cfg, cc)\n_p('ifeq ($(config),%s)', _MAKE.esc(cfg.shortname))\ncpp.platformtools(cfg, cc)\n_p('  OBJDIR     = %s', _MAKE.esc(cfg.objectsdir))\n_p('  TARGETDIR  = %s', _MAKE.esc(cfg.buildtarget.directory))\n_p('  TARGET     = $(TARGETDIR)/%s', _MAKE.esc(cfg.buildtarget.name))\n_p('  DEFINES   +=%s', make.list(cc.getdefines(cfg.defines)))\n_p('  INCLUDES  +=%s', make.list("
187   "cc.getincludedirs(cfg.includedirs)))\ncpp.pchconfig(cfg)\ncpp.flags(cfg, cc)\ncpp.linker(cfg, cc)\n_p('  OBJECTS := \\\\')\nfor _, file in ipairs(prj.files) do\nif path.iscppfile(file) then\nlocal excluded = false\nfor _, exclude in ipairs(cfg.excludes) do\nexcluded = (exclude == file)\nif (excluded) then break end\nend\nif excluded == false then\n_p('\\t$(OBJDIR)/%s.o \\\\'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n)\nend\nend\nend\n_p('')\n_p('  define PREBUILDCMDS')\nif #cfg.prebuildcommands > 0 then\n_p('\\t@echo Running pre-build commands')\n_p('\\t%s', table.implode(cfg.prebuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define PRELINKCMDS')\nif #cfg.prelinkcommands > 0 then\n_p('\\t@echo Running pre-link commands')\n_p('\\t%s', table.implode(cfg.prelinkcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define POSTBUILDCMDS')\nif #cfg.postbuildcommands > 0 then\n_p('\\t@echo Running post-build commands')\n_p('\\t%s', table.implode(cfg.postbuildcommands, \"\", \"\", "
188   "\"\\n\\t\"))\nend\n_p('  endef')\nmake.settings(cfg, cc)\n_p('endif')\n_p('')\nend\nfunction cpp.platformtools(cfg, cc)\nlocal platform = cc.platforms[cfg.platform]\nif platform.cc then\n_p('  CC         = %s', platform.cc)\nend\nif platform.cxx then\n_p('  CXX        = %s', platform.cxx)\nend\nif platform.ar then\n_p('  AR         = %s', platform.ar)\nend\nend\nfunction cpp.flags(cfg, cc)\nif cfg.pchheader and not cfg.flags.NoPCH then\n_p('  FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p('  FORCE_INCLUDE += -include %s'\n,premake.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p('  ALL_CPPFLAGS  += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))\n_p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions, cfg.b"
189   "uildoptions_cpp)))\n_p('  ALL_OBJCFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_objc)))\n_p('  ALL_RESFLAGS  += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n        make.list(table.join(cc.getdefines(cfg.resdefines),\n                                cc.getincludedirs(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(cfg, cc)\n_p('  ALL_LDFLAGS   += $(LDFLAGS)%s', make.list(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions)))\n_p('  LDDEPS    +=%s', make.list(_MAKE.esc(premake.getlinks(cfg, \"siblings\", \"fullpath\"))))\n_p('  LIBS      += $(LDDEPS)%s', make.list(cc.getlinkflags(cfg)))\nif cfg.kind == \"StaticLib\" then\nif cfg.platform:startswith(\"Universal\") then\n_p('  LINKCMD    = libtool -o $(TARGET)')\nelse\nif cc.llvm then\n_p('  LINKCMD    = $(AR) rcs $(TARGET)')\nelse\n_p('  LINKCMD    = $(AR) -rcs $(TARGET)')\nend\nend\nelse\nlocal tool = iif(cfg.language == \"C\", \"CC\", \"CXX"
190   "\")\n_p('  LINKCMD    = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', tool)\nend\nend\nfunction cpp.pchconfig(cfg)\nif not cfg.pchheader or cfg.flags.NoPCH then\nreturn\nend\nlocal pch = cfg.pchheader\nfor _, incdir in ipairs(cfg.includedirs) do\nlocal abspath = path.getabsolute(path.join(cfg.project.location, incdir))\nlocal testname = path.join(abspath, pch)\nif os.isfile(testname) then\npch = path.getrelative(cfg.location, testname)\nbreak\nend\nend\n_p('  PCH        = %s', _MAKE.esc(pch))\n_p('  GCH        = $(OBJDIR)/$(notdir $(PCH)).gch')\nend\nfunction cpp.pchrules(prj)\n_p('ifneq (,$(PCH))')\n_p('$(GCH): $(PCH)')\n_p('\\t@echo $(notdir $<)')\nlocal cmd = iif(prj.language == \"C\", \"$(CC) -x c-header $(ALL_CFLAGS)\", \"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")\n_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"', cmd)\n_p('endif')\n_p('')\nend\nfunction cpp.fileRules(prj)\nfor _, file in ipairs(prj.files or {}) do\nif path.iscppf"
191   "ile(file) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n, _MAKE.esc(file)\n)\nif (path.isobjcfile(file) and prj.msgcompile_objc) then\n_p('\\t@echo ' .. prj.msgcompile_objc)\nelseif prj.msgcompile then\n_p('\\t@echo ' .. prj.msgcompile)\nelse\n_p('\\t@echo $(notdir $<)')\nend\nif (path.isobjcfile(file)) then\n_p('\\t$(SILENT) $(CXX) $(ALL_OBJCFLAGS) $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.o=%%.d) -c \"$<\"')\nelse\ncpp.buildcommand(path.iscfile(file) and not prj.options.ForceCPP, \"o\")\nend\n_p('')\nelseif (path.getextension(file) == \".rc\") then\n_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))\nif prj.msgresource then\n_p('\\t@echo ' .. prj.msgresource)\nelse\n_p('\\t@echo $(notdir $<)')\nend\n_p('\\t$(SILENT) $(RESCOMP) $< -O coff -o \"$@\" $(ALL_RESFLAGS)')\n_p('')\nend\nend\nend\nfunction cpp.buildcommand(iscfile, objext)\nlocal flags = iif(iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)')\n_p('\\t$(SILENT) %s $(FORCE_INCLUDE) -o \"$"
192   "@\" -MF $(@:%%.%s=%%.d) -c \"$<\"', flags, objext)\nend\n",
192193
193194   /* actions/make/make_csharp.lua */
194195   "local function getresourcefilename(cfg, fname)\nif path.getextension(fname) == \".resx\" then\n    local name = cfg.buildtarget.basename .. \".\"\n    local dir = path.getdirectory(fname)\n    if dir ~= \".\" then \nname = name .. path.translate(dir, \".\") .. \".\"\nend\nreturn \"$(OBJDIR)/\" .. _MAKE.esc(name .. path.getbasename(fname)) .. \".resources\"\nelse\nreturn fname\nend\nend\nfunction premake.make_csharp(prj)\nlocal csc = premake.dotnet\nlocal cfglibs = { }\nlocal cfgpairs = { }\nlocal anycfg\nfor cfg in premake.eachconfig(prj) do\nanycfg = cfg\ncfglibs[cfg] = premake.getlinks(cfg, \"siblings\", \"fullpath\")\ncfgpairs[cfg] = { }\nfor _, fname in ipairs(cfglibs[cfg]) do\nif path.getdirectory(fname) ~= cfg.buildtarget.directory then\ncfgpairs[cfg][\"$(TARGETDIR)/\" .. _MAKE.esc(path.getname(fname))] = _MAKE.esc(fname)\nend\nend\nend\nlocal sources = {}\nlocal embedded = { }\nlocal copypairs = { }\nfor fcfg in premake.project.eachfile(prj) do\nlocal action = csc.getbuildaction(fcfg)\nif action == \"Co"
trunk/3rdparty/mongoose/docs/API.md
r244869r244870
183183is used, no calls to `mg_send*` or `mg_printf*` functions must be made, and
184184event handler must return `MG_MORE`.
185185
186    int mg_websocket_write(struct mg_connection* conn, int opcode,
187                           const char *data, size_t data_len);
186    size_t mg_websocket_write(struct mg_connection* conn, int opcode,
187                              const char *data, size_t data_len);
188    size_t mg_websocket_printf(struct mg_connection* conn, int opcode,
189                               const char *fmt, ...);
188190
189Similar to `mg_write()`, but wraps the data into a websocket frame with a
190given websocket `opcode`.
191191
192Similar to `mg_write()` and `mg_printf()`, but wraps the data into a
193websocket frame with a given websocket `opcode`.
194
192195    const char *mg_get_header(const struct mg_connection *, const char *name);
193196
194197Get the value of particular HTTP header. This is a helper function.
trunk/3rdparty/mongoose/examples/multi_threaded_server/Makefile
r244869r244870
22# All rights reserved
33
44PROG = multi_threaded_server
5CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
5CFLAGS = -W -Wall -I../.. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS $(CFLAGS_EXTRA)
66SOURCES = $(PROG).c ../../mongoose.c
77
88$(PROG): $(SOURCES)
trunk/3rdparty/mongoose/examples/proxy_server/Makefile
r244869r244870
33
44PROG = proxy_server
55FLAGS = -I../..  -DNS_ENABLE_SSL
6CFLAGS = -W -Wall -g -O0 -pthread  -lssl $(FLAGS) $(CFLAGS_EXTRA)
6CFLAGS = -W -Wall -g -O0 -pthread  -lssl -DMONGOOSE_ENABLE_THREADS $(FLAGS) $(CFLAGS_EXTRA)
77SOURCES = $(PROG).c ../../mongoose.c
88
99unix: $(SOURCES)
trunk/3rdparty/mongoose/examples/web_server/Makefile
r244869r244870
22# All rights reserved
33
44PROG = web_server
5CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
5CFLAGS = -W -Wall -I../.. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS $(CFLAGS_EXTRA)
66SOURCES = $(PROG).c ../../mongoose.c
7OPENSSL_FLAGS = -DNS_ENABLE_SSL -lssl
78
9# PolarSSL paths and flags
10POLARSSL_PATH = /usr/local
11POLARSSLCOMPAT_PATH = ./../../../polar
12SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
13INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
14LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
15CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR) -DNS_ENABLE_SSL
16#
17
818$(PROG): $(SOURCES)
919   $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
1020
21openssl:
22   $(CC) -o $(PROG) $(SOURCES) $(CFLAGS) $(OPENSSL_FLAGS)
23
24polarssl:
25   $(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
26   
1127clean:
1228   rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
trunk/3rdparty/mongoose/examples/web_server/certs/cert.pem
r0r244870
1-----BEGIN CERTIFICATE-----
2MIIC+zCCAeOgAwIBAgIJAPhB8jbL+G82MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
3BAMMCTEyNy4wLjAuMTAeFw0xNTAzMDYxMjQzMzNaFw0yNTAzMDMxMjQzMzNaMBQx
4EjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
5ggEBALi3b3daMgzUEROKob1Caf68i+//cTRkPdBJv2cOBak21CdQzY0Nvx73GLzf
65TKB347BCHNbYRKGJXDbYdmFp20/WeBHkY7RS3Ad2Q5lzyx66u9PxNx7hJIiqBgF
758VU+E3o/I+o8QNIoOT+wtCiq3Nwkp+zGBJmS32rzMEV9bcKxSzMrkfRhF+XAREd
8DwM9vfPg6WRb/b+vv06uvVwcw390RprLautGfBdaRddVYkIAKJGRRTqZAvTRFW1J
9FcIVOxlN+iA7qP7xjr3tUP78qMmlu0MXsHrUR2cgfveZK2sdUW5G804yHsU5sC8l
10FbtLKMEOyLsk2bEIScOXgum7g2sCAwEAAaNQME4wHQYDVR0OBBYEFHtLzUqAsXkH
11Il8S5sMhJuVhRJLdMB8GA1UdIwQYMBaAFHtLzUqAsXkHIl8S5sMhJuVhRJLdMAwG
12A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEzHc0AOr+qs0OFvWMfcSMi7
13O/aYlLS6f7Sos+lli69+61EcmCTJVarVeAVUsAoqmzBKDbeOpAK1hGX6/GGcXjR2
14BmuU0hUKyX9l1lwdMKU45BayH/riElwnvAyj2GxKoPpdIjlHns4SAITOCUx9NfpM
15agd7kjolton0ZQ5DI/2a43PkqHv1lY4Dp60wJlxit9U68bsGOycCJ/BsAyrPROb2
16D1MkpMBIdfHc8uxRywM3/l9buFX8yrrMUGOYKgfjDwdzbj0iwIixoGpHL7IfeBtu
17dvGO/g2rEhbtAP+xIgOR3GvzqjZh30er3no7zjDMn65tTME18Aq3tBQY7vPDKms=
18-----END CERTIFICATE-----
19-----BEGIN PRIVATE KEY-----
20MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4t293WjIM1BET
21iqG9Qmn+vIvv/3E0ZD3QSb9nDgWpNtQnUM2NDb8e9xi83+Uygd+OwQhzW2EShiVw
2222HZhadtP1ngR5GO0UtwHdkOZc8seurvT8Tce4SSIqgYBefFVPhN6PyPqPEDSKDk
23/sLQoqtzcJKfsxgSZkt9q8zBFfW3CsUszK5H0YRflwERHQ8DPb3z4OlkW/2/r79O
24rr1cHMN/dEaay2rrRnwXWkXXVWJCACiRkUU6mQL00RVtSRXCFTsZTfogO6j+8Y69
257VD+/KjJpbtDF7B61EdnIH73mStrHVFuRvNOMh7FObAvJRW7SyjBDsi7JNmxCEnD
26l4Lpu4NrAgMBAAECggEAaFuqbAHXOQwuwZ2XFzgIblTTsrncmT7w9VZU/sIbTKif
27X771AnX7vmDX5w2PjeN2DE7emV3NEAwd5w7qz1wFZWFfQ6jrgYaZWjRixxGZ5IVl
28aeLlU7OtCGrwEPJ1KTWCO3IgDoHh+Hr1+6o7Imhk+QlmrTcfqHWGvO9s9MGVWt2S
29RLAnSTFiOe5brdJnmlqq1sKZmnLmpydBaPUOYpZGAgRasrjdMZB+lZOazd1x23/5
30GAcm0rDREMnO9b2Jt+TNEZHT6d5KpVoExztZEZj8QCLXoic/SpFIqHGtpNlQXa+d
31BVqgQbIYjO8ldldxZ8YIyJDVF+9e/uBBwu6jBIIsEQKBgQDspEHCyyuh4LG+7BbZ
32eXlsfCxPTM6K9w31ZwHAwRtAuGqrOrE+pFJG9CEsFZbAI1aOGmZZdjexuSMcOlXl
33TIVJTQHoFtoGEsanYEXO4O1t02Ab/DCYSpXusXUraRBRPpsTC77Sh5mxLUNd23d9
34NhnDBuwChAmC+IYexjkXeqPYFwKBgQDH08PEd+2PVo4MD8UVKUlEcgoyCr6ESiyp
35HfYyhhfd5x3DbZLoKCkunDfBs/hakQk8DA2nn4tl4ZjfmzXmX0EBx+E5YTdYshW7
36ZcjN5x64B5PEOAR/NZA6agNlp3XGXXXgX+gnN6pgE49eVU22nZ4G+QBKD6NcCviB
37LBPUxMbvzQKBgHgZYRqonGtaqzsXfP1AjmSFnMNeWtDiU95BOf2Gw/sT3WcrsXr2
38UJ+cFR3XkxvOk4YpVdp/igKT0ILqBGAMdvTdtWMB/gLpEpMt5B/7veRoS7XIRy1z
39ZSawP6QZfWOOX4vKAT29/j2SmEcRNFKC245EfBFGy8EBuqfxuFX3MyJfAoGBAJ0y
40tjsErVmpma1baosvI3g4zlR3p1CimWehLmCopHXorr1iocMIdP0535L+ZU258y3N
41vaA0HpFTW9PsYgaMwLMJ7uAY3lVkIzx84e849i2HqHMgLkl0dbW+WFXL2xblxylv
42yU2wuNNED/EB4lTawcpycAvTKYvrBXt4lVE4S9exAoGAGl6vZV3zyw4jpIw4uDfk
43LTPYUrghFDDGKExyeOnC/W9pqR2veqzfBz02C3jqwhewoqgAcnNc2sg0rJmM+6Oz
44Z2mmGZTHO9xR++7+W7e8AkQBbS6TB8a+7yNcM4USLP+b9sX5N+8gFhFs9tG7j/no
45G44qLsJ/yve7/QsOA37uEMs=
46-----END PRIVATE KEY-----
trunk/3rdparty/mongoose/examples/web_server/web_server.c
r244869r244870
7171static char s_config_file[PATH_MAX];  // Set by process_command_line_arguments
7272static struct mg_server *server;    // Set by start_mongoose()
7373static const char *s_default_document_root = ".";
74#ifndef NS_ENABLE_SSL
7475static const char *s_default_listening_port = "8080";
76#else
77static const char *s_default_listening_port = "ssl://8443:certs/cert.pem";
78#endif
79
7580static char **s_argv = { NULL };
7681
7782static void set_options(char *argv[]);
trunk/3rdparty/mongoose/examples/websocket_ssl_proxy/Makefile
r244869r244870
22# All rights reserved
33
44PROG = ws_ssl
5CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 $(CFLAGS_EXTRA)
5CFLAGS = -W -Wall -I../.. -I. -pthread -g -O0 -DMONGOOSE_ENABLE_THREADS -DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY $(CFLAGS_EXTRA)
6LDFLAGS = -lssl
67SOURCES = ws_ssl.c ../../mongoose.c ssl_wrapper.c
78
9# PolarSSL paths and flags
10POLARSSL_PATH = /usr/local
11POLARSSLCOMPAT_PATH = ./../../../polar
12SOURCES_POLAR = $(SOURCES) $(POLARSSLCOMPAT_PATH)/polarssl_compat.c
13INCDIR_POLAR = -I$(POLARSSLCOMPAT_PATH) -I$(POLARSSL_PATH)/include
14LDFLAGS_POLAR = -L$(POLARSSL_PATH)/lib -lmbedtls
15CFLAGS_POLAR = $(CFLAGS) $(INCDIR_POLAR)
16#
17
818all: $(PROG)
919
1020$(PROG): $(SOURCES)
11   $(CC) -o $(PROG) $(SOURCES) \
12      -DNS_ENABLE_SSL -DSSL_WRAPPER_USE_AS_LIBRARY -lssl $(CFLAGS)
21   $(CC) -o $(PROG) $(SOURCES) $(LDFLAGS) $(CFLAGS)
1322
23polarssl: $(SOURCES_POLAR)
24   $(CC) -o $(PROG) $(SOURCES_POLAR) $(LDFLAGS_POLAR) $(CFLAGS_POLAR)
25
1426clean:
1527   rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
trunk/3rdparty/mongoose/mongoose.c
r244869r244870
14861486};
14871487
14881488#define MG_HEADERS_SENT NSF_USER_1
1489#define MG_LONG_RUNNING NSF_USER_2
1489#define MG_USING_CHUNKED_API NSF_USER_2
14901490#define MG_CGI_CONN NSF_USER_3
14911491#define MG_PROXY_CONN NSF_USER_4
14921492#define MG_PROXY_DONT_PARSE NSF_USER_5
r244869r244870
27162716}
27172717
27182718void mg_send_status(struct mg_connection *c, int status) {
2719  struct connection *conn = MG_CONN_2_CONN(c);
27192720  if (c->status_code == 0) {
27202721    c->status_code = status;
27212722    mg_printf(c, "HTTP/1.1 %d %s\r\n", status, status_code_to_str(status));
27222723  }
2724  conn->ns_conn->flags |= MG_USING_CHUNKED_API;
27232725}
27242726
27252727void mg_send_header(struct mg_connection *c, const char *name, const char *v) {
2728  struct connection *conn = MG_CONN_2_CONN(c);
27262729  if (c->status_code == 0) {
27272730    c->status_code = 200;
27282731    mg_printf(c, "HTTP/1.1 %d %s\r\n", 200, status_code_to_str(200));
27292732  }
27302733  mg_printf(c, "%s: %s\r\n", name, v);
2734  conn->ns_conn->flags |= MG_USING_CHUNKED_API;
27312735}
27322736
27332737static void terminate_headers(struct mg_connection *c) {
r244869r244870
31093113  int result;
31103114  conn->mg_conn.content = conn->ns_conn->recv_iobuf.buf;
31113115  if ((result = call_user(conn, MG_REQUEST)) == MG_TRUE) {
3112    if (conn->ns_conn->flags & MG_HEADERS_SENT) {
3116    if (conn->ns_conn->flags & MG_USING_CHUNKED_API) {
3117      terminate_headers(&conn->mg_conn);
31133118      write_terminating_chunk(conn);
31143119    }
31153120    close_local_endpoint(conn);
r244869r244870
48754880  conn->cl = conn->num_bytes_recv = conn->request_len = 0;
48764881  conn->ns_conn->flags &= ~(NSF_FINISHED_SENDING_DATA |
48774882                            NSF_BUFFER_BUT_DONT_SEND | NSF_CLOSE_IMMEDIATELY |
4878                            MG_HEADERS_SENT | MG_LONG_RUNNING);
4883                            MG_HEADERS_SENT | MG_USING_CHUNKED_API);
48794884
48804885  // Do not memset() the whole structure, as some of the fields
48814886  // (IP addresses & ports, server_param) must survive. Nullify the rest.


Previous 199869 Revisions Next


© 1997-2024 The MAME Team