mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Drag and drop API experiment
This commit is contained in:
		
							
								
								
									
										170
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -2231,6 +2231,15 @@ void ImGui::NewFrame() | |||||||
|     if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) |     if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) | ||||||
|         g.ScalarAsInputTextId = 0; |         g.ScalarAsInputTextId = 0; | ||||||
|  |  | ||||||
|  |     // Elapse drag & drop payload | ||||||
|  |     if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) | ||||||
|  |     { | ||||||
|  |         g.DragDropActive = false; | ||||||
|  |         g.DragDropPayload.Clear(); | ||||||
|  |         g.DragDropPayloadBufHeap.clear(); | ||||||
|  |         memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Update keyboard input state |     // Update keyboard input state | ||||||
|     memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); |     memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); | ||||||
|     for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) |     for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) | ||||||
| @@ -5868,6 +5877,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool | |||||||
|         { |         { | ||||||
|             if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) |             if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) | ||||||
|                 if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay))  // Repeat mode trumps <on release> |                 if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay))  // Repeat mode trumps <on release> | ||||||
|  |                     if (!g.DragDropActive) | ||||||
|                         pressed = true; |                         pressed = true; | ||||||
|             ClearActiveID(); |             ClearActiveID(); | ||||||
|         } |         } | ||||||
| @@ -9426,7 +9436,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl | |||||||
|     else |     else | ||||||
|         window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border |         window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border | ||||||
|  |  | ||||||
|     if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) |     if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) | ||||||
|         ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); |         ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); | ||||||
|  |  | ||||||
|     return pressed; |     return pressed; | ||||||
| @@ -10584,6 +10594,164 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //----------------------------------------------------------------------------- | ||||||
|  | // DRAG AND DROP | ||||||
|  | //----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | // Call when current ID is active.  | ||||||
|  | // When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() | ||||||
|  | bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     ImGuiWindow* window = g.CurrentWindow; | ||||||
|  |     if (g.IO.MouseDown[mouse_button] == false) | ||||||
|  |         return false; | ||||||
|  |     if (g.ActiveId != window->DC.LastItemId) | ||||||
|  |         return false; | ||||||
|  |  | ||||||
|  |     if (IsMouseDragging(mouse_button)) | ||||||
|  |     { | ||||||
|  |         if (!g.DragDropActive) | ||||||
|  |         { | ||||||
|  |             ImGuiPayload& payload = g.DragDropPayload; | ||||||
|  |             payload.Clear(); | ||||||
|  |             payload.SourceId = g.ActiveId; | ||||||
|  |             payload.SourceParentId = window->IDStack.back(); | ||||||
|  |             g.DragDropActive = true; | ||||||
|  |             g.DragDropSourceFlags = flags; | ||||||
|  |             g.DragDropMouseButton = mouse_button; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!(flags & ImGuiDragDropFlags_SourceNoAutoTooltip)) | ||||||
|  |         { | ||||||
|  |             // FIXME-DRAG | ||||||
|  |             //SetNextWindowPos(g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding); | ||||||
|  |             //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This is better but e.g ColorButton with checkboard has issue with transparent colors :( | ||||||
|  |             SetNextWindowPos(g.IO.MousePos); | ||||||
|  |             PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); | ||||||
|  |             BeginTooltipEx(ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_ShowBorders); | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ImGui::EndDragDropSource() | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     IM_ASSERT(g.DragDropActive); | ||||||
|  |     IM_ASSERT(g.DragDropPayload.DataFrameCount != -1); // Forgot to call SetDragDropSourcePayload(), at least once on the first frame of a successful BeginDragDropSource() | ||||||
|  |  | ||||||
|  |     if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoAutoTooltip)) | ||||||
|  |     { | ||||||
|  |         EndTooltip(); | ||||||
|  |         PopStyleColor(); | ||||||
|  |         //PopStyleVar(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Use 'cond' to choose to submit paypload on drag start or every frame | ||||||
|  | bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond) | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     ImGuiPayload& payload = g.DragDropPayload; | ||||||
|  |     if (cond == 0) | ||||||
|  |         cond = ImGuiCond_Always; | ||||||
|  |  | ||||||
|  |     IM_ASSERT(type != NULL); | ||||||
|  |     IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType));       // Payload type can be at most 8 characters longs | ||||||
|  |     IM_ASSERT(data != NULL && data_size > 0); | ||||||
|  |     IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); | ||||||
|  |     IM_ASSERT(payload.SourceId != 0);                               // Not called between BeginDragDropSource() and EndDragDropSource() | ||||||
|  |  | ||||||
|  |     if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) | ||||||
|  |     { | ||||||
|  |         // Copy payload | ||||||
|  |         ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType)); | ||||||
|  |         g.DragDropPayloadBufHeap.resize(0); | ||||||
|  |         if (data_size > sizeof(g.DragDropPayloadBufLocal)) | ||||||
|  |         { | ||||||
|  |             // Store in heap | ||||||
|  |             g.DragDropPayloadBufHeap.resize((int)data_size); | ||||||
|  |             payload.Data = g.DragDropPayloadBufHeap.Data; | ||||||
|  |             memcpy((void*)payload.Data, data, data_size); | ||||||
|  |         } | ||||||
|  |         else if (data_size > 0) | ||||||
|  |         { | ||||||
|  |             // Store locally | ||||||
|  |             memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); | ||||||
|  |             payload.Data = g.DragDropPayloadBufLocal; | ||||||
|  |             memcpy((void*)payload.Data, data, data_size); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             payload.Data = NULL; | ||||||
|  |         } | ||||||
|  |         payload.DataSize = (int)data_size; | ||||||
|  |     } | ||||||
|  |     payload.DataFrameCount = g.FrameCount; | ||||||
|  |  | ||||||
|  |     return (payload.AcceptFrameCount == g.FrameCount) || (payload.AcceptFrameCount == g.FrameCount - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ImGui::BeginDragDropTarget() | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     if (!g.DragDropActive) | ||||||
|  |         return false; | ||||||
|  |  | ||||||
|  |     ImGuiWindow* window = g.CurrentWindow; | ||||||
|  |     //if (!window->DC.LastItemRectHoveredRect || (g.ActiveId == g.DragDropPayload.SourceId || g.ActiveIdPreviousFrame == g.DragDropPayload.SourceId)) | ||||||
|  |     if (!window->DC.LastItemRectHoveredRect || (window->DC.LastItemId && window->DC.LastItemId == g.DragDropPayload.SourceId)) | ||||||
|  |         return false; | ||||||
|  |     if (window->RootWindow != g.HoveredWindow->RootWindow) | ||||||
|  |         return false; | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     ImGuiWindow* window = g.CurrentWindow; | ||||||
|  |     ImGuiPayload& payload = g.DragDropPayload; | ||||||
|  |     IM_ASSERT(g.DragDropActive);                        // Not called between BeginDragDropTarget() and EndDragDropTarget() ? | ||||||
|  |     IM_ASSERT(window->DC.LastItemRectHoveredRect);      // Not called between BeginDragDropTarget() and EndDragDropTarget() ? | ||||||
|  |     IM_ASSERT(payload.DataFrameCount != -1);            // Internal/usage error, please report! | ||||||
|  |     if (type != NULL && !payload.IsDataType(type)) | ||||||
|  |         return NULL; | ||||||
|  |  | ||||||
|  |     if (payload.AcceptId == 0) | ||||||
|  |         payload.AcceptId = window->DC.LastItemId; | ||||||
|  |          | ||||||
|  |     bool was_accepted_previously = (payload.AcceptFrameCount == g.FrameCount - 1); | ||||||
|  |     if (payload.AcceptFrameCount != g.FrameCount) | ||||||
|  |     { | ||||||
|  |         // Render drop visuals | ||||||
|  |         if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) | ||||||
|  |         { | ||||||
|  |             ImRect r = window->DC.LastItemRect; | ||||||
|  |             r.Expand(4.0f); | ||||||
|  |             window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f);        // FIXME-DRAG FIXME-STYLE | ||||||
|  |             window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f);   // FIXME-DRAG FIXME-STYLE | ||||||
|  |         } | ||||||
|  |         payload.AcceptFrameCount = g.FrameCount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); | ||||||
|  |     if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) | ||||||
|  |         return NULL; | ||||||
|  |  | ||||||
|  |     return &payload; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // We don't really use/need this now, but added it for the sake of consistency and because we might need it later. | ||||||
|  | void ImGui::EndDragDropTarget() | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     IM_ASSERT(g.DragDropActive); | ||||||
|  | } | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| // PLATFORM DEPENDENT HELPERS | // PLATFORM DEPENDENT HELPERS | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
|   | |||||||
| @@ -43,9 +43,11 @@ struct ImGuiIniData; | |||||||
| struct ImGuiMouseCursorData; | struct ImGuiMouseCursorData; | ||||||
| struct ImGuiPopupRef; | struct ImGuiPopupRef; | ||||||
| struct ImGuiWindow; | struct ImGuiWindow; | ||||||
|  | struct ImGuiPayload;                // User data payload for drag and drop operations | ||||||
|  |  | ||||||
| typedef int ImGuiLayoutType;        // enum: horizontal or vertical             // enum ImGuiLayoutType_ | typedef int ImGuiLayoutType;        // enum: horizontal or vertical             // enum ImGuiLayoutType_ | ||||||
| typedef int ImGuiButtonFlags;       // flags: for ButtonEx(), ButtonBehavior()  // enum ImGuiButtonFlags_ | typedef int ImGuiButtonFlags;       // flags: for ButtonEx(), ButtonBehavior()  // enum ImGuiButtonFlags_ | ||||||
|  | typedef int ImGuiDragDropFlags;     // flags: for *DragDrop*()                  // enum ImGuiDragDropFlags_ | ||||||
| typedef int ImGuiItemFlags;         // flags: for PushItemFlag()                // enum ImGuiItemFlags_ | typedef int ImGuiItemFlags;         // flags: for PushItemFlag()                // enum ImGuiItemFlags_ | ||||||
| typedef int ImGuiSeparatorFlags;    // flags: for Separator() - internal        // enum ImGuiSeparatorFlags_ | typedef int ImGuiSeparatorFlags;    // flags: for Separator() - internal        // enum ImGuiSeparatorFlags_ | ||||||
| typedef int ImGuiSliderFlags;       // flags: for SliderBehavior()              // enum ImGuiSliderFlags_ | typedef int ImGuiSliderFlags;       // flags: for SliderBehavior()              // enum ImGuiSliderFlags_ | ||||||
| @@ -215,6 +217,15 @@ enum ImGuiSeparatorFlags_ | |||||||
|     ImGuiSeparatorFlags_Vertical            = 1 << 1 |     ImGuiSeparatorFlags_Vertical            = 1 << 1 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() | ||||||
|  | enum ImGuiDragDropFlags_ | ||||||
|  | { | ||||||
|  |     ImGuiDragDropFlags_SourceNoAutoTooltip      = 1 << 0, | ||||||
|  |     ImGuiDragDropFlags_AcceptBeforeDelivery     = 1 << 1,       // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. | ||||||
|  |     ImGuiDragDropFlags_AcceptNoDrawDefaultRect  = 1 << 2,       // Do not draw the default highlight rectangle when hovering over target. | ||||||
|  |     ImGuiDragDropFlags_AcceptPeekOnly           = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect  // For peeking ahead and inspecting the payload before delivery. | ||||||
|  | }; | ||||||
|  |  | ||||||
| // FIXME: this is in development, not exposed/functional as a generic feature yet. | // FIXME: this is in development, not exposed/functional as a generic feature yet. | ||||||
| enum ImGuiLayoutType_ | enum ImGuiLayoutType_ | ||||||
| { | { | ||||||
| @@ -404,6 +415,28 @@ struct ImGuiPopupRef | |||||||
|     ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } |     ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // Data payload for Drag and Drop operations | ||||||
|  | struct ImGuiPayload | ||||||
|  | { | ||||||
|  |     // Members | ||||||
|  |     const void*     Data;               // Data (copied and owned by dear imgui) | ||||||
|  |     int             DataSize;           // Data size | ||||||
|  |  | ||||||
|  |     // [Internal] | ||||||
|  |     ImGuiID         SourceId;           // Source item id | ||||||
|  |     ImGuiID         SourceParentId;     // Source parent id (if available) | ||||||
|  |     ImGuiID         AcceptId;           // Target item id (set at the time of accepting the payload) | ||||||
|  |     int             AcceptFrameCount;   // Last time a target expressed a desire to accept the source | ||||||
|  |     int             DataFrameCount;     // Data timestamp | ||||||
|  |     char            DataType[8 + 1];    // Data type tag (short user-supplied string) | ||||||
|  |     bool            Delivery;           // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item | ||||||
|  |  | ||||||
|  |     ImGuiPayload()  { Clear(); } | ||||||
|  |     void Clear()    { SourceId = SourceParentId = AcceptId = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } | ||||||
|  |     bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } | ||||||
|  |     bool IsDelivery() const                 { return Delivery; } | ||||||
|  | }; | ||||||
|  |  | ||||||
| // Main state for ImGui | // Main state for ImGui | ||||||
| struct ImGuiContext | struct ImGuiContext | ||||||
| { | { | ||||||
| @@ -472,6 +505,14 @@ struct ImGuiContext | |||||||
|     ImGuiMouseCursor        MouseCursor; |     ImGuiMouseCursor        MouseCursor; | ||||||
|     ImGuiMouseCursorData    MouseCursorData[ImGuiMouseCursor_Count_]; |     ImGuiMouseCursorData    MouseCursorData[ImGuiMouseCursor_Count_]; | ||||||
|  |  | ||||||
|  |     // Drag and Drop | ||||||
|  |     bool                    DragDropActive; | ||||||
|  |     ImGuiDragDropFlags      DragDropSourceFlags; | ||||||
|  |     int                     DragDropMouseButton; | ||||||
|  |     ImGuiPayload            DragDropPayload; | ||||||
|  |     ImVector<unsigned char> DragDropPayloadBufHeap;             // We don't expose the ImVector<> directly | ||||||
|  |     unsigned char           DragDropPayloadBufLocal[8]; | ||||||
|  |  | ||||||
|     // Widget state |     // Widget state | ||||||
|     ImGuiTextEditState      InputTextState; |     ImGuiTextEditState      InputTextState; | ||||||
|     ImFont                  InputTextPasswordFont; |     ImFont                  InputTextPasswordFont; | ||||||
| @@ -547,6 +588,10 @@ struct ImGuiContext | |||||||
|         SetNextTreeNodeOpenVal = false; |         SetNextTreeNodeOpenVal = false; | ||||||
|         SetNextTreeNodeOpenCond = 0; |         SetNextTreeNodeOpenCond = 0; | ||||||
|  |  | ||||||
|  |         DragDropActive = false; | ||||||
|  |         DragDropSourceFlags = 0; | ||||||
|  |         DragDropMouseButton = -1; | ||||||
|  |  | ||||||
|         ScalarAsInputTextId = 0; |         ScalarAsInputTextId = 0; | ||||||
|         ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; |         ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; | ||||||
|         DragCurrentValue = 0.0f; |         DragCurrentValue = 0.0f; | ||||||
| @@ -810,6 +855,14 @@ namespace ImGui | |||||||
|     IMGUI_API void          Scrollbar(ImGuiLayoutType direction); |     IMGUI_API void          Scrollbar(ImGuiLayoutType direction); | ||||||
|     IMGUI_API void          VerticalSeparator();        // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. |     IMGUI_API void          VerticalSeparator();        // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. | ||||||
|  |  | ||||||
|  |     // FIXME-WIP: New Drag and Drop API | ||||||
|  |     IMGUI_API bool          BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0);                      // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() | ||||||
|  |     IMGUI_API bool          SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. | ||||||
|  |     IMGUI_API void          EndDragDropSource(); | ||||||
|  |     IMGUI_API bool          BeginDragDropTarget();                                                                        // Call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() | ||||||
|  |     IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0);                  // Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. | ||||||
|  |     IMGUI_API void          EndDragDropTarget(); | ||||||
|  |  | ||||||
|     // FIXME-WIP: New Columns API |     // FIXME-WIP: New Columns API | ||||||
|     IMGUI_API void          BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). |     IMGUI_API void          BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). | ||||||
|     IMGUI_API void          EndColumns();                                                         // close columns |     IMGUI_API void          EndColumns();                                                         // close columns | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 omar
					omar