mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Tables: Reworked padding/spacing/width.
All widths are stored without padding. Decorelate padding from presence of border. Added ImGuiTableFlags_Pad/NoPad flags. Added demo. Merge StartXHeaders and StartXRows into StartX. Distinguish CellSpacingX1 and CellSpacingX2 for clarity and to avoid loss of width on non-even spacing values.
This commit is contained in:
		
							
								
								
									
										12
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1077,9 +1077,13 @@ enum ImGuiTableFlags_ | |||||||
|     ImGuiTableFlags_NoHostExtendY                   = 1 << 17,  // (FIXME-TABLE: Reword as SizingPolicy?) Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible) |     ImGuiTableFlags_NoHostExtendY                   = 1 << 17,  // (FIXME-TABLE: Reword as SizingPolicy?) Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible) | ||||||
|     ImGuiTableFlags_NoKeepColumnsVisible            = 1 << 18,  // (FIXME-TABLE) Disable code that keeps column always minimally visible when table width gets too small and horizontal scrolling is off. |     ImGuiTableFlags_NoKeepColumnsVisible            = 1 << 18,  // (FIXME-TABLE) Disable code that keeps column always minimally visible when table width gets too small and horizontal scrolling is off. | ||||||
|     ImGuiTableFlags_NoClip                          = 1 << 19,  // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). |     ImGuiTableFlags_NoClip                          = 1 << 19,  // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). | ||||||
|  |     // Padding | ||||||
|  |     ImGuiTableFlags_PadOuterX                       = 1 << 20,  // Default if BordersOuterV is on. Enable outer-most padding. | ||||||
|  |     ImGuiTableFlags_NoPadOuterX                     = 1 << 21,  // Default if BordersOuterV is off. Disable outer-most padding. | ||||||
|  |     ImGuiTableFlags_NoPadInnerX                     = 1 << 22,  // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off). | ||||||
|     // Scrolling |     // Scrolling | ||||||
|     ImGuiTableFlags_ScrollX                         = 1 << 20,  // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. |     ImGuiTableFlags_ScrollX                         = 1 << 23,  // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. | ||||||
|     ImGuiTableFlags_ScrollY                         = 1 << 21,  // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. |     ImGuiTableFlags_ScrollY                         = 1 << 24,  // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. | ||||||
|     ImGuiTableFlags_Scroll                          = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, |     ImGuiTableFlags_Scroll                          = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, | ||||||
|  |  | ||||||
|     // [Internal] Combinations and masks |     // [Internal] Combinations and masks | ||||||
| @@ -1134,8 +1138,8 @@ enum ImGuiTableRowFlags_ | |||||||
| enum ImGuiTableBgTarget_ | enum ImGuiTableBgTarget_ | ||||||
| { | { | ||||||
|     ImGuiTableBgTarget_None                         = 0, |     ImGuiTableBgTarget_None                         = 0, | ||||||
|     ImGuiTableBgTarget_ColumnBg0                    = 1,        // FIXME-TABLE: Todo. Set column background color 0 (generally used for background |     //ImGuiTableBgTarget_ColumnBg0                  = 1,        // FIXME-TABLE: Todo. Set column background color 0 (generally used for background | ||||||
|     ImGuiTableBgTarget_ColumnBg1                    = 2,        // FIXME-TABLE: Todo. Set column background color 1 (generally used for selection marking) |     //ImGuiTableBgTarget_ColumnBg1                  = 2,        // FIXME-TABLE: Todo. Set column background color 1 (generally used for selection marking) | ||||||
|     ImGuiTableBgTarget_RowBg0                       = 3,        // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) |     ImGuiTableBgTarget_RowBg0                       = 3,        // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) | ||||||
|     ImGuiTableBgTarget_RowBg1                       = 4,        // Set row background color 1 (generally used for selection marking) |     ImGuiTableBgTarget_RowBg1                       = 4,        // Set row background color 1 (generally used for selection marking) | ||||||
|     ImGuiTableBgTarget_CellBg                       = 5         // Set cell background color (top-most color) |     ImGuiTableBgTarget_CellBg                       = 5         // Set cell background color (top-most color) | ||||||
|   | |||||||
							
								
								
									
										106
									
								
								imgui_demo.cpp
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								imgui_demo.cpp
									
									
									
									
									
								
							| @@ -3405,9 +3405,8 @@ static void ShowDemoWindowTables() | |||||||
|     { |     { | ||||||
|         // Expose a few Borders related flags interactively |         // Expose a few Borders related flags interactively | ||||||
|         enum ContentsType { CT_Text, CT_FillButton }; |         enum ContentsType { CT_Text, CT_FillButton }; | ||||||
|         static ImGuiTableFlags flags = ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg; |         static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; | ||||||
|         static bool display_headers = false; |         static bool display_headers = false; | ||||||
|         static bool display_width = false; |  | ||||||
|         static int contents_type = CT_Text; |         static int contents_type = CT_Text; | ||||||
|  |  | ||||||
|         PushStyleCompact(); |         PushStyleCompact(); | ||||||
| @@ -3438,7 +3437,6 @@ static void ShowDemoWindowTables() | |||||||
|         ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text); |         ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text); | ||||||
|         ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton); |         ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton); | ||||||
|         ImGui::Checkbox("Display headers", &display_headers); |         ImGui::Checkbox("Display headers", &display_headers); | ||||||
|         ImGui::Checkbox("Display debug width", &display_width); |  | ||||||
|         PopStyleCompact(); |         PopStyleCompact(); | ||||||
|  |  | ||||||
|         if (ImGui::BeginTable("##table1", 3, flags)) |         if (ImGui::BeginTable("##table1", 3, flags)) | ||||||
| @@ -3458,28 +3456,11 @@ static void ShowDemoWindowTables() | |||||||
|                 ImGui::TableNextRow(); |                 ImGui::TableNextRow(); | ||||||
|                 for (int column = 0; column < 3; column++) |                 for (int column = 0; column < 3; column++) | ||||||
|                 { |                 { | ||||||
|                     ImGui::TableSetColumnIndex(column); |                     if (!ImGui::TableSetColumnIndex(column)) | ||||||
|                     char buf[32]; |                         continue; | ||||||
|                     if (display_width) |  | ||||||
|                     { |  | ||||||
|                         // [DEBUG] Draw limits FIXME-TABLE: Move to Advanced section |  | ||||||
|                         ImVec2 p = ImGui::GetCursorScreenPos(); |  | ||||||
|                         float contents_x1 = p.x; |  | ||||||
|                         float contents_x2 = ImGui::GetWindowPos().x + ImGui::GetContentRegionMax().x; |  | ||||||
|                         float cliprect_x1 = ImGui::GetWindowDrawList()->GetClipRectMin().x; |  | ||||||
|                         float cliprect_x2 = ImGui::GetWindowDrawList()->GetClipRectMax().x; |  | ||||||
|                         float y1 = p.y; |  | ||||||
|                         float y2 = p.y + ImGui::GetTextLineHeight() + 2.0f; |  | ||||||
|                         ImDrawList* fg_draw_list = ImGui::GetForegroundDrawList(); |  | ||||||
|                         fg_draw_list->AddRect(ImVec2(contents_x1, y1 + 0.0f), ImVec2(contents_x2, y2 + 0.0f), IM_COL32(255, 0, 0, 255));   // Contents limit (e.g. Cell + Padding) |  | ||||||
|                         fg_draw_list->AddLine(ImVec2(cliprect_x1, y2 + 1.0f), ImVec2(cliprect_x2, y2 + 1.0f), IM_COL32(255, 255, 0, 255)); // Hard clipping limit |  | ||||||
|                         sprintf(buf, "w=%.2f", contents_x2 - contents_x1); |  | ||||||
|                     } |  | ||||||
|                     else |  | ||||||
|                     { |  | ||||||
|                         sprintf(buf, "Hello %d,%d", row, column); |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|  |                     char buf[32]; | ||||||
|  |                     sprintf(buf, "Hello %d,%d", row, column); | ||||||
|                     if (contents_type == CT_Text) |                     if (contents_type == CT_Text) | ||||||
|                         ImGui::TextUnformatted(buf); |                         ImGui::TextUnformatted(buf); | ||||||
|                     else if (contents_type) |                     else if (contents_type) | ||||||
| @@ -3650,25 +3631,82 @@ static void ShowDemoWindowTables() | |||||||
|  |  | ||||||
|     if (open_action != -1) |     if (open_action != -1) | ||||||
|         ImGui::SetNextItemOpen(open_action != 0); |         ImGui::SetNextItemOpen(open_action != 0); | ||||||
|     if (ImGui::TreeNode("Explicit widths")) |     if (ImGui::TreeNode("Padding")) | ||||||
|     { |     { | ||||||
|         static ImGuiTableFlags flags = ImGuiTableFlags_None; |         static ImGuiTableFlags flags = ImGuiTableFlags_BordersV; | ||||||
|  |  | ||||||
|  |         HelpMarker( | ||||||
|  |             "We often want outer padding activated when any using features which makes the edges of a column visible:\n" | ||||||
|  |             "e.g.:\n" | ||||||
|  |             "- BorderOuterV\n" | ||||||
|  |             "- any form of row selection\n" | ||||||
|  |             "Because of this, activating BorderOuterV sets the default to PadOuterX. Using PadOuterX or NoPadOuterX you can override the default.\n"); | ||||||
|  |  | ||||||
|         PushStyleCompact(); |         PushStyleCompact(); | ||||||
|         ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", (unsigned int*)&flags, ImGuiTableFlags_NoKeepColumnsVisible); |         ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", (unsigned int*)&flags, ImGuiTableFlags_PadOuterX); | ||||||
|  |         ImGui::SameLine(); HelpMarker("Enable outer-most padding (default if ImGuiTableFlags_BordersOuterV is set)"); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", (unsigned int*)&flags, ImGuiTableFlags_NoPadOuterX); | ||||||
|  |         ImGui::SameLine(); HelpMarker("Disable outer-most padding (default if ImGuiTableFlags_BordersOuterV is not set)"); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", (unsigned int*)&flags, ImGuiTableFlags_NoPadInnerX); | ||||||
|  |         ImGui::SameLine(); HelpMarker("Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off)"); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", (unsigned int*)&flags, ImGuiTableFlags_BordersOuterV); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", (unsigned int*)&flags, ImGuiTableFlags_BordersInnerV); | ||||||
|         PopStyleCompact(); |         PopStyleCompact(); | ||||||
|  |  | ||||||
|         if (ImGui::BeginTable("##table1", 3, flags)) |         if (ImGui::BeginTable("##table1", 3, flags)) | ||||||
|         { |         { | ||||||
|             // We could also set ImGuiTableFlags_SizingPolicyFixedX on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. |  | ||||||
|             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); |  | ||||||
|             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f); |  | ||||||
|             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); |  | ||||||
|             for (int row = 0; row < 5; row++) |             for (int row = 0; row < 5; row++) | ||||||
|             { |             { | ||||||
|                 ImGui::TableNextRow(); |                 ImGui::TableNextRow(); | ||||||
|                 for (int column = 0; column < 3; column++) |                 for (int column = 0; column < 3; column++) | ||||||
|                 { |                 { | ||||||
|                     ImGui::TableSetColumnIndex(column); |                     ImGui::TableSetColumnIndex(column); | ||||||
|  |                     if (row == 0) | ||||||
|  |                     { | ||||||
|  |                         ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         char buf[32]; | ||||||
|  |                         sprintf(buf, "Hello %d,%d", row, column); | ||||||
|  |                         ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); | ||||||
|  |                     } | ||||||
|  |                     if (ImGui::TableGetHoveredColumn() == column) | ||||||
|  |                         ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, IM_COL32(0, 100, 0, 255)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             ImGui::EndTable(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ImGui::TreePop(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (open_action != -1) | ||||||
|  |         ImGui::SetNextItemOpen(open_action != 0); | ||||||
|  |     if (ImGui::TreeNode("Explicit widths")) | ||||||
|  |     { | ||||||
|  |         static ImGuiTableFlags flags = ImGuiTableFlags_None; | ||||||
|  |         PushStyleCompact(); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", (unsigned int*)&flags, ImGuiTableFlags_NoKeepColumnsVisible); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", (unsigned int*)&flags, ImGuiTableFlags_BordersInnerV); | ||||||
|  |         ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", (unsigned int*)&flags, ImGuiTableFlags_BordersOuterV); | ||||||
|  |         PopStyleCompact(); | ||||||
|  |  | ||||||
|  |         if (ImGui::BeginTable("##table1", 4, flags)) | ||||||
|  |         { | ||||||
|  |             // We could also set ImGuiTableFlags_SizingPolicyFixedX on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. | ||||||
|  |             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f); | ||||||
|  |             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); | ||||||
|  |             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f); | ||||||
|  |             ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); | ||||||
|  |             for (int row = 0; row < 5; row++) | ||||||
|  |             { | ||||||
|  |                 ImGui::TableNextRow(); | ||||||
|  |                 for (int column = 0; column < 4; column++) | ||||||
|  |                 { | ||||||
|  |                     ImGui::TableSetColumnIndex(column); | ||||||
|  |                     if (row == 0) | ||||||
|  |                         ImGui::Text("(%.2f)", ImGui::GetContentRegionAvail().x); | ||||||
|                     ImGui::Text("Hello %d,%d", row, column); |                     ImGui::Text("Hello %d,%d", row, column); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -3679,7 +3717,7 @@ static void ShowDemoWindowTables() | |||||||
|  |  | ||||||
|     if (open_action != -1) |     if (open_action != -1) | ||||||
|         ImGui::SetNextItemOpen(open_action != 0); |         ImGui::SetNextItemOpen(open_action != 0); | ||||||
|     if (ImGui::TreeNode("Vertical scrolling, with clipping")) |     if (ImGui::TreeNode("Vertical scrolling")) | ||||||
|     { |     { | ||||||
|         HelpMarker("Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\nWe also demonstrate using ImGuiListClipper to virtualize the submission of many items."); |         HelpMarker("Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\nWe also demonstrate using ImGuiListClipper to virtualize the submission of many items."); | ||||||
|         static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; |         static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; | ||||||
| @@ -4356,6 +4394,7 @@ static void ShowDemoWindowTables() | |||||||
|         ImGui::TreePop(); |         ImGui::TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG] | ||||||
|     if (open_action != -1) |     if (open_action != -1) | ||||||
|         ImGui::SetNextItemOpen(open_action != 0); |         ImGui::SetNextItemOpen(open_action != 0); | ||||||
|     if (ImGui::TreeNode("Advanced")) |     if (ImGui::TreeNode("Advanced")) | ||||||
| @@ -4415,6 +4454,9 @@ static void ShowDemoWindowTables() | |||||||
|  |  | ||||||
|             if (ImGui::TreeNodeEx("Sizing, Padding:", ImGuiTreeNodeFlags_DefaultOpen)) |             if (ImGui::TreeNodeEx("Sizing, Padding:", ImGuiTreeNodeFlags_DefaultOpen)) | ||||||
|             { |             { | ||||||
|  |                 ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", (unsigned int*)&flags, ImGuiTableFlags_PadOuterX); | ||||||
|  |                 ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", (unsigned int*)&flags, ImGuiTableFlags_NoPadOuterX); | ||||||
|  |                 ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", (unsigned int*)&flags, ImGuiTableFlags_NoPadInnerX); | ||||||
|                 if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretchX", (unsigned int*)&flags, ImGuiTableFlags_SizingPolicyStretchX)) |                 if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretchX", (unsigned int*)&flags, ImGuiTableFlags_SizingPolicyStretchX)) | ||||||
|                     flags &= ~(ImGuiTableFlags_SizingPolicyMaskX_ ^ ImGuiTableFlags_SizingPolicyStretchX);  // Can't specify both sizing polices so we clear the other |                     flags &= ~(ImGuiTableFlags_SizingPolicyMaskX_ ^ ImGuiTableFlags_SizingPolicyStretchX);  // Can't specify both sizing polices so we clear the other | ||||||
|                 ImGui::SameLine(); HelpMarker("[Default if ScrollX is off]\nFit all columns within available width (or specified inner_width). Fixed and Stretch columns allowed."); |                 ImGui::SameLine(); HelpMarker("[Default if ScrollX is off]\nFit all columns within available width (or specified inner_width). Fixed and Stretch columns allowed."); | ||||||
|   | |||||||
| @@ -1887,7 +1887,7 @@ struct ImGuiTabBar | |||||||
| #define IMGUI_TABLE_MAX_COLUMNS         64                  // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. | #define IMGUI_TABLE_MAX_COLUMNS         64                  // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. | ||||||
| #define IMGUI_TABLE_MAX_DRAW_CHANNELS   (2 + 64 * 2)        // See TableUpdateDrawChannels() | #define IMGUI_TABLE_MAX_DRAW_CHANNELS   (2 + 64 * 2)        // See TableUpdateDrawChannels() | ||||||
|  |  | ||||||
| // [Internal] sizeof() ~ 104 | // [Internal] sizeof() ~ 108 | ||||||
| // We use the terminology "Visible" to refer to a column that is not Hidden by user or settings. However it may still be out of view and clipped (see IsClipped). | // We use the terminology "Visible" to refer to a column that is not Hidden by user or settings. However it may still be out of view and clipped (see IsClipped). | ||||||
| struct ImGuiTableColumn | struct ImGuiTableColumn | ||||||
| { | { | ||||||
| @@ -1897,10 +1897,11 @@ struct ImGuiTableColumn | |||||||
|     ImGuiTableColumnFlags   Flags;                          // Effective flags. See ImGuiTableColumnFlags_ |     ImGuiTableColumnFlags   Flags;                          // Effective flags. See ImGuiTableColumnFlags_ | ||||||
|     float                   MinX;                           // Absolute positions |     float                   MinX;                           // Absolute positions | ||||||
|     float                   MaxX; |     float                   MaxX; | ||||||
|     float                   WidthOrWeightInitValue;         // Value passed to TableSetupColumn() |     float                   InitStretchWeightOrWidth;       // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_). | ||||||
|     float                   WidthStretchWeight;             // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially. |     float                   StretchWeight;                  // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially. | ||||||
|     float                   WidthRequest;                   // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from WidthStretchWeight in TableUpdateLayout() |     float                   WidthAuto;                      // Automatic width | ||||||
|     float                   WidthGiven;                     // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be >WidthRequest to honor minimum width, may be <WidthRequest to honor shrinking columns down in tight space. |     float                   WidthRequest;                   // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from StretchWeight in TableUpdateLayout() | ||||||
|  |     float                   WidthGiven;                     // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space. | ||||||
|     float                   StartX;                         // Start position for the frame, currently ~(MinX + CellPaddingX) |     float                   StartX;                         // Start position for the frame, currently ~(MinX + CellPaddingX) | ||||||
|     float                   ContentMaxPosFrozen;            // Submitted contents absolute maximum position, from which we can infer width. Kept as float because we need to manipulate those between each cell change. |     float                   ContentMaxPosFrozen;            // Submitted contents absolute maximum position, from which we can infer width. Kept as float because we need to manipulate those between each cell change. | ||||||
|     float                   ContentMaxPosUnfrozen; |     float                   ContentMaxPosUnfrozen; | ||||||
| @@ -1931,7 +1932,7 @@ struct ImGuiTableColumn | |||||||
|     ImGuiTableColumn() |     ImGuiTableColumn() | ||||||
|     { |     { | ||||||
|         memset(this, 0, sizeof(*this)); |         memset(this, 0, sizeof(*this)); | ||||||
|         WidthStretchWeight = WidthRequest = WidthGiven = -1.0f; |         StretchWeight = WidthRequest = -1.0f; | ||||||
|         NameOffset = -1; |         NameOffset = -1; | ||||||
|         IsVisible = IsVisibleNextFrame = true; |         IsVisible = IsVisibleNextFrame = true; | ||||||
|         DisplayOrder = IndexWithinVisibleSet = -1; |         DisplayOrder = IndexWithinVisibleSet = -1; | ||||||
| @@ -1985,10 +1986,11 @@ struct ImGuiTable | |||||||
|     float                       BorderX1; |     float                       BorderX1; | ||||||
|     float                       BorderX2; |     float                       BorderX2; | ||||||
|     float                       HostIndentX; |     float                       HostIndentX; | ||||||
|     float                       CellPaddingX1;              // Padding from each borders |     float                       OuterPaddingX; | ||||||
|     float                       CellPaddingX2; |     float                       CellPaddingX;               // Padding from each borders | ||||||
|     float                       CellPaddingY; |     float                       CellPaddingY; | ||||||
|     float                       CellSpacingX;               // Spacing between non-bordered cells |     float                       CellSpacingX1;              // Spacing between non-bordered cells | ||||||
|  |     float                       CellSpacingX2; | ||||||
|     float                       LastOuterHeight;            // Outer height from last frame |     float                       LastOuterHeight;            // Outer height from last frame | ||||||
|     float                       LastFirstRowHeight;         // Height of first row from last frame |     float                       LastFirstRowHeight;         // Height of first row from last frame | ||||||
|     float                       InnerWidth;                 // User value passed to BeginTable(), see comments at the top of BeginTable() for details. |     float                       InnerWidth;                 // User value passed to BeginTable(), see comments at the top of BeginTable() for details. | ||||||
| @@ -2285,7 +2287,7 @@ namespace ImGui | |||||||
|     IMGUI_API void          TableEndRow(ImGuiTable* table); |     IMGUI_API void          TableEndRow(ImGuiTable* table); | ||||||
|     IMGUI_API void          TableBeginCell(ImGuiTable* table, int column_n); |     IMGUI_API void          TableBeginCell(ImGuiTable* table, int column_n); | ||||||
|     IMGUI_API void          TableEndCell(ImGuiTable* table); |     IMGUI_API void          TableEndCell(ImGuiTable* table); | ||||||
|     IMGUI_API ImRect        TableGetCellBgRect(); |     IMGUI_API ImRect        TableGetCellBgRect(const ImGuiTable* table, int column_n); | ||||||
|     IMGUI_API const char*   TableGetColumnName(const ImGuiTable* table, int column_n); |     IMGUI_API const char*   TableGetColumnName(const ImGuiTable* table, int column_n); | ||||||
|     IMGUI_API ImGuiID       TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); |     IMGUI_API ImGuiID       TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); | ||||||
|     IMGUI_API void          TableSetColumnAutofit(ImGuiTable* table, int column_n); |     IMGUI_API void          TableSetColumnAutofit(ImGuiTable* table, int column_n); | ||||||
|   | |||||||
							
								
								
									
										228
									
								
								imgui_tables.cpp
									
									
									
									
									
								
							
							
						
						
									
										228
									
								
								imgui_tables.cpp
									
									
									
									
									
								
							| @@ -290,17 +290,25 @@ bool    ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG | |||||||
|     table->HostCursorMaxPos = inner_window->DC.CursorMaxPos; |     table->HostCursorMaxPos = inner_window->DC.CursorMaxPos; | ||||||
|     inner_window->ParentWorkRect = inner_window->WorkRect; |     inner_window->ParentWorkRect = inner_window->WorkRect; | ||||||
|  |  | ||||||
|     // Borders |     // Padding and Spacing | ||||||
|     // - None               ........Content..... Pad .....Content........ |     // - None               ........Content..... Pad .....Content........ | ||||||
|     // - OuterV             | Pad ..Content..... Pad .....Content.. Pad |       // FIXME-TABLE: Not handled properly |     // - PadOuter           | Pad ..Content..... Pad .....Content.. Pad | | ||||||
|     // - InnerV             ........Content.. Pad | Pad ..Content........       // FIXME-TABLE: Not handled properly |     // - PadInner           ........Content.. Pad | Pad ..Content........ | ||||||
|     // - OuterV+InnerV      | Pad ..Content.. Pad | Pad ..Content.. Pad | |     // - PadOuter+PadInner  | Pad ..Content.. Pad | Pad ..Content.. Pad | | ||||||
|  |     const bool pad_outer_x = (flags & ImGuiTableFlags_NoPadOuterX) ? false : (flags & ImGuiTableFlags_PadOuterX) ? true : (flags & ImGuiTableFlags_BordersOuterV) != 0; | ||||||
|     const bool has_cell_padding_x = (flags & ImGuiTableFlags_BordersOuterV) != 0; |     const bool pad_inner_x = (flags & ImGuiTableFlags_NoPadInnerX) ? false : true; | ||||||
|     table->CellPaddingX1 = has_cell_padding_x ? g.Style.CellPadding.x + 1.0f : 0.0f; |     const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f; | ||||||
|     table->CellPaddingX2 = has_cell_padding_x ? g.Style.CellPadding.x : 0.0f; |     const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f; | ||||||
|  |     const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f; | ||||||
|  |     const float inner_spacing = inner_spacing_for_border + inner_spacing_explicit; | ||||||
|  |     table->CellSpacingX1 = ImCeil(inner_spacing * 0.5f); | ||||||
|  |     table->CellSpacingX2 = inner_spacing - table->CellSpacingX1; | ||||||
|  |     table->CellPaddingX = inner_padding_explicit; | ||||||
|     table->CellPaddingY = g.Style.CellPadding.y; |     table->CellPaddingY = g.Style.CellPadding.y; | ||||||
|     table->CellSpacingX = has_cell_padding_x ? 0.0f : g.Style.CellPadding.x; |  | ||||||
|  |     const float outer_padding_for_border = (flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f; | ||||||
|  |     const float outer_padding_explicit = pad_outer_x ? g.Style.CellPadding.x : 0.0f; | ||||||
|  |     table->OuterPaddingX = (outer_padding_for_border + outer_padding_explicit) - table->CellPaddingX; | ||||||
|  |  | ||||||
|     table->CurrentColumn = -1; |     table->CurrentColumn = -1; | ||||||
|     table->CurrentRow = -1; |     table->CurrentRow = -1; | ||||||
| @@ -332,7 +340,7 @@ bool    ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG | |||||||
|     outer_window->DC.CurrentTableIdx = table_idx; |     outer_window->DC.CurrentTableIdx = table_idx; | ||||||
|     if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. |     if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. | ||||||
|         inner_window->DC.CurrentTableIdx = table_idx; |         inner_window->DC.CurrentTableIdx = table_idx; | ||||||
|     if ((table_last_flags & ImGuiTableFlags_Reorderable) && !(flags & ImGuiTableFlags_Reorderable)) |     if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) | ||||||
|         table->IsResetDisplayOrderRequest = true; |         table->IsResetDisplayOrderRequest = true; | ||||||
|  |  | ||||||
|     // Setup memory buffer (clear data if columns count changed) |     // Setup memory buffer (clear data if columns count changed) | ||||||
| @@ -591,11 +599,12 @@ static void TableFixColumnSortDirection(ImGuiTableColumn* column) | |||||||
|         column->SortDirection = ImGuiSortDirection_Ascending; |         column->SortDirection = ImGuiSortDirection_Ascending; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Minimum column content width (without padding) | ||||||
| static float TableGetMinColumnWidth() | static float TableGetMinColumnWidth() | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     // return g.Style.ColumnsMinSpacing; |     // return g.Style.ColumnsMinSpacing; // FIXME-TABLE | ||||||
|     return g.Style.FramePadding.x * 3.0f; |     return g.Style.FramePadding.x * 1.0f; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Layout columns for the frame | // Layout columns for the frame | ||||||
| @@ -614,14 +623,13 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|     // Compute offset, clip rect for the frame |     // Compute offset, clip rect for the frame | ||||||
|     // (can't make auto padding larger than what WorkRect knows about so right-alignment matches) |     // (can't make auto padding larger than what WorkRect knows about so right-alignment matches) | ||||||
|     const ImRect work_rect = table->WorkRect; |     const ImRect work_rect = table->WorkRect; | ||||||
|     const float padding_auto_x = table->CellPaddingX2; |  | ||||||
|     const float min_column_width = TableGetMinColumnWidth(); |     const float min_column_width = TableGetMinColumnWidth(); | ||||||
|  |     const float min_column_width_padded = min_column_width + table->CellPaddingX * 2.0f; | ||||||
|  |  | ||||||
|     int count_fixed = 0; |     int count_fixed = 0; | ||||||
|     float sum_weights_stretched = 0.0f;     // Sum of all weights for weighted columns. |     float sum_weights_stretched = 0.0f;     // Sum of all weights for weighted columns. | ||||||
|     float sum_width_fixed_requests = 0.0f;  // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns. |     float sum_width_fixed_requests = 0.0f;  // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns. | ||||||
|     table->LeftMostStretchedColumnDisplayOrder = -1; |     table->LeftMostStretchedColumnDisplayOrder = -1; | ||||||
|     table->ColumnsAutoFitWidth = 0.0f; |  | ||||||
|     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) | ||||||
|     { |     { | ||||||
|         if (!(table->VisibleMaskByDisplayOrder & ((ImU64)1 << order_n))) |         if (!(table->VisibleMaskByDisplayOrder & ((ImU64)1 << order_n))) | ||||||
| @@ -642,30 +650,26 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|  |  | ||||||
|         // Calculate "ideal" column width for nothing to be clipped. |         // Calculate "ideal" column width for nothing to be clipped. | ||||||
|         // Combine width from regular rows + width from headers unless requested not to. |         // Combine width from regular rows + width from headers unless requested not to. | ||||||
|         const float column_content_width_rows = (float)ImMax(column->ContentWidthFrozen, column->ContentWidthUnfrozen); |         const float content_width_body = (float)ImMax(column->ContentWidthFrozen, column->ContentWidthUnfrozen); | ||||||
|         const float column_content_width_headers = (float)column->ContentWidthHeadersIdeal; |         const float content_width_headers = (float)column->ContentWidthHeadersIdeal; | ||||||
|         float column_width_ideal = column_content_width_rows; |         float width_auto = content_width_body; | ||||||
|         if (!(table->Flags & ImGuiTableFlags_NoHeadersWidth) && !(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth)) |         if (!(table->Flags & ImGuiTableFlags_NoHeadersWidth) && !(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth)) | ||||||
|             column_width_ideal = ImMax(column_width_ideal, column_content_width_headers); |             width_auto = ImMax(width_auto, content_width_headers); | ||||||
|         column_width_ideal = ImMax(column_width_ideal + padding_auto_x, min_column_width); |         width_auto = ImMax(width_auto, min_column_width); // Without padding | ||||||
|  |  | ||||||
|         // Non-resizable columns also submit their requested width |         // Non-resizable columns also submit their requested width | ||||||
|         if (column->Flags & ImGuiTableColumnFlags_WidthFixed) |         if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f) | ||||||
|             if (column->WidthOrWeightInitValue > 0.0f) |  | ||||||
|             if (!(table->Flags & ImGuiTableFlags_Resizable) || !(column->Flags & ImGuiTableColumnFlags_NoResize)) |             if (!(table->Flags & ImGuiTableFlags_Resizable) || !(column->Flags & ImGuiTableColumnFlags_NoResize)) | ||||||
|                     column_width_ideal = ImMax(column_width_ideal, column->WidthOrWeightInitValue); |                 width_auto = ImMax(width_auto, column->InitStretchWeightOrWidth); | ||||||
|  |  | ||||||
|         // CellSpacingX is >0.0f when there's no vertical border |         column->WidthAuto = width_auto; | ||||||
|         table->ColumnsAutoFitWidth += column_width_ideal; |  | ||||||
|         if (column->PrevVisibleColumn != -1) |  | ||||||
|             table->ColumnsAutoFitWidth += table->CellSpacingX; |  | ||||||
|  |  | ||||||
|         if (column->Flags & (ImGuiTableColumnFlags_WidthAlwaysAutoResize | ImGuiTableColumnFlags_WidthFixed)) |         if (column->Flags & (ImGuiTableColumnFlags_WidthAlwaysAutoResize | ImGuiTableColumnFlags_WidthFixed)) | ||||||
|         { |         { | ||||||
|             // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) |             // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) | ||||||
|             count_fixed += 1; |             count_fixed += 1; | ||||||
|             if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) && !column->IsClipped)) |             if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) && !column->IsClipped)) | ||||||
|                 column->WidthRequest = column_width_ideal; |                 column->WidthRequest = width_auto; | ||||||
|  |  | ||||||
|             // FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets |             // FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets | ||||||
|             // (e.g. TextWrapped) too much. Otherwise what tends to happen is that TextWrapped would output a very |             // (e.g. TextWrapped) too much. Otherwise what tends to happen is that TextWrapped would output a very | ||||||
| @@ -680,17 +684,18 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             IM_ASSERT(column->Flags & ImGuiTableColumnFlags_WidthStretch); |             IM_ASSERT(column->Flags & ImGuiTableColumnFlags_WidthStretch); | ||||||
|             const int init_size = (column->WidthStretchWeight < 0.0f); |             const int init_size = (column->StretchWeight < 0.0f); | ||||||
|             if (init_size) |             if (init_size) | ||||||
|                 column->WidthStretchWeight = 1.0f; |                 column->StretchWeight = 1.0f; | ||||||
|             sum_weights_stretched += column->WidthStretchWeight; |             sum_weights_stretched += column->StretchWeight; | ||||||
|             if (table->LeftMostStretchedColumnDisplayOrder == -1) |             if (table->LeftMostStretchedColumnDisplayOrder == -1) | ||||||
|                 table->LeftMostStretchedColumnDisplayOrder = (ImS8)column->DisplayOrder; |                 table->LeftMostStretchedColumnDisplayOrder = (ImS8)column->DisplayOrder; | ||||||
|         } |         } | ||||||
|  |         sum_width_fixed_requests += table->CellPaddingX * 2.0f; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Layout |     // Layout | ||||||
|     const float width_spacings = table->CellSpacingX * (table->ColumnsVisibleCount - 1); |     const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsVisibleCount - 1); | ||||||
|     float width_avail; |     float width_avail; | ||||||
|     if ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) |     if ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) | ||||||
|         width_avail = table->InnerClipRect.GetWidth() - width_spacings; |         width_avail = table->InnerClipRect.GetWidth() - width_spacings; | ||||||
| @@ -703,6 +708,7 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|     // Mark some columns as not resizable |     // Mark some columns as not resizable | ||||||
|     int count_resizable = 0; |     int count_resizable = 0; | ||||||
|     table->ColumnsTotalWidth = width_spacings; |     table->ColumnsTotalWidth = width_spacings; | ||||||
|  |     table->ColumnsAutoFitWidth = width_spacings; | ||||||
|     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) | ||||||
|     { |     { | ||||||
|         if (!(table->VisibleMaskByDisplayOrder & ((ImU64)1 << order_n))) |         if (!(table->VisibleMaskByDisplayOrder & ((ImU64)1 << order_n))) | ||||||
| @@ -712,8 +718,8 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         // Allocate width for stretched/weighted columns |         // Allocate width for stretched/weighted columns | ||||||
|         if (column->Flags & ImGuiTableColumnFlags_WidthStretch) |         if (column->Flags & ImGuiTableColumnFlags_WidthStretch) | ||||||
|         { |         { | ||||||
|             // WidthStretchWeight gets converted into WidthRequest |             // StretchWeight gets converted into WidthRequest | ||||||
|             float weight_ratio = column->WidthStretchWeight / sum_weights_stretched; |             float weight_ratio = column->StretchWeight / sum_weights_stretched; | ||||||
|             column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, min_column_width) + 0.01f); |             column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, min_column_width) + 0.01f); | ||||||
|             width_remaining_for_stretched_columns -= column->WidthRequest; |             width_remaining_for_stretched_columns -= column->WidthRequest; | ||||||
|  |  | ||||||
| @@ -735,7 +741,8 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|  |  | ||||||
|         // Assign final width, record width in case we will need to shrink |         // Assign final width, record width in case we will need to shrink | ||||||
|         column->WidthGiven = ImFloor(ImMax(column->WidthRequest, min_column_width)); |         column->WidthGiven = ImFloor(ImMax(column->WidthRequest, min_column_width)); | ||||||
|         table->ColumnsTotalWidth += column->WidthGiven; |         table->ColumnsTotalWidth += column->WidthGiven + table->CellPaddingX * 2.0f; | ||||||
|  |         table->ColumnsAutoFitWidth += column->WidthAuto + table->CellPaddingX * 2.0f; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
| @@ -788,6 +795,7 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|     // Setup final position, offset and clipping rectangles |     // Setup final position, offset and clipping rectangles | ||||||
|     int visible_n = 0; |     int visible_n = 0; | ||||||
|     float offset_x = (table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x; |     float offset_x = (table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x; | ||||||
|  |     offset_x += table->OuterPaddingX; | ||||||
|     ImRect host_clip_rect = table->InnerClipRect; |     ImRect host_clip_rect = table->InnerClipRect; | ||||||
|     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |     for (int order_n = 0; order_n < table->ColumnsCount; order_n++) | ||||||
|     { |     { | ||||||
| @@ -820,7 +828,7 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         { |         { | ||||||
|             // Frozen columns can't reach beyond visible width else scrolling will naturally break. |             // Frozen columns can't reach beyond visible width else scrolling will naturally break. | ||||||
|             if (order_n < table->FreezeColumnsRequest) |             if (order_n < table->FreezeColumnsRequest) | ||||||
|                 max_x = table->InnerClipRect.Max.x - (table->FreezeColumnsRequest - order_n) * min_column_width; |                 max_x = table->InnerClipRect.Max.x - (table->FreezeColumnsRequest - order_n) * min_column_width_padded - table->OuterPaddingX; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
| @@ -828,18 +836,19 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|             // sure they are all visible. Because of this we also know that all of the columns will always fit in |             // sure they are all visible. Because of this we also know that all of the columns will always fit in | ||||||
|             // table->WorkRect and therefore in table->InnerRect (because ScrollX is off) |             // table->WorkRect and therefore in table->InnerRect (because ScrollX is off) | ||||||
|             if (!(table->Flags & ImGuiTableFlags_NoKeepColumnsVisible)) |             if (!(table->Flags & ImGuiTableFlags_NoKeepColumnsVisible)) | ||||||
|                 max_x = table->WorkRect.Max.x - (table->ColumnsVisibleCount - (column->IndexWithinVisibleSet + 1)) * min_column_width; |                 max_x = table->WorkRect.Max.x - (table->ColumnsVisibleCount - (column->IndexWithinVisibleSet + 1)) * min_column_width_padded - table->OuterPaddingX; | ||||||
|         } |         } | ||||||
|         if (offset_x + column->WidthGiven > max_x) |         if (offset_x + column->WidthGiven + table->CellPaddingX * 2.0f > max_x) // FIXME-TABLE: CHECK | ||||||
|             column->WidthGiven = ImMax(max_x - offset_x, min_column_width); |             column->WidthGiven = ImMax(max_x - offset_x - table->CellPaddingX * 2.0f, min_column_width); | ||||||
|  |  | ||||||
|         column->MinX = offset_x; |         // Min, Max, Starting positions | ||||||
|         column->MaxX = column->MinX + column->WidthGiven; |         column->MinX = offset_x - table->CellSpacingX1; | ||||||
|  |         column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX2 + table->CellPaddingX * 2.0f; | ||||||
|  |         column->StartX = offset_x + table->CellPaddingX; | ||||||
|  |  | ||||||
|         //// A one pixel padding on the right side makes clipping more noticeable and contents look less cramped. |  | ||||||
|         column->ClipRect.Min.x = column->MinX; |         column->ClipRect.Min.x = column->MinX; | ||||||
|         column->ClipRect.Min.y = work_rect.Min.y; |         column->ClipRect.Min.y = work_rect.Min.y; | ||||||
|         column->ClipRect.Max.x = column->MaxX;// -1.0f; |         column->ClipRect.Max.x = column->MaxX; | ||||||
|         column->ClipRect.Max.y = FLT_MAX; |         column->ClipRect.Max.y = FLT_MAX; | ||||||
|         column->ClipRect.ClipWithFull(host_clip_rect); |         column->ClipRect.ClipWithFull(host_clip_rect); | ||||||
|  |  | ||||||
| @@ -853,8 +862,23 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x) |         if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x) | ||||||
|             table->HoveredColumnBody = (ImS8)column_n; |             table->HoveredColumnBody = (ImS8)column_n; | ||||||
|  |  | ||||||
|         // Starting cursor position |         // [DEBUG] Display overlay | ||||||
|         column->StartX = column->MinX + table->CellPaddingX1; | #if 0 | ||||||
|  |         if (g.IO.KeyShift) | ||||||
|  |         { | ||||||
|  |             // Note that ClipRect should always cover MinX..MaxX (in order to guarantee that draw calls can be merged into parent) | ||||||
|  |             float y1 = table->WorkRect.Min.y; | ||||||
|  |             float y2 = table->WorkRect.Min.y + table->LastOuterHeight; | ||||||
|  |             //GetForegroundDrawList()->AddLine(ImVec2(column->MinX, y1 - 5.0f), ImVec2(column->MinX, y2 + 5.0f), IM_COL32(0, 255, 50, 255)); | ||||||
|  |             //GetForegroundDrawList()->AddLine(ImVec2(column->MaxX, y1 - 5.0f), ImVec2(column->MaxX, y2 + 5.0f), IM_COL32(0, 255, 50, 255)); | ||||||
|  |             //GetForegroundDrawList()->AddRect(ImVec2(column->ClipRect.Min.x, y1), ImVec2(column->ClipRect.Max.x, y2), IM_COL32(255, 0, 0, 255), 0.0f, 0, 1.0f); | ||||||
|  |             //GetForegroundDrawList()->AddRect(ImVec2(column->MinX + table->CellPaddingX, y1), ImVec2(column->MaxX - table->CellPaddingX, y2), IM_COL32(255, 255, 0, 255)); | ||||||
|  |             char buf[128]; | ||||||
|  |             ImFormatString(buf, IM_ARRAYSIZE(buf), "(cont_w)\n%.2f\n(max-min)\n%.2f", column->MaxX - table->CellPaddingX - column->StartX, column->MaxX - column->MinX); | ||||||
|  |             GetForegroundDrawList()->AddRectFilled(ImVec2(column->MinX, y1), ImVec2(column->MaxX, y2), IM_COL32(0, 0, 0, 200)); | ||||||
|  |             GetForegroundDrawList()->AddText(ImVec2(column->StartX, y1), IM_COL32(255, 255, 255, 255), buf); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|         // Alignment |         // Alignment | ||||||
|         // FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in |         // FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in | ||||||
| @@ -866,9 +890,8 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         //    column->StartX = ImLerp(column->StartX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f); |         //    column->StartX = ImLerp(column->StartX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f); | ||||||
|  |  | ||||||
|         // Reset content width variables |         // Reset content width variables | ||||||
|         const float initial_max_pos_x = column->MinX + table->CellPaddingX1; |         column->ContentMaxPosFrozen = column->ContentMaxPosUnfrozen = column->StartX; | ||||||
|         column->ContentMaxPosFrozen = column->ContentMaxPosUnfrozen = initial_max_pos_x; |         column->ContentMaxPosHeadersUsed = column->ContentMaxPosHeadersIdeal = column->StartX; | ||||||
|         column->ContentMaxPosHeadersUsed = column->ContentMaxPosHeadersIdeal = initial_max_pos_x; |  | ||||||
|  |  | ||||||
|         // Don't decrement auto-fit counters until container window got a chance to submit its items |         // Don't decrement auto-fit counters until container window got a chance to submit its items | ||||||
|         if (table->HostSkipItems == false) |         if (table->HostSkipItems == false) | ||||||
| @@ -880,7 +903,7 @@ void    ImGui::TableUpdateLayout(ImGuiTable* table) | |||||||
|         if (visible_n < table->FreezeColumnsCount) |         if (visible_n < table->FreezeColumnsCount) | ||||||
|             host_clip_rect.Min.x = ImMax(host_clip_rect.Min.x, column->MaxX + 2.0f); |             host_clip_rect.Min.x = ImMax(host_clip_rect.Min.x, column->MaxX + 2.0f); | ||||||
|  |  | ||||||
|         offset_x += column->WidthGiven + table->CellSpacingX; |         offset_x += column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; | ||||||
|         visible_n++; |         visible_n++; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1063,7 +1086,7 @@ void    ImGui::EndTable() | |||||||
|         ImGuiTableColumn* column = &table->Columns[column_n]; |         ImGuiTableColumn* column = &table->Columns[column_n]; | ||||||
|  |  | ||||||
|         // Store content width (for both Headers and Rows) |         // Store content width (for both Headers and Rows) | ||||||
|         float ref_x = column->StartX - table->CellPaddingX1; |         float ref_x = column->StartX; | ||||||
|         column->ContentWidthFrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosFrozen - ref_x); |         column->ContentWidthFrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosFrozen - ref_x); | ||||||
|         column->ContentWidthUnfrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosUnfrozen - ref_x); |         column->ContentWidthUnfrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosUnfrozen - ref_x); | ||||||
|         column->ContentWidthHeadersUsed = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersUsed - ref_x); |         column->ContentWidthHeadersUsed = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersUsed - ref_x); | ||||||
| @@ -1081,18 +1104,18 @@ void    ImGui::EndTable() | |||||||
|     table->DrawSplitter.Merge(inner_window->DrawList); |     table->DrawSplitter.Merge(inner_window->DrawList); | ||||||
|  |  | ||||||
|     // When releasing a column being resized, scroll to keep the resulting column in sight |     // When releasing a column being resized, scroll to keep the resulting column in sight | ||||||
|     const float min_column_width = TableGetMinColumnWidth(); |  | ||||||
|     if (!(table->Flags & ImGuiTableFlags_ScrollX) && inner_window != outer_window) |     if (!(table->Flags & ImGuiTableFlags_ScrollX) && inner_window != outer_window) | ||||||
|     { |     { | ||||||
|         inner_window->Scroll.x = 0.0f; |         inner_window->Scroll.x = 0.0f; | ||||||
|     } |     } | ||||||
|     else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceCurrent) |     else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceCurrent) | ||||||
|     { |     { | ||||||
|  |         const float min_column_width_padded = TableGetMinColumnWidth() + table->CellPaddingX * 2.0f; | ||||||
|         ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn]; |         ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn]; | ||||||
|         if (column->MaxX < table->InnerClipRect.Min.x) |         if (column->MaxX < table->InnerClipRect.Min.x) | ||||||
|             SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x - min_column_width, 1.0f); |             SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x - min_column_width_padded, 1.0f); | ||||||
|         else if (column->MaxX > table->InnerClipRect.Max.x) |         else if (column->MaxX > table->InnerClipRect.Max.x) | ||||||
|             SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x + min_column_width, 1.0f); |             SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x + min_column_width_padded, 1.0f); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Apply resizing/dragging at the end of the frame |     // Apply resizing/dragging at the end of the frame | ||||||
| @@ -1100,7 +1123,7 @@ void    ImGui::EndTable() | |||||||
|     { |     { | ||||||
|         ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; |         ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; | ||||||
|         const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); |         const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); | ||||||
|         const float new_width = ImFloor(new_x2 - column->MinX); |         const float new_width = ImFloor(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); | ||||||
|         table->ResizedColumnNextWidth = new_width; |         table->ResizedColumnNextWidth = new_width; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1177,7 +1200,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) | |||||||
|             const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent); |             const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent); | ||||||
|             const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0; |             const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0; | ||||||
|  |  | ||||||
|             if (column->MaxX > table->InnerClipRect.Max.x && !is_resized && is_hovered) |             if (column->MaxX > table->InnerClipRect.Max.x && !is_resized)// && is_hovered) | ||||||
|                 continue; |                 continue; | ||||||
|             if (column->NextVisibleColumn == -1 && !is_resizable) |             if (column->NextVisibleColumn == -1 && !is_resizable) | ||||||
|                 continue; |                 continue; | ||||||
| @@ -1222,6 +1245,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) | |||||||
|         } |         } | ||||||
|         else if (table->Flags & ImGuiTableFlags_BordersOuterV) |         else if (table->Flags & ImGuiTableFlags_BordersOuterV) | ||||||
|         { |         { | ||||||
|  |             // FIXME-TABLE: could use AddRect or explicit VLine/HLine helper? | ||||||
|             outer_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size); |             outer_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size); | ||||||
|             outer_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size); |             outer_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size); | ||||||
|         } |         } | ||||||
| @@ -1234,6 +1258,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) | |||||||
|     if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y) |     if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y) | ||||||
|     { |     { | ||||||
|         // Draw bottom-most row border |         // Draw bottom-most row border | ||||||
|  |         // FIXME-TABLE: could use AddRect or explicit VLine/HLine helper? | ||||||
|         const float border_y = table->RowPosY2; |         const float border_y = table->RowPosY2; | ||||||
|         if (border_y >= table->BackgroundClipRect.Min.y && border_y < table->BackgroundClipRect.Max.y) |         if (border_y >= table->BackgroundClipRect.Min.y && border_y < table->BackgroundClipRect.Max.y) | ||||||
|             inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size); |             inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size); | ||||||
| @@ -1252,7 +1277,7 @@ static void TableUpdateColumnsWeightFromWidth(ImGuiTable* table) | |||||||
|         ImGuiTableColumn* column = &table->Columns[column_n]; |         ImGuiTableColumn* column = &table->Columns[column_n]; | ||||||
|         if (!column->IsVisible || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) |         if (!column->IsVisible || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) | ||||||
|             continue; |             continue; | ||||||
|         visible_weight += column->WidthStretchWeight; |         visible_weight += column->StretchWeight; | ||||||
|         visible_width += column->WidthRequest; |         visible_width += column->WidthRequest; | ||||||
|     } |     } | ||||||
|     IM_ASSERT(visible_weight > 0.0f && visible_width > 0.0f); |     IM_ASSERT(visible_weight > 0.0f && visible_width > 0.0f); | ||||||
| @@ -1263,11 +1288,12 @@ static void TableUpdateColumnsWeightFromWidth(ImGuiTable* table) | |||||||
|         ImGuiTableColumn* column = &table->Columns[column_n]; |         ImGuiTableColumn* column = &table->Columns[column_n]; | ||||||
|         if (!column->IsVisible || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) |         if (!column->IsVisible || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) | ||||||
|             continue; |             continue; | ||||||
|         column->WidthStretchWeight = ((column->WidthRequest + 0.0f) / visible_width) * visible_weight; |         column->StretchWeight = ((column->WidthRequest + 0.0f) / visible_width) * visible_weight; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| // Public wrapper | // Public wrapper | ||||||
|  | // 'width' = inner column width, without padding | ||||||
| void ImGui::TableSetColumnWidth(int column_n, float width) | void ImGui::TableSetColumnWidth(int column_n, float width) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
| @@ -1282,7 +1308,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width) | |||||||
| void ImGui::TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column_0, float column_0_width) | void ImGui::TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column_0, float column_0_width) | ||||||
| { | { | ||||||
|     // Constraints |     // Constraints | ||||||
|     float min_width = TableGetMinColumnWidth(); |     const float min_width = TableGetMinColumnWidth(); | ||||||
|     float max_width_0 = FLT_MAX; |     float max_width_0 = FLT_MAX; | ||||||
|     if (!(table->Flags & ImGuiTableFlags_ScrollX)) |     if (!(table->Flags & ImGuiTableFlags_ScrollX)) | ||||||
|         max_width_0 = (table->WorkRect.Max.x - column_0->MinX) - (table->ColumnsVisibleCount - (column_0->IndexWithinVisibleSet + 1)) * min_width; |         max_width_0 = (table->WorkRect.Max.x - column_0->MinX) - (table->ColumnsVisibleCount - (column_0->IndexWithinVisibleSet + 1)) * min_width; | ||||||
| @@ -1431,7 +1457,7 @@ void    ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table) | |||||||
|                     width_contents = ImMax(column->ContentWidthFrozen, column->ContentWidthHeadersUsed); |                     width_contents = ImMax(column->ContentWidthFrozen, column->ContentWidthHeadersUsed); | ||||||
|                 else                                // Row freeze: use width after freeze |                 else                                // Row freeze: use width after freeze | ||||||
|                     width_contents = column->ContentWidthUnfrozen; |                     width_contents = column->ContentWidthUnfrozen; | ||||||
|                 if (width_contents > column->WidthGiven) |                 if (width_contents > column->WidthGiven + table->CellPaddingX * 1.0f) | ||||||
|                     continue; |                     continue; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -1537,12 +1563,12 @@ void    ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| // We use a default parameter of 'init_width_or_weight == -1' | // We use a default parameter of 'init_width_or_weight == -1', | ||||||
| //  ImGuiTableColumnFlags_WidthFixed,    width  <= 0 --> init width == auto | // - with ImGuiTableColumnFlags_WidthFixed,    width  <= 0 --> init width == auto | ||||||
| //  ImGuiTableColumnFlags_WidthFixed,    width  >  0 --> init width == manual | // - with ImGuiTableColumnFlags_WidthFixed,    width  >  0 --> init width == manual | ||||||
| //  ImGuiTableColumnFlags_WidthStretch,  weight <  0 --> init weight == 1.0f | // - with ImGuiTableColumnFlags_WidthStretch,  weight <  0 --> init weight == 1.0f | ||||||
| //  ImGuiTableColumnFlags_WidthStretch,  weight >= 0 --> init weight == custom | // - with ImGuiTableColumnFlags_WidthStretch,  weight >= 0 --> init weight == custom | ||||||
| // Use a different API? | // Widths are specified _without_ CellPadding. So if you specify a width of 100.0f the column will be 100.0f+Padding*2.0f and you can fit a 100.0-wide item in it. | ||||||
| void    ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) | void    ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
| @@ -1573,8 +1599,8 @@ void    ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, | |||||||
|         if (init_width_or_weight < 0.0f) |         if (init_width_or_weight < 0.0f) | ||||||
|             init_width_or_weight = 1.0f; |             init_width_or_weight = 1.0f; | ||||||
|     } |     } | ||||||
|     column->WidthOrWeightInitValue = init_width_or_weight; |     column->InitStretchWeightOrWidth = init_width_or_weight; | ||||||
|     if (table->IsInitializing && column->WidthRequest < 0.0f && column->WidthStretchWeight < 0.0f) |     if (table->IsInitializing && column->WidthRequest < 0.0f && column->StretchWeight < 0.0f) | ||||||
|     { |     { | ||||||
|         // Init width or weight |         // Init width or weight | ||||||
|         if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) |         if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) | ||||||
| @@ -1584,9 +1610,9 @@ void    ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, | |||||||
|             column->AutoFitQueue = 0x00; |             column->AutoFitQueue = 0x00; | ||||||
|         } |         } | ||||||
|         if (flags & ImGuiTableColumnFlags_WidthStretch) |         if (flags & ImGuiTableColumnFlags_WidthStretch) | ||||||
|             column->WidthStretchWeight = init_width_or_weight; |             column->StretchWeight = init_width_or_weight; | ||||||
|         else |         else | ||||||
|             column->WidthStretchWeight = 1.0f; |             column->StretchWeight = 1.0f; | ||||||
|     } |     } | ||||||
|     if (table->IsInitializing) |     if (table->IsInitializing) | ||||||
|     { |     { | ||||||
| @@ -1740,10 +1766,9 @@ void    ImGui::TableEndRow(ImGuiTable* table) | |||||||
|             ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCurrent]; |             ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCurrent]; | ||||||
|             for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++) |             for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++) | ||||||
|             { |             { | ||||||
|                 ImGuiTableColumn* column = &table->Columns[cell_data->Column]; |                 ImRect cell_bg_rect = TableGetCellBgRect(table, cell_data->Column); | ||||||
|                 ImRect cell_rect(column->MinX - table->CellSpacingX, bg_y1, column->MaxX, bg_y2); // FIXME-TABLE: Padding currently wrong until we finish the padding refactor |                 cell_bg_rect.ClipWith(table->BackgroundClipRect); | ||||||
|                 cell_rect.ClipWith(table->BackgroundClipRect); |                 window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); | ||||||
|                 window->DrawList->AddRectFilled(cell_rect.Min, cell_rect.Max, cell_data->BgColor); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -1820,8 +1845,8 @@ void    ImGui::TableBeginCell(ImGuiTable* table, int column_n) | |||||||
|     window->DC.NavLayerCurrent = column->NavLayerCurrent; |     window->DC.NavLayerCurrent = column->NavLayerCurrent; | ||||||
|  |  | ||||||
|     window->WorkRect.Min.y = window->DC.CursorPos.y; |     window->WorkRect.Min.y = window->DC.CursorPos.y; | ||||||
|     window->WorkRect.Min.x = column->MinX + table->CellPaddingX1; |     window->WorkRect.Min.x = column->MinX + table->CellPaddingX + table->CellSpacingX1; | ||||||
|     window->WorkRect.Max.x = column->MaxX - table->CellPaddingX2; |     window->WorkRect.Max.x = column->MaxX - table->CellPaddingX - table->CellSpacingX2; | ||||||
|  |  | ||||||
|     // To allow ImGuiListClipper to function we propagate our row height |     // To allow ImGuiListClipper to function we propagate our row height | ||||||
|     if (!column->IsVisible) |     if (!column->IsVisible) | ||||||
| @@ -1950,14 +1975,20 @@ int     ImGui::TableGetColumnIndex() | |||||||
| } | } | ||||||
|  |  | ||||||
| // Return the cell rectangle based on currently known height. | // Return the cell rectangle based on currently known height. | ||||||
| // Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations. | // - Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations. | ||||||
| //   The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it. | //   The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it. | ||||||
| ImRect  ImGui::TableGetCellBgRect() | // - Important: if ImGuiTableFlags_PadOuterX is set but ImGuiTableFlags_PadInnerX is not set, the outer-most left and right | ||||||
|  | //   columns report a small offset so their CellBgRect can extend up to the outer border. | ||||||
|  | ImRect  ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     const ImGuiTableColumn* column = &table->Columns[column_n]; | ||||||
|     ImGuiTable* table = g.CurrentTable; |     float x1 = column->MinX; | ||||||
|     ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; |     float x2 = column->MaxX; | ||||||
|     return ImRect(column->MinX, table->RowPosY1, column->MaxX, table->RowPosY2); |     if (column->PrevVisibleColumn == -1) | ||||||
|  |         x1 -= table->CellSpacingX1; | ||||||
|  |     if (column->NextVisibleColumn == -1) | ||||||
|  |         x2 += table->CellSpacingX2; | ||||||
|  |     return ImRect(x1, table->RowPosY1, x2, table->RowPosY2); | ||||||
| } | } | ||||||
|  |  | ||||||
| const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n) | const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n) | ||||||
| @@ -2206,12 +2237,10 @@ void    ImGui::TableHeader(const char* label) | |||||||
|     ImVec2 label_pos = window->DC.CursorPos; |     ImVec2 label_pos = window->DC.CursorPos; | ||||||
|  |  | ||||||
|     // If we already got a row height, there's use that. |     // If we already got a row height, there's use that. | ||||||
|     ImRect cell_r = TableGetCellBgRect(); |     // FIXME-TABLE-PADDING: Problem if the correct outer-padding CellBgRect strays off our ClipRect | ||||||
|     cell_r.Min.x -= table->CellSpacingX; // FIXME-TABLE: TableGetCellRect() is misleading. |     ImRect cell_r = TableGetCellBgRect(table, column_n); | ||||||
|     float label_height = ImMax(label_size.y, table->RowMinHeight - g.Style.CellPadding.y * 2.0f); |     float label_height = ImMax(label_size.y, table->RowMinHeight - g.Style.CellPadding.y * 2.0f); | ||||||
|  |  | ||||||
|     //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] |  | ||||||
|  |  | ||||||
|     // Keep header highlighted when context menu is open. |     // Keep header highlighted when context menu is open. | ||||||
|     // (FIXME-TABLE: however we cannot assume the ID of said popup if it has been created by the user...) |     // (FIXME-TABLE: however we cannot assume the ID of said popup if it has been created by the user...) | ||||||
|     const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent); |     const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent); | ||||||
| @@ -2221,12 +2250,16 @@ void    ImGui::TableHeader(const char* label) | |||||||
|     if (!ItemAdd(bb, id)) |     if (!ItemAdd(bb, id)) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|  |     //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] | ||||||
|  |     //GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] | ||||||
|  |  | ||||||
|     bool hovered, held; |     bool hovered, held; | ||||||
|     bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None); |     bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None); | ||||||
|     if (hovered || selected) |     if (hovered || selected) | ||||||
|     { |     { | ||||||
|         const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); |         const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); | ||||||
|         RenderFrame(bb.Min, bb.Max, col, false, 0.0f); |         //RenderFrame(bb.Min, bb.Max, col, false, 0.0f); | ||||||
|  |         TableSetBgColor(ImGuiTableBgTarget_CellBg, col, table->CurrentColumn); | ||||||
|         RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); |         RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); | ||||||
|     } |     } | ||||||
|     if (held) |     if (held) | ||||||
| @@ -2611,7 +2644,7 @@ void ImGui::TableSaveSettings(ImGuiTable* table) | |||||||
|     settings->SaveFlags = ImGuiTableFlags_None; |     settings->SaveFlags = ImGuiTableFlags_None; | ||||||
|     for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++) |     for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++) | ||||||
|     { |     { | ||||||
|         const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->WidthStretchWeight : column->WidthRequest; |         const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->StretchWeight : column->WidthRequest; | ||||||
|         column_settings->WidthOrWeight = width_or_weight; |         column_settings->WidthOrWeight = width_or_weight; | ||||||
|         column_settings->Index = (ImS8)n; |         column_settings->Index = (ImS8)n; | ||||||
|         column_settings->DisplayOrder = column->DisplayOrder; |         column_settings->DisplayOrder = column->DisplayOrder; | ||||||
| @@ -2623,9 +2656,9 @@ void ImGui::TableSaveSettings(ImGuiTable* table) | |||||||
|             save_ref_scale = true; |             save_ref_scale = true; | ||||||
|  |  | ||||||
|         // We skip saving some data in the .ini file when they are unnecessary to restore our state. |         // We skip saving some data in the .ini file when they are unnecessary to restore our state. | ||||||
|         // Note that fixed width where initial width was derived from auto-fit will always be saved as WidthOrWeightInitValue will be 0.0f. |         // Note that fixed width where initial width was derived from auto-fit will always be saved as InitStretchWeightOrWidth will be 0.0f. | ||||||
|         // FIXME-TABLE: We don't have logic to easily compare SortOrder to DefaultSortOrder yet so it's always saved when present. |         // FIXME-TABLE: We don't have logic to easily compare SortOrder to DefaultSortOrder yet so it's always saved when present. | ||||||
|         if (width_or_weight != column->WidthOrWeightInitValue) |         if (width_or_weight != column->InitStretchWeightOrWidth) | ||||||
|             settings->SaveFlags |= ImGuiTableFlags_Resizable; |             settings->SaveFlags |= ImGuiTableFlags_Resizable; | ||||||
|         if (column->DisplayOrder != n) |         if (column->DisplayOrder != n) | ||||||
|             settings->SaveFlags |= ImGuiTableFlags_Reorderable; |             settings->SaveFlags |= ImGuiTableFlags_Reorderable; | ||||||
| @@ -2678,7 +2711,7 @@ void ImGui::TableLoadSettings(ImGuiTable* table) | |||||||
|         if (settings->SaveFlags & ImGuiTableFlags_Resizable) |         if (settings->SaveFlags & ImGuiTableFlags_Resizable) | ||||||
|         { |         { | ||||||
|             if (column_settings->IsStretch) |             if (column_settings->IsStretch) | ||||||
|                 column->WidthStretchWeight = column_settings->WidthOrWeight; |                 column->StretchWeight = column_settings->WidthOrWeight; | ||||||
|             else |             else | ||||||
|                 column->WidthRequest = column_settings->WidthOrWeight; |                 column->WidthRequest = column_settings->WidthOrWeight; | ||||||
|             column->AutoFitQueue = 0x00; |             column->AutoFitQueue = 0x00; | ||||||
| @@ -2824,7 +2857,7 @@ void    ImGui::TableSettingsInstallHandler(ImGuiContext* context) | |||||||
|  |  | ||||||
| void ImGui::DebugNodeTable(ImGuiTable* table) | void ImGui::DebugNodeTable(ImGuiTable* table) | ||||||
| { | { | ||||||
|     char buf[256]; |     char buf[512]; | ||||||
|     char* p = buf; |     char* p = buf; | ||||||
|     const char* buf_end = buf + IM_ARRAYSIZE(buf); |     const char* buf_end = buf + IM_ARRAYSIZE(buf); | ||||||
|     const bool is_active = (table->LastFrameActive >= ImGui::GetFrameCount() - 2); |     const bool is_active = (table->LastFrameActive >= ImGui::GetFrameCount() - 2); | ||||||
| @@ -2839,21 +2872,23 @@ void ImGui::DebugNodeTable(ImGuiTable* table) | |||||||
|     BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f)", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight()); |     BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f)", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight()); | ||||||
|     BulletText("InnerWidth: %.1f%s", table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); |     BulletText("InnerWidth: %.1f%s", table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); | ||||||
|     BulletText("ColumnsWidth: %.1f, AutoFitWidth: %.1f", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth); |     BulletText("ColumnsWidth: %.1f, AutoFitWidth: %.1f", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth); | ||||||
|  |     BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", table->CellPaddingX, table->CellSpacingX1, table->CellSpacingX2, table->OuterPaddingX); | ||||||
|     BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder); |     BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder); | ||||||
|     BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn); |     BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn); | ||||||
|     for (int n = 0; n < table->ColumnsCount; n++) |     for (int n = 0; n < table->ColumnsCount; n++) | ||||||
|     { |     { | ||||||
|         ImGuiTableColumn* column = &table->Columns[n]; |         ImGuiTableColumn* column = &table->Columns[n]; | ||||||
|         const char* name = TableGetColumnName(table, n); |         const char* name = TableGetColumnName(table, n); | ||||||
|         BulletText("Column %d order %d name '%s': +%.1f to +%.1f\n" |         ImFormatString(buf, IM_ARRAYSIZE(buf), | ||||||
|  |             "Column %d order %d name '%s': +%.1f to +%.1f\n" | ||||||
|             "Visible: %d, Clipped: %d, DrawChannels: %d,%d\n" |             "Visible: %d, Clipped: %d, DrawChannels: %d,%d\n" | ||||||
|             "WidthGiven/Request: %.2f/%.2f, WidthWeight: %.3f\n" |             "WidthGiven: %.2f, Request/Auto: %.2f/%.2f, StretchWeight: %.3f\n" | ||||||
|             "ContentWidth: Frozen %d, Unfrozen %d, HeadersUsed/Ideal %d/%d\n" |             "ContentWidth: Frozen %d, Unfrozen %d, HeadersUsed/Ideal %d/%d\n" | ||||||
|             "SortOrder: %d, SortDir: %s\n" |             "SortOrder: %d, SortDir: %s\n" | ||||||
|             "UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..", |             "UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..", | ||||||
|             n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, |             n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, | ||||||
|             column->IsVisible, column->IsClipped, column->DrawChannelFrozen, column->DrawChannelUnfrozen, |             column->IsVisible, column->IsClipped, column->DrawChannelFrozen, column->DrawChannelUnfrozen, | ||||||
|             column->WidthGiven, column->WidthRequest, column->WidthStretchWeight, |             column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, | ||||||
|             column->ContentWidthFrozen, column->ContentWidthUnfrozen, column->ContentWidthHeadersUsed, column->ContentWidthHeadersIdeal, |             column->ContentWidthFrozen, column->ContentWidthUnfrozen, column->ContentWidthHeadersUsed, column->ContentWidthHeadersIdeal, | ||||||
|             column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? "Ascending" : (column->SortDirection == ImGuiSortDirection_Descending) ? "Descending" : "None", |             column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? "Ascending" : (column->SortDirection == ImGuiSortDirection_Descending) ? "Descending" : "None", | ||||||
|             column->UserID, column->Flags, |             column->UserID, column->Flags, | ||||||
| @@ -2861,6 +2896,13 @@ void ImGui::DebugNodeTable(ImGuiTable* table) | |||||||
|             (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "", |             (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "", | ||||||
|             (column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) ? "WidthAlwaysAutoResize " : "", |             (column->Flags & ImGuiTableColumnFlags_WidthAlwaysAutoResize) ? "WidthAlwaysAutoResize " : "", | ||||||
|             (column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : ""); |             (column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : ""); | ||||||
|  |         Bullet(); | ||||||
|  |         Selectable(buf); | ||||||
|  |         if (IsItemHovered()) | ||||||
|  |         { | ||||||
|  |             ImRect r(column->MinX, table->OuterRect.Min.y, column->MaxX, table->OuterRect.Max.y); | ||||||
|  |             GetForegroundDrawList()->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255)); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     if (ImGuiTableSettings* settings = TableGetBoundSettings(table)) |     if (ImGuiTableSettings* settings = TableGetBoundSettings(table)) | ||||||
|         DebugNodeTableSettings(settings); |         DebugNodeTableSettings(settings); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut