@@ -32,6 +32,9 @@ class BranchesView : Subview
3232 private const string DeleteBranchTitle = "Delete Branch?" ;
3333 private const string DeleteBranchButton = "Delete" ;
3434 private const string CancelButtonLabel = "Cancel" ;
35+ private const string DeleteBranchContextMenuLabel = "Delete" ;
36+ private const string SwitchBranchContextMenuLabel = "Switch" ;
37+ private const string CheckoutBranchContextMenuLabel = "Checkout" ;
3538
3639 [ NonSerialized ] private int listID = - 1 ;
3740 [ NonSerialized ] private BranchesMode targetMode ;
@@ -163,12 +166,7 @@ private void OnButtonBarGUI()
163166 {
164167 if ( GUILayout . Button ( DeleteBranchButton , EditorStyles . miniButton , GUILayout . ExpandWidth ( false ) ) )
165168 {
166- var selectedBranchName = treeLocals . SelectedNode . Name ;
167- var dialogMessage = string . Format ( DeleteBranchMessageFormatString , selectedBranchName ) ;
168- if ( EditorUtility . DisplayDialog ( DeleteBranchTitle , dialogMessage , DeleteBranchButton , CancelButtonLabel ) )
169- {
170- GitClient . DeleteBranch ( selectedBranchName , true ) . Start ( ) ;
171- }
169+ DeleteLocalBranch ( treeLocals . SelectedNode . Name ) ;
172170 }
173171 }
174172 EditorGUI . EndDisabledGroup ( ) ;
@@ -282,26 +280,20 @@ private void OnTreeGUI(Rect rect)
282280
283281 var treeHadFocus = treeLocals . SelectedNode != null ;
284282
285- rect = treeLocals . Render ( rect , scroll , _ => { } , node =>
286- {
287- if ( EditorUtility . DisplayDialog ( ConfirmSwitchTitle , String . Format ( ConfirmSwitchMessage , node . Name ) , ConfirmSwitchOK ,
288- ConfirmSwitchCancel ) )
289- {
290- GitClient . SwitchBranch ( node . Name )
291- . FinallyInUI ( ( success , e ) =>
292- {
293- if ( success )
294- {
295- Redraw ( ) ;
296- }
297- else
298- {
299- EditorUtility . DisplayDialog ( Localization . SwitchBranchTitle ,
300- String . Format ( Localization . SwitchBranchFailedDescription , node . Name ) ,
301- Localization . Ok ) ;
302- }
303- } ) . Start ( ) ;
304- }
283+ rect = treeLocals . Render ( rect , scroll ,
284+ node => { } ,
285+ node => {
286+ if ( node . IsFolder )
287+ return ;
288+
289+ SwitchBranch ( node . Name ) ;
290+ } ,
291+ node => {
292+ if ( node . IsFolder )
293+ return ;
294+
295+ var menu = CreateContextMenuForLocalBranchNode ( node ) ;
296+ menu . ShowAsContext ( ) ;
305297 } ) ;
306298
307299 if ( treeHadFocus && treeLocals . SelectedNode == null )
@@ -316,45 +308,20 @@ private void OnTreeGUI(Rect rect)
316308
317309 rect . y += Styles . TreePadding ;
318310
319- rect = treeRemotes . Render ( rect , scroll , _ => { } , selectedNode =>
320- {
321- var indexOfFirstSlash = selectedNode . Name . IndexOf ( '/' ) ;
322- var originName = selectedNode . Name . Substring ( 0 , indexOfFirstSlash ) ;
323- var branchName = selectedNode . Name . Substring ( indexOfFirstSlash + 1 ) ;
311+ rect = treeRemotes . Render ( rect , scroll ,
312+ node => { } ,
313+ node => {
314+ if ( node . IsFolder )
315+ return ;
324316
325- if ( Repository . LocalBranches . Any ( localBranch => localBranch . Name == branchName ) )
326- {
327- EditorUtility . DisplayDialog ( WarningCheckoutBranchExistsTitle ,
328- String . Format ( WarningCheckoutBranchExistsMessage , branchName ) ,
329- WarningCheckoutBranchExistsOK ) ;
330- }
331- else
332- {
333- var confirmCheckout = EditorUtility . DisplayDialog ( ConfirmCheckoutBranchTitle ,
334- String . Format ( ConfirmCheckoutBranchMessage , selectedNode . Name , originName ) ,
335- ConfirmCheckoutBranchOK ,
336- ConfirmCheckoutBranchCancel ) ;
317+ CheckoutRemoteBranch ( node . Name ) ;
318+ } ,
319+ node => {
320+ if ( node . IsFolder )
321+ return ;
337322
338- if ( confirmCheckout )
339- {
340- GitClient
341- . CreateBranch ( branchName , selectedNode . Name )
342- . FinallyInUI ( ( success , e ) =>
343- {
344- if ( success )
345- {
346- Redraw ( ) ;
347- }
348- else
349- {
350- EditorUtility . DisplayDialog ( Localization . SwitchBranchTitle ,
351- String . Format ( Localization . SwitchBranchFailedDescription , selectedNode . Name ) ,
352- Localization . Ok ) ;
353- }
354- } )
355- . Start ( ) ;
356- }
357- }
323+ var menu = CreateContextMenuForRemoteBranchNode ( node ) ;
324+ menu . ShowAsContext ( ) ;
358325 } ) ;
359326
360327 if ( treeHadFocus && treeRemotes . SelectedNode == null )
@@ -369,6 +336,107 @@ private void OnTreeGUI(Rect rect)
369336 GUILayout . Space ( rect . y - initialRect . y ) ;
370337 }
371338
339+ private GenericMenu CreateContextMenuForLocalBranchNode ( TreeNode node )
340+ {
341+ var genericMenu = new GenericMenu ( ) ;
342+
343+ var deleteGuiContent = new GUIContent ( DeleteBranchContextMenuLabel ) ;
344+ var switchGuiContent = new GUIContent ( SwitchBranchContextMenuLabel ) ;
345+
346+ if ( node . IsActive )
347+ {
348+ genericMenu . AddDisabledItem ( deleteGuiContent ) ;
349+ genericMenu . AddDisabledItem ( switchGuiContent ) ;
350+ }
351+ else
352+ {
353+ genericMenu . AddItem ( deleteGuiContent , false , ( ) => {
354+ DeleteLocalBranch ( node . Name ) ;
355+ } ) ;
356+
357+ genericMenu . AddItem ( switchGuiContent , false , ( ) => {
358+ SwitchBranch ( node . Name ) ;
359+ } ) ;
360+ }
361+
362+ return genericMenu ;
363+ }
364+
365+ private GenericMenu CreateContextMenuForRemoteBranchNode ( TreeNode node )
366+ {
367+ var genericMenu = new GenericMenu ( ) ;
368+
369+ var checkoutGuiContent = new GUIContent ( CheckoutBranchContextMenuLabel ) ;
370+
371+ genericMenu . AddItem ( checkoutGuiContent , false , ( ) => {
372+ CheckoutRemoteBranch ( node . Name ) ;
373+ } ) ;
374+
375+ return genericMenu ;
376+ }
377+
378+ private void CheckoutRemoteBranch ( string branch )
379+ {
380+ var indexOfFirstSlash = branch . IndexOf ( '/' ) ;
381+ var originName = branch . Substring ( 0 , indexOfFirstSlash ) ;
382+ var branchName = branch . Substring ( indexOfFirstSlash + 1 ) ;
383+
384+ if ( Repository . LocalBranches . Any ( localBranch => localBranch . Name == branchName ) )
385+ {
386+ EditorUtility . DisplayDialog ( WarningCheckoutBranchExistsTitle ,
387+ String . Format ( WarningCheckoutBranchExistsMessage , branchName ) , WarningCheckoutBranchExistsOK ) ;
388+ }
389+ else
390+ {
391+ var confirmCheckout = EditorUtility . DisplayDialog ( ConfirmCheckoutBranchTitle ,
392+ String . Format ( ConfirmCheckoutBranchMessage , branch , originName ) , ConfirmCheckoutBranchOK ,
393+ ConfirmCheckoutBranchCancel ) ;
394+
395+ if ( confirmCheckout )
396+ {
397+ GitClient . CreateBranch ( branchName , branch ) . FinallyInUI ( ( success , e ) => {
398+ if ( success )
399+ {
400+ Redraw ( ) ;
401+ }
402+ else
403+ {
404+ EditorUtility . DisplayDialog ( Localization . SwitchBranchTitle ,
405+ String . Format ( Localization . SwitchBranchFailedDescription , branch ) , Localization . Ok ) ;
406+ }
407+ } ) . Start ( ) ;
408+ }
409+ }
410+ }
411+
412+ private void SwitchBranch ( string branch )
413+ {
414+ if ( EditorUtility . DisplayDialog ( ConfirmSwitchTitle , String . Format ( ConfirmSwitchMessage , branch ) , ConfirmSwitchOK ,
415+ ConfirmSwitchCancel ) )
416+ {
417+ GitClient . SwitchBranch ( branch ) . FinallyInUI ( ( success , e ) => {
418+ if ( success )
419+ {
420+ Redraw ( ) ;
421+ }
422+ else
423+ {
424+ EditorUtility . DisplayDialog ( Localization . SwitchBranchTitle ,
425+ String . Format ( Localization . SwitchBranchFailedDescription , branch ) , Localization . Ok ) ;
426+ }
427+ } ) . Start ( ) ;
428+ }
429+ }
430+
431+ private void DeleteLocalBranch ( string branch )
432+ {
433+ var dialogMessage = string . Format ( DeleteBranchMessageFormatString , branch ) ;
434+ if ( EditorUtility . DisplayDialog ( DeleteBranchTitle , dialogMessage , DeleteBranchButton , CancelButtonLabel ) )
435+ {
436+ GitClient . DeleteBranch ( branch , true ) . Start ( ) ;
437+ }
438+ }
439+
372440 private int CompareBranches ( GitBranch a , GitBranch b )
373441 {
374442 if ( a . Name . Equals ( "master" ) )
0 commit comments