Process hit-testing on resizing borders. Actual size change will be applied in EndTable() - Set table->HoveredColumnBorder with a short delay/timer to reduce visual feedback noise.
| 1283 | // Process hit-testing on resizing borders. Actual size change will be applied in EndTable() |
| 1284 | // - Set table->HoveredColumnBorder with a short delay/timer to reduce visual feedback noise. |
| 1285 | void ImGui::TableUpdateBorders(ImGuiTable* table) |
| 1286 | { |
| 1287 | ImGuiContext& g = *GImGui; |
| 1288 | IM_ASSERT(table->Flags & ImGuiTableFlags_Resizable); |
| 1289 | |
| 1290 | // At this point OuterRect height may be zero or under actual final height, so we rely on temporal coherency and |
| 1291 | // use the final height from last frame. Because this is only affecting _interaction_ with columns, it is not |
| 1292 | // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). |
| 1293 | // Actual columns highlight/render will be performed in EndTable() and not be affected. |
| 1294 | ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); |
| 1295 | const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale); |
| 1296 | const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight; |
| 1297 | const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight); |
| 1298 | const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight; |
| 1299 | |
| 1300 | for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |
| 1301 | { |
| 1302 | if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) |
| 1303 | continue; |
| 1304 | |
| 1305 | const int column_n = table->DisplayOrderToIndex[order_n]; |
| 1306 | ImGuiTableColumn* column = &table->Columns[column_n]; |
| 1307 | if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) |
| 1308 | continue; |
| 1309 | |
| 1310 | // ImGuiTableFlags_NoBordersInBodyUntilResize will be honored in TableDrawBorders() |
| 1311 | const float border_y2_hit = (table->Flags & ImGuiTableFlags_NoBordersInBody) ? hit_y2_head : hit_y2_body; |
| 1312 | if ((table->Flags & ImGuiTableFlags_NoBordersInBody) && table->IsUsingHeaders == false) |
| 1313 | continue; |
| 1314 | |
| 1315 | if (!column->IsVisibleX && table->LastResizedColumn != column_n) |
| 1316 | continue; |
| 1317 | |
| 1318 | ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent); |
| 1319 | ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit); |
| 1320 | ItemAdd(hit_rect, column_id, NULL, ImGuiItemFlags_NoNav); |
| 1321 | //GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100)); |
| 1322 | |
| 1323 | bool hovered = false, held = false; |
| 1324 | bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus); |
| 1325 | if (pressed && IsMouseDoubleClicked(0)) |
| 1326 | { |
| 1327 | TableSetColumnWidthAutoSingle(table, column_n); |
| 1328 | ClearActiveID(); |
| 1329 | held = false; |
| 1330 | } |
| 1331 | if (held) |
| 1332 | { |
| 1333 | if (table->LastResizedColumn == -1) |
| 1334 | table->ResizeLockMinContentsX2 = table->RightMostEnabledColumn != -1 ? table->Columns[table->RightMostEnabledColumn].MaxX : -FLT_MAX; |
| 1335 | table->ResizedColumn = (ImGuiTableColumnIdx)column_n; |
| 1336 | table->InstanceInteracted = table->InstanceCurrent; |
| 1337 | } |
| 1338 | if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held) |
| 1339 | { |
| 1340 | table->HoveredColumnBorder = (ImGuiTableColumnIdx)column_n; |
| 1341 | SetMouseCursor(ImGuiMouseCursor_ResizeEW); |
| 1342 | } |
nothing calls this directly
no test coverage detected