A game about forced loneliness, made by TACStudios
at master 534 lines 16 kB view raw
1using System.Collections.Generic; 2 3using UnityEditor.IMGUI.Controls; 4using UnityEngine; 5 6using Codice.Client.Commands; 7using Codice.Client.Common; 8using Codice.CM.Common; 9using Codice.Utils; 10using PlasticGui; 11using PlasticGui.WorkspaceWindow.Diff; 12using Unity.PlasticSCM.Editor.UI; 13using Unity.PlasticSCM.Editor.UI.Tree; 14 15namespace Unity.PlasticSCM.Editor.Views.Diff 16{ 17 internal class DiffTreeView : PlasticTreeView 18 { 19 internal DiffTreeView(DiffTreeViewMenu menu) 20 { 21 mMenu = menu; 22 23 customFoldoutYOffset = UnityConstants.TREEVIEW_FOLDOUT_Y_OFFSET; 24 25 mCooldownFilterAction = new CooldownWindowDelayer( 26 DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL); 27 28 EnableHorizontalScrollbar(); 29 } 30 31 public override void OnGUI(Rect rect) 32 { 33 base.OnGUI(rect); 34 35 Event e = Event.current; 36 37 if (e.type != EventType.KeyDown) 38 return; 39 40 bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e); 41 42 if (isProcessed) 43 e.Use(); 44 } 45 46 protected override bool CanChangeExpandedState(TreeViewItem item) 47 { 48 return item is ChangeCategoryTreeViewItem 49 || item is MergeCategoryTreeViewItem; 50 } 51 52 protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem) 53 { 54 try 55 { 56 RegenerateRows( 57 mDiffTree, 58 mTreeViewItemIds, 59 this, 60 rootItem, 61 mRows, 62 mExpandCategories); 63 } 64 finally 65 { 66 mExpandCategories = false; 67 } 68 69 return mRows; 70 } 71 72 protected override void CommandEventHandling() 73 { 74 // NOTE - empty override to prevent crash when pressing ctrl-a in the treeview 75 } 76 77 protected override void SearchChanged(string newSearch) 78 { 79 mCooldownFilterAction.Ping(); 80 } 81 82 protected override void ContextClickedItem(int id) 83 { 84 mMenu.Popup(); 85 Repaint(); 86 } 87 88 protected override void RowGUI(RowGUIArgs args) 89 { 90 float itemWidth; 91 TreeViewItemGUI( 92 args.item, args.rowRect, rowHeight, mDiffTree, args.selected, args.focused, out itemWidth); 93 94 float rowWidth = baseIndent + args.item.depth * depthIndentWidth + 95 itemWidth + UnityConstants.TREEVIEW_ROW_WIDTH_OFFSET; 96 97 if (rowWidth > mLargestRowWidth) 98 mLargestRowWidth = rowWidth; 99 } 100 101 protected override void AfterRowsGUI() 102 { 103 if (mHorizontalColumn != null) 104 mHorizontalColumn.width = mLargestRowWidth; 105 106 base.AfterRowsGUI(); 107 } 108 109 internal void ClearModel() 110 { 111 mTreeViewItemIds.Clear(); 112 113 mDiffTree = new UnityDiffTree(); 114 } 115 116 internal void BuildModel( 117 WorkspaceInfo wkInfo, 118 List<ClientDiff> diffs, 119 BranchResolver brResolver, 120 bool skipMergeTracking) 121 { 122 mTreeViewItemIds.Clear(); 123 124 mDiffTree.BuildCategories(wkInfo, diffs, brResolver, skipMergeTracking); 125 } 126 127 internal void Refilter() 128 { 129 Filter filter = new Filter(searchString); 130 mDiffTree.Filter(filter, ColumnsNames); 131 132 mExpandCategories = true; 133 } 134 135 internal void Sort() 136 { 137 mDiffTree.Sort( 138 PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn), 139 sortAscending: true); 140 } 141 142 internal ClientDiffInfo GetMetaDiff(ClientDiffInfo diff) 143 { 144 return mDiffTree.GetMetaDiff(diff); 145 } 146 147 internal bool SelectionHasMeta() 148 { 149 if (!HasSelection()) 150 return false; 151 152 ClientDiffInfo selectedDiff = GetSelectedDiffs(false)[0]; 153 154 if (selectedDiff == null) 155 return false; 156 157 return mDiffTree.HasMeta(selectedDiff); 158 } 159 160 internal List<ClientDiffInfo> GetSelectedDiffs(bool includeMetaFiles) 161 { 162 List<ClientDiffInfo> result = new List<ClientDiffInfo>(); 163 164 IList<int> selectedIds = GetSelection(); 165 166 if (selectedIds.Count == 0) 167 return result; 168 169 foreach (KeyValuePair<ITreeViewNode, int> item 170 in mTreeViewItemIds.GetInfoItems()) 171 { 172 if (!selectedIds.Contains(item.Value)) 173 continue; 174 175 if (!(item.Key is ClientDiffInfo)) 176 continue; 177 178 result.Add((ClientDiffInfo)item.Key); 179 } 180 181 if (includeMetaFiles) 182 mDiffTree.FillWithMeta(result); 183 184 return result; 185 } 186 187 void DelayedSearchChanged() 188 { 189 Refilter(); 190 191 Sort(); 192 193 Reload(); 194 195 TableViewOperations.ScrollToSelection(this); 196 } 197 198 void EnableHorizontalScrollbar() 199 { 200 mHorizontalColumn = new MultiColumnHeaderState.Column(); 201 mHorizontalColumn.autoResize = false; 202 203 MultiColumnHeaderState.Column[] cols = { mHorizontalColumn }; 204 MultiColumnHeaderState headerState = new MultiColumnHeaderState(cols); 205 206 multiColumnHeader = new MultiColumnHeader(headerState); 207 multiColumnHeader.height = 0f; 208 } 209 210 static void RegenerateRows( 211 UnityDiffTree diffTree, 212 TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds, 213 TreeView treeView, 214 TreeViewItem rootItem, 215 List<TreeViewItem> rows, 216 bool expandCategories) 217 { 218 ClearRows(rootItem, rows); 219 220 List<IDiffCategory> categories = diffTree.GetNodes(); 221 222 if (categories == null) 223 return; 224 225 foreach (IDiffCategory category in categories) 226 { 227 if (category is CategoryGroup && 228 ((CategoryGroup)category).CategoryType == CategoryGroup.Type.MergeCategory) 229 { 230 AddMergeCategory( 231 rootItem, 232 category, 233 rows, 234 treeViewItemIds, 235 treeView, 236 expandCategories); 237 } 238 239 if (category is ChangeCategory) 240 { 241 AddChangeCategory( 242 rootItem, 243 category, 244 rows, 245 treeViewItemIds, 246 treeView, 247 expandCategories); 248 } 249 } 250 251 if (!expandCategories) 252 return; 253 254 treeView.state.expandedIDs = treeViewItemIds.GetCategoryIds(); 255 } 256 257 static void ClearRows( 258 TreeViewItem rootItem, 259 List<TreeViewItem> rows) 260 { 261 if (rootItem.hasChildren) 262 rootItem.children.Clear(); 263 264 rows.Clear(); 265 } 266 267 static void AddMergeCategory( 268 TreeViewItem rootItem, 269 IDiffCategory category, 270 List<TreeViewItem> rows, 271 TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds, 272 TreeView treeView, 273 bool expandCategories) 274 { 275 int categoryId; 276 if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId)) 277 categoryId = treeViewItemIds.AddCategoryItem(category); 278 279 MergeCategoryTreeViewItem mergeCategoryTreeViewItem = 280 new MergeCategoryTreeViewItem( 281 categoryId, 282 rootItem.depth + 1, 283 (CategoryGroup)category); 284 285 rootItem.AddChild(mergeCategoryTreeViewItem); 286 rows.Add(mergeCategoryTreeViewItem); 287 288 if (!expandCategories && 289 !treeView.IsExpanded(mergeCategoryTreeViewItem.id)) 290 return; 291 292 for (int i = 0; i < category.GetChildrenCount(); i++) 293 { 294 IDiffCategory child = (IDiffCategory)((ITreeViewNode)category) 295 .GetChild(i); 296 297 AddChangeCategory( 298 mergeCategoryTreeViewItem, 299 child, 300 rows, 301 treeViewItemIds, 302 treeView, 303 expandCategories); 304 } 305 } 306 307 static void AddChangeCategory( 308 TreeViewItem parentItem, 309 IDiffCategory category, 310 List<TreeViewItem> rows, 311 TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds, 312 TreeView treeView, 313 bool expandCategories) 314 { 315 int categoryId; 316 if (!treeViewItemIds.TryGetCategoryItemId(category, out categoryId)) 317 categoryId = treeViewItemIds.AddCategoryItem(category); 318 319 ChangeCategoryTreeViewItem changeCategoryTreeViewItem = 320 new ChangeCategoryTreeViewItem( 321 categoryId, 322 parentItem.depth + 1, 323 (ChangeCategory)category); 324 325 parentItem.AddChild(changeCategoryTreeViewItem); 326 rows.Add(changeCategoryTreeViewItem); 327 328 if (!expandCategories && 329 !treeView.IsExpanded(changeCategoryTreeViewItem.id)) 330 return; 331 332 AddClientDiffs( 333 changeCategoryTreeViewItem, 334 (ITreeViewNode)category, 335 rows, 336 treeViewItemIds); 337 } 338 339 static void AddClientDiffs( 340 TreeViewItem parentItem, 341 ITreeViewNode parentNode, 342 List<TreeViewItem> rows, 343 TreeViewItemIds<IDiffCategory, ITreeViewNode> treeViewItemIds) 344 { 345 for (int i = 0; i < parentNode.GetChildrenCount(); i++) 346 { 347 ITreeViewNode child = parentNode.GetChild(i); 348 349 int nodeId; 350 if (!treeViewItemIds.TryGetInfoItemId(child, out nodeId)) 351 nodeId = treeViewItemIds.AddInfoItem(child); 352 353 TreeViewItem changeTreeViewItem = 354 new ClientDiffTreeViewItem( 355 nodeId, 356 parentItem.depth + 1, 357 (ClientDiffInfo)child); 358 359 parentItem.AddChild(changeTreeViewItem); 360 rows.Add(changeTreeViewItem); 361 } 362 } 363 364 static void TreeViewItemGUI( 365 TreeViewItem item, 366 Rect rowRect, 367 float rowHeight, 368 UnityDiffTree diffTree, 369 bool isSelected, 370 bool isFocused, 371 out float itemWidth) 372 { 373 if (item is MergeCategoryTreeViewItem) 374 { 375 MergeCategoryTreeViewItemGUI( 376 rowRect, 377 (MergeCategoryTreeViewItem)item, 378 isSelected, 379 isFocused, 380 out itemWidth); 381 return; 382 } 383 384 if (item is ChangeCategoryTreeViewItem) 385 { 386 ChangeCategoryTreeViewItemGUI( 387 rowRect, 388 (ChangeCategoryTreeViewItem)item, 389 isSelected, 390 isFocused, 391 out itemWidth); 392 return; 393 } 394 395 if (item is ClientDiffTreeViewItem) 396 { 397 ClientDiffTreeViewItemGUI( 398 rowRect, 399 rowHeight, 400 diffTree, 401 (ClientDiffTreeViewItem)item, 402 isSelected, 403 isFocused, 404 out itemWidth); 405 return; 406 } 407 408 itemWidth = 0; 409 } 410 411 static void MergeCategoryTreeViewItemGUI( 412 Rect rowRect, 413 MergeCategoryTreeViewItem item, 414 bool isSelected, 415 bool isFocused, 416 out float itemWidth) 417 { 418 string label = item.Category.CategoryName; 419 string infoLabel = PlasticLocalization.Name.ItemsCount.GetString( 420 item.Category.GetChildrenCount()); 421 422 itemWidth = CalculateLabelWidth(label); 423 424 DrawTreeViewItem.ForCategoryItem( 425 rowRect, 426 item.depth, 427 label, 428 infoLabel, 429 isSelected, 430 isFocused); 431 } 432 433 static void ChangeCategoryTreeViewItemGUI( 434 Rect rowRect, 435 ChangeCategoryTreeViewItem item, 436 bool isSelected, 437 bool isFocused, 438 out float itemWidth) 439 { 440 string label = item.Category.CategoryName; 441 string infoLabel = PlasticLocalization.Name.ItemsCount.GetString( 442 item.Category.GetChildrenCount()); 443 444 itemWidth = CalculateLabelWidth(label); 445 446 DrawTreeViewItem.ForCategoryItem( 447 rowRect, 448 item.depth, 449 label, 450 infoLabel, 451 isSelected, 452 isFocused); 453 } 454 455 static void ClientDiffTreeViewItemGUI( 456 Rect rowRect, 457 float rowHeight, 458 UnityDiffTree diffTree, 459 ClientDiffTreeViewItem item, 460 bool isSelected, 461 bool isFocused, 462 out float itemWidth) 463 { 464 string label = ClientDiffView.GetColumnText( 465 item.Difference.DiffWithMount.Mount.RepSpec, 466 item.Difference.DiffWithMount.Difference, 467 PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn)); 468 469 if (diffTree.HasMeta(item.Difference)) 470 label = string.Concat(label, UnityConstants.TREEVIEW_META_LABEL); 471 472 Texture icon = GetClientDiffIcon( 473 item.Difference.DiffWithMount.Difference.IsDirectory, 474 label); 475 476 itemWidth = CalculateItemWidth(label, icon, rowHeight); 477 478 DrawTreeViewItem.ForItemCell( 479 rowRect, 480 rowHeight, 481 item.depth, 482 icon, 483 null, 484 label, 485 isSelected, 486 isFocused, 487 false, 488 false); 489 } 490 491 static float CalculateItemWidth( 492 string label, 493 Texture icon, 494 float rowHeight) 495 { 496 float labelWidth = CalculateLabelWidth(label); 497 float iconWidth = rowHeight * ((float)icon.width / icon.height); 498 499 return labelWidth + iconWidth; 500 } 501 502 static float CalculateLabelWidth(string label) 503 { 504 GUIContent content = new GUIContent(label); 505 Vector2 contentSize = DefaultStyles.label.CalcSize(content); 506 507 return contentSize.x; 508 } 509 510 static Texture GetClientDiffIcon(bool isDirectory, string path) 511 { 512 if (isDirectory) 513 return Images.GetDirectoryIcon(); 514 515 return Images.GetFileIconFromCmPath(path); 516 } 517 518 bool mExpandCategories; 519 520 TreeViewItemIds<IDiffCategory, ITreeViewNode> mTreeViewItemIds = 521 new TreeViewItemIds<IDiffCategory, ITreeViewNode>(); 522 523 UnityDiffTree mDiffTree = new UnityDiffTree(); 524 525 MultiColumnHeaderState.Column mHorizontalColumn; 526 float mLargestRowWidth; 527 528 readonly CooldownWindowDelayer mCooldownFilterAction; 529 530 static readonly List<string> ColumnsNames = new List<string> { 531 PlasticLocalization.GetString(PlasticLocalization.Name.PathColumn)}; 532 readonly DiffTreeViewMenu mMenu; 533 } 534}