@ -13,11 +13,12 @@ Index of this file:
// Forward declarations and basic types
// ImGui API (Dear ImGui end-user API)
// Flags & Enumerations
// ImVector
// ImGuiStyle
// ImGuiIO
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
// Obsolete functions
// Helpers (Im Vector, Im GuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// Helpers (Im GuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData)
// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFont)
@ -1148,6 +1149,77 @@ enum ImGuiCond_
# endif
} ;
//-----------------------------------------------------------------------------
// Helper: ImVector<>
// Lightweight std::vector<>-like class to avoid dragging dependencies (also: some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
// You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our data structures are relying on it.
// Important: our implementation does NOT call C++ constructors/destructors, we treat everything as raw data! This is intentional but be extra mindful of that,
// do NOT use this class as a std::vector replacement in your own code!
//-----------------------------------------------------------------------------
template < typename T >
class ImVector
{
public :
int Size ;
int Capacity ;
T * Data ;
typedef T value_type ;
typedef value_type * iterator ;
typedef const value_type * const_iterator ;
inline ImVector ( ) { Size = Capacity = 0 ; Data = NULL ; }
inline ~ ImVector ( ) { if ( Data ) ImGui : : MemFree ( Data ) ; }
inline ImVector ( const ImVector < T > & src ) { Size = Capacity = 0 ; Data = NULL ; operator = ( src ) ; }
inline ImVector < T > & operator = ( const ImVector < T > & src ) { clear ( ) ; resize ( src . Size ) ; memcpy ( Data , src . Data , ( size_t ) Size * sizeof ( value_type ) ) ; return * this ; }
inline bool empty ( ) const { return Size = = 0 ; }
inline int size ( ) const { return Size ; }
inline int capacity ( ) const { return Capacity ; }
inline value_type & operator [ ] ( int i ) { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline const value_type & operator [ ] ( int i ) const { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline void clear ( ) { if ( Data ) { Size = Capacity = 0 ; ImGui : : MemFree ( Data ) ; Data = NULL ; } }
inline iterator begin ( ) { return Data ; }
inline const_iterator begin ( ) const { return Data ; }
inline iterator end ( ) { return Data + Size ; }
inline const_iterator end ( ) const { return Data + Size ; }
inline value_type & front ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline const value_type & front ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline value_type & back ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline const value_type & back ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline void swap ( ImVector < value_type > & rhs ) { int rhs_size = rhs . Size ; rhs . Size = Size ; Size = rhs_size ; int rhs_cap = rhs . Capacity ; rhs . Capacity = Capacity ; Capacity = rhs_cap ; value_type * rhs_data = rhs . Data ; rhs . Data = Data ; Data = rhs_data ; }
inline int _grow_capacity ( int sz ) const { int new_capacity = Capacity ? ( Capacity + Capacity / 2 ) : 8 ; return new_capacity > sz ? new_capacity : sz ; }
inline void resize ( int new_size ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; Size = new_size ; }
inline void resize ( int new_size , const value_type & v ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; if ( new_size > Size ) for ( int n = Size ; n < new_size ; n + + ) memcpy ( & Data [ n ] , & v , sizeof ( v ) ) ; Size = new_size ; }
inline void reserve ( int new_capacity )
{
if ( new_capacity < = Capacity )
return ;
value_type * new_data = ( value_type * ) ImGui : : MemAlloc ( ( size_t ) new_capacity * sizeof ( value_type ) ) ;
if ( Data )
{
memcpy ( new_data , Data , ( size_t ) Size * sizeof ( value_type ) ) ;
ImGui : : MemFree ( Data ) ;
}
Data = new_data ;
Capacity = new_capacity ;
}
// NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden.
inline void push_back ( const value_type & v ) { if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; memcpy ( & Data [ Size ] , & v , sizeof ( v ) ) ; Size + + ; }
inline void pop_back ( ) { IM_ASSERT ( Size > 0 ) ; Size - - ; }
inline void push_front ( const value_type & v ) { if ( Size = = 0 ) push_back ( v ) ; else insert ( Data , v ) ; }
inline iterator erase ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + 1 , ( ( size_t ) Size - ( size_t ) off - 1 ) * sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator erase ( const_iterator it , const_iterator it_last ) { IM_ASSERT ( it > = Data & & it < Data + Size & & it_last > it & & it_last < = Data + Size ) ; const ptrdiff_t count = it_last - it ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + count , ( ( size_t ) Size - ( size_t ) off - count ) * sizeof ( value_type ) ) ; Size - = ( int ) count ; return Data + off ; }
inline iterator erase_unsorted ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; if ( it < Data + Size - 1 ) memcpy ( Data + off , Data + Size - 1 , sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator insert ( const_iterator it , const value_type & v ) { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; if ( off < ( int ) Size ) memmove ( Data + off + 1 , Data + off , ( ( size_t ) Size - ( size_t ) off ) * sizeof ( value_type ) ) ; memcpy ( & Data [ off ] , & v , sizeof ( v ) ) ; Size + + ; return Data + off ; }
inline bool contains ( const value_type & v ) const { const T * data = Data ; const T * data_end = Data + Size ; while ( data < data_end ) if ( * data + + = = v ) return true ; return false ; }
inline int index_from_pointer ( const_iterator it ) const { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; return ( int ) off ; }
} ;
//-----------------------------------------------------------------------------
// ImGuiStyle
// You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame().
@ -1447,71 +1519,6 @@ typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
// Helpers
//-----------------------------------------------------------------------------
// Helper: Lightweight 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).
// *Important* Our implementation does NOT call C++ constructors/destructors. This is intentional, we do not require it but you have to be mindful of that. Do _not_ use this class as a std::vector replacement in your code!
template < typename T >
class ImVector
{
public :
int Size ;
int Capacity ;
T * Data ;
typedef T value_type ;
typedef value_type * iterator ;
typedef const value_type * const_iterator ;
inline ImVector ( ) { Size = Capacity = 0 ; Data = NULL ; }
inline ~ ImVector ( ) { if ( Data ) ImGui : : MemFree ( Data ) ; }
inline ImVector ( const ImVector < T > & src ) { Size = Capacity = 0 ; Data = NULL ; operator = ( src ) ; }
inline ImVector < T > & operator = ( const ImVector < T > & src ) { clear ( ) ; resize ( src . Size ) ; memcpy ( Data , src . Data , ( size_t ) Size * sizeof ( value_type ) ) ; return * this ; }
inline bool empty ( ) const { return Size = = 0 ; }
inline int size ( ) const { return Size ; }
inline int capacity ( ) const { return Capacity ; }
inline value_type & operator [ ] ( int i ) { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline const value_type & operator [ ] ( int i ) const { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline void clear ( ) { if ( Data ) { Size = Capacity = 0 ; ImGui : : MemFree ( Data ) ; Data = NULL ; } }
inline iterator begin ( ) { return Data ; }
inline const_iterator begin ( ) const { return Data ; }
inline iterator end ( ) { return Data + Size ; }
inline const_iterator end ( ) const { return Data + Size ; }
inline value_type & front ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline const value_type & front ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline value_type & back ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline const value_type & back ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline void swap ( ImVector < value_type > & rhs ) { int rhs_size = rhs . Size ; rhs . Size = Size ; Size = rhs_size ; int rhs_cap = rhs . Capacity ; rhs . Capacity = Capacity ; Capacity = rhs_cap ; value_type * rhs_data = rhs . Data ; rhs . Data = Data ; Data = rhs_data ; }
inline int _grow_capacity ( int sz ) const { int new_capacity = Capacity ? ( Capacity + Capacity / 2 ) : 8 ; return new_capacity > sz ? new_capacity : sz ; }
inline void resize ( int new_size ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; Size = new_size ; }
inline void resize ( int new_size , const value_type & v ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; if ( new_size > Size ) for ( int n = Size ; n < new_size ; n + + ) memcpy ( & Data [ n ] , & v , sizeof ( v ) ) ; Size = new_size ; }
inline void reserve ( int new_capacity )
{
if ( new_capacity < = Capacity )
return ;
value_type * new_data = ( value_type * ) ImGui : : MemAlloc ( ( size_t ) new_capacity * sizeof ( value_type ) ) ;
if ( Data )
{
memcpy ( new_data , Data , ( size_t ) Size * sizeof ( value_type ) ) ;
ImGui : : MemFree ( Data ) ;
}
Data = new_data ;
Capacity = new_capacity ;
}
// NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden.
inline void push_back ( const value_type & v ) { if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; memcpy ( & Data [ Size ] , & v , sizeof ( v ) ) ; Size + + ; }
inline void pop_back ( ) { IM_ASSERT ( Size > 0 ) ; Size - - ; }
inline void push_front ( const value_type & v ) { if ( Size = = 0 ) push_back ( v ) ; else insert ( Data , v ) ; }
inline iterator erase ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + 1 , ( ( size_t ) Size - ( size_t ) off - 1 ) * sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator erase ( const_iterator it , const_iterator it_last ) { IM_ASSERT ( it > = Data & & it < Data + Size & & it_last > it & & it_last < = Data + Size ) ; const ptrdiff_t count = it_last - it ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + count , ( ( size_t ) Size - ( size_t ) off - count ) * sizeof ( value_type ) ) ; Size - = ( int ) count ; return Data + off ; }
inline iterator erase_unsorted ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; if ( it < Data + Size - 1 ) memcpy ( Data + off , Data + Size - 1 , sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator insert ( const_iterator it , const value_type & v ) { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; if ( off < ( int ) Size ) memmove ( Data + off + 1 , Data + off , ( ( size_t ) Size - ( size_t ) off ) * sizeof ( value_type ) ) ; memcpy ( & Data [ off ] , & v , sizeof ( v ) ) ; Size + + ; return Data + off ; }
inline bool contains ( const value_type & v ) const { const T * data = Data ; const T * data_end = Data + Size ; while ( data < data_end ) if ( * data + + = = v ) return true ; return false ; }
inline int index_from_pointer ( const_iterator it ) const { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; return ( int ) off ; }
} ;
// Helper: IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE() macros to call MemAlloc + Placement New, Placement Delete + MemFree
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.