Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit fd4b6ed

Browse files
Merge pull request #467 from github-for-unity/enhancements/branches-view-right-click
Handling branch right click
2 parents 970a25f + daa4ef6 commit fd4b6ed

File tree

2 files changed

+142
-68
lines changed

2 files changed

+142
-68
lines changed

src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs

Lines changed: 131 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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"))

src/UnityExtension/Assets/Editor/GitHub.Unity/UI/TreeControl.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public void Load(IEnumerable<ITreeData> data, string title)
132132
foldersKeys = Folders.Keys.Cast<string>().ToList();
133133
}
134134

135-
public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = null, Action<TreeNode> doubleClick = null)
135+
public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = null, Action<TreeNode> doubleClick = null, Action<TreeNode> rightClick = null)
136136
{
137137
Profiler.BeginSample("TreeControl");
138138
bool visible = true;
@@ -191,7 +191,7 @@ public Rect Render(Rect rect, Vector2 scroll, Action<TreeNode> singleClick = nul
191191
{
192192
if (visible)
193193
{
194-
RequiresRepaint = HandleInput(rect, node, i, singleClick, doubleClick);
194+
RequiresRepaint = HandleInput(rect, node, i, singleClick, doubleClick, rightClick);
195195
}
196196
rect.y += ItemHeight + ItemSpacing;
197197
}
@@ -255,7 +255,7 @@ private int ToggleNodeVisibility(int idx, TreeNode rootNode)
255255
return idx;
256256
}
257257

258-
private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<TreeNode> singleClick = null, Action<TreeNode> doubleClick = null)
258+
private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<TreeNode> singleClick = null, Action<TreeNode> doubleClick = null, Action<TreeNode> rightClick = null)
259259
{
260260
bool selectionChanged = false;
261261
var clickRect = new Rect(0f, rect.y, rect.width, rect.height);
@@ -265,14 +265,20 @@ private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<Tree
265265
SelectedNode = currentNode;
266266
selectionChanged = true;
267267
var clickCount = Event.current.clickCount;
268-
if (clickCount == 1 && singleClick != null)
268+
var mouseButton = Event.current.button;
269+
270+
if (mouseButton == 0 && clickCount == 1 && singleClick != null)
269271
{
270272
singleClick(currentNode);
271273
}
272-
if (clickCount > 1 && doubleClick != null)
274+
if (mouseButton == 0 && clickCount > 1 && doubleClick != null)
273275
{
274276
doubleClick(currentNode);
275277
}
278+
if (mouseButton == 1 && clickCount == 1 && rightClick != null)
279+
{
280+
rightClick(currentNode);
281+
}
276282
}
277283

278284
// Keyboard navigation if this child is the current selection

0 commit comments

Comments
 (0)