mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Tables: simplified and tidying up TableSetColumnWidth(), fixes resizing a fixed column surrounded by stretch column (manually or via auto-fit menu). TableHeader() showing highlighted when held.
This commit is contained in:
		
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1050,7 +1050,7 @@ enum ImGuiTabItemFlags_ | ||||
| //    - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable(). | ||||
| // - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions. | ||||
| //   (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized). | ||||
| //   The typical use of mixing sizing policies is to have ScrollX disabled, one or two Stretch Column and many Fixed Columns. | ||||
| //   The typical use of mixing sizing policies is to have ScrollX disabled, first Fixed columns and then one or two TRAILING Stretch columns. | ||||
| enum ImGuiTableFlags_ | ||||
| { | ||||
|     // Features | ||||
|   | ||||
| @@ -1876,6 +1876,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width) | ||||
|     if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width) | ||||
|         return; | ||||
|  | ||||
|     //IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthGiven, column_0_width); | ||||
|     ImGuiTableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &table->Columns[column_0->NextEnabledColumn] : NULL; | ||||
|  | ||||
|     // In this surprisingly not simple because of how we support mixing Fixed and multiple Stretch columns. | ||||
| @@ -1897,66 +1898,44 @@ void ImGui::TableSetColumnWidth(int column_n, float width) | ||||
|     // - W1 F2 F3  resize from F3|          --> ok: no-op (disabled by Resize Rule 1) | ||||
|     // - W1 F2     resize from F2|          --> ok: no-op (disabled by Resize Rule 1) | ||||
|     // - W1 W2 F3  resize from W1| or W2|   --> ok | ||||
|     // - W1 F2 W3  resize from W1| or F2|   --> FIXME | ||||
|     // - W1 F2 W3  resize from W1| or F2|   --> ok | ||||
|     // - F1 W2 F3  resize from W2|          --> ok | ||||
|     // - F1 W3 F2  resize from W3|          --> ok | ||||
|     // - W1 F2 F3  resize from W1|          --> ok: equivalent to resizing |F2. F3 will not move. (forwarded by Resize Rule 2) | ||||
|     // - W1 F2 F3  resize from W1|          --> ok: equivalent to resizing |F2. F3 will not move. | ||||
|     // - W1 F2 F3  resize from F2|          --> ok | ||||
|     // All resizes from a Wx columns are locking other columns. | ||||
|  | ||||
|     // Possible improvements: | ||||
|     // - W1 W2 W3  resize W1|               --> to not be stuck, both W2 and W3 would stretch down. Seems possible to fix. Would be most beneficial to simplify resize of all-weighted columns. | ||||
|     // - W1 F2 W3  resize W1| or F2|        --> symmetrical resize is weird and glitchy. Seems possible to fix. | ||||
|     // - W3 F1 F2  resize W3|               --> to not be stuck past F1|, both F1 and F2 would need to stretch down, which would be lossy or ambiguous. Seems hard to fix. | ||||
|  | ||||
|     // Rules: | ||||
|     // - [Resize Rule 1] Can't resize from right of right-most visible column if there is any Stretch column. Implemented in TableUpdateLayout(). | ||||
|     // - [Resize Rule 2] Resizing from right-side of a Stretch column before a fixed column forward sizing to left-side of fixed column. | ||||
|     // - [Resize Rule 3] If we are are followed by a fixed column and we have a Stretch column before, we need to ensure that our left border won't move. | ||||
|     table->IsSettingsDirty = true; | ||||
|     // [Resize Rule 1] Can't resize from right of right-most visible column if there is any Stretch column. Implemented in TableUpdateLayout(). | ||||
|  | ||||
|     // If we have all Fixed columns OR resizing a Fixed column that doesn't come after a Stretch one, we can do an offsetting resize. | ||||
|     // This is the preferred resize path | ||||
|     if (column_0->Flags & ImGuiTableColumnFlags_WidthFixed) | ||||
|         if (!column_1 || table->LeftMostStretchedColumn == -1 || table->Columns[table->LeftMostStretchedColumn].DisplayOrder >= column_0->DisplayOrder) | ||||
|         { | ||||
|         // [Resize Rule 3] If we are are followed by a fixed column and we have a Stretch column before, we need to ensure | ||||
|         // that our left border won't move, which we can do by making sure column_a/column_b resizes cancels each others. | ||||
|         if (column_1 && (column_1->Flags & ImGuiTableColumnFlags_WidthFixed)) | ||||
|             if (table->LeftMostStretchedColumn != -1 && table->Columns[table->LeftMostStretchedColumn].DisplayOrder < column_0->DisplayOrder) | ||||
|             { | ||||
|                 // (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b) | ||||
|                 float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width); | ||||
|                 column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width; | ||||
|                 column_1->WidthRequest = column_1_width; | ||||
|             column_0->WidthRequest = column_0_width; | ||||
|             table->IsSettingsDirty = true; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Apply | ||||
|         //IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthRequested, column_0_width); | ||||
|         column_0->WidthRequest = column_0_width; | ||||
|     } | ||||
|     else if (column_0->Flags & ImGuiTableColumnFlags_WidthStretch) | ||||
|     { | ||||
|     // We can also use previous column if there's no next one (this is used when doing an auto-fit on the right-most stretch column) | ||||
|     if (column_1 == NULL) | ||||
|         column_1 = (column_0->PrevEnabledColumn != -1) ? &table->Columns[column_0->PrevEnabledColumn] : NULL; | ||||
|     if (column_1 == NULL) | ||||
|         return; | ||||
|  | ||||
|         if (column_1->Flags & ImGuiTableColumnFlags_WidthFixed) | ||||
|         { | ||||
|             // [Resize Rule 2] | ||||
|             float off = (column_0->WidthGiven - column_0_width); | ||||
|             float column_1_width = column_1->WidthGiven + off; | ||||
|             column_1->WidthRequest = ImMax(min_width, column_1_width); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // At this point column_1 is the next OR previous column and we know it is a stretch column. | ||||
|     // Resizing from right-side of a Stretch column before a Fixed column forward sizing to left-side of fixed column. | ||||
|     // (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b) | ||||
|     float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width); | ||||
|     column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width; | ||||
|             column_1->WidthRequest = column_1_width; | ||||
|     column_0->WidthRequest = column_0_width; | ||||
|     column_1->WidthRequest = column_1_width; | ||||
|     if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch) | ||||
|         TableUpdateColumnsWeightFromWidth(table); | ||||
|         } | ||||
|     } | ||||
|     table->IsSettingsDirty = true; | ||||
| } | ||||
|  | ||||
| // Disable clipping then auto-fit, will take 2 frames | ||||
| @@ -2715,7 +2694,7 @@ void ImGui::TableHeader(const char* label) | ||||
|     bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap); | ||||
|     if (g.ActiveId != id) | ||||
|         SetItemAllowOverlap(); | ||||
|     if (hovered || selected) | ||||
|     if (held || hovered || selected) | ||||
|     { | ||||
|         const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); | ||||
|         //RenderFrame(bb.Min, bb.Max, col, false, 0.0f); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user