Skip to content

Commit 3ae9b05

Browse files
committedJun 2, 2018
Refactor JumpList and thumbnail toolbars management
Move the code related to Windows jumplists and thumbnail toolbars out of FormBrowse into own set of classes. The underlying functionality remains for the most part the same. For the ease of use added an abstraction that represents a thumbnail toolbar button; and a class that aggregate all available buttons. Relates to gitextensions#4549.
1 parent b87f180 commit 3ae9b05

5 files changed

+280
-185
lines changed
 

‎GitUI/CommandsDialogs/FormBrowse.cs

+20-185
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
using GitUIPluginInterfaces;
2828
using Microsoft.VisualStudio.Threading;
2929
using Microsoft.Win32;
30-
using Microsoft.WindowsAPICodePack.Taskbar;
3130
using ResourceManager;
3231

3332
namespace GitUI.CommandsDialogs
@@ -87,10 +86,6 @@ public partial class FormBrowse : GitModuleForm, IBrowseRepo
8786
private ToolStripItem _bisect;
8887
private ToolStripItem _warning;
8988

90-
private ThumbnailToolBarButton _commitButton;
91-
private ThumbnailToolBarButton _pushButton;
92-
private ThumbnailToolBarButton _pullButton;
93-
private bool _toolbarButtonsCreated;
9489
private readonly ToolStripMenuItem _toolStripGitStatus;
9590
private readonly GitStatusMonitor _gitStatusMonitor;
9691
private readonly FilterRevisionsHelper _filterRevisionsHelper;
@@ -107,6 +102,7 @@ public partial class FormBrowse : GitModuleForm, IBrowseRepo
107102
private readonly IRepositoryDescriptionProvider _repositoryDescriptionProvider;
108103
private readonly IAppTitleGenerator _appTitleGenerator;
109104
private readonly ILongShaProvider _longShaProvider;
105+
private readonly WindowsJumpListManager _windowsJumpListManager;
110106
private static bool _showRevisionInfoNextToRevisionGrid;
111107
private bool _startWithDashboard = false;
112108

@@ -269,6 +265,7 @@ public FormBrowse(GitUICommands commands, string filter)
269265

270266
_repositoryDescriptionProvider = new RepositoryDescriptionProvider(new GitDirectoryResolver());
271267
_appTitleGenerator = new AppTitleGenerator(_repositoryDescriptionProvider);
268+
_windowsJumpListManager = new WindowsJumpListManager(_repositoryDescriptionProvider);
272269

273270
FillBuildReport(); // Ensure correct page visibility
274271
RevisionGrid.ShowBuildServerInfo = true;
@@ -407,10 +404,11 @@ private void HideDashboard()
407404

408405
private void BrowseLoad(object sender, EventArgs e)
409406
{
410-
if (EnvUtils.RunningOnWindows() && TaskbarManager.IsPlatformSupported)
411-
{
412-
TaskbarManager.Instance.ApplicationId = "GitExtensions";
413-
}
407+
var buttons = new WindowsThumbnailToolbarButtons(
408+
new WindowsThumbnailToolbarButton(toolStripButton1.Text, toolStripButton1.Image, ToolStripButton1Click),
409+
new WindowsThumbnailToolbarButton(toolStripButtonPush.Text, toolStripButtonPush.Image, PushToolStripMenuItemClick),
410+
new WindowsThumbnailToolbarButton(toolStripButtonPull.Text, toolStripButtonPull.Image, PullToolStripMenuItemClick));
411+
_windowsJumpListManager.CreateJumpList(Handle, buttons);
414412

415413
SetSplitterPositions();
416414
HideVariableMainMenuItems();
@@ -641,7 +639,6 @@ private void InternalInitialize(bool hard)
641639
RefreshWorkingDirCombo();
642640
var branchName = !string.IsNullOrEmpty(branchSelect.Text) ? branchSelect.Text : _noBranchTitle.Text;
643641
Text = _appTitleGenerator.Generate(Module.WorkingDir, validBrowseDir, branchName);
644-
UpdateJumplist(validBrowseDir);
645642

646643
OnActivate();
647644

@@ -651,13 +648,19 @@ private void InternalInitialize(bool hard)
651648

652649
if (validBrowseDir)
653650
{
651+
_windowsJumpListManager.AddToRecent(Module.WorkingDir);
652+
654653
// add Navigate and View menu
655654
_formBrowseMenus.ResetMenuCommandSets();
656655
_formBrowseMenus.AddMenuCommandSet(MainMenuItem.NavigateMenu, RevisionGrid.MenuCommands.GetNavigateMenuCommands());
657656
_formBrowseMenus.AddMenuCommandSet(MainMenuItem.ViewMenu, RevisionGrid.MenuCommands.GetViewMenuCommands());
658657

659658
_formBrowseMenus.InsertAdditionalMainMenuItems(repositoryToolStripMenuItem);
660659
}
660+
else
661+
{
662+
_windowsJumpListManager.DisableThumbnailToolbar();
663+
}
661664

662665
UICommands.RaisePostBrowseInitialize(this);
663666
}
@@ -808,137 +811,6 @@ private void UserMenu_Click(object sender, EventArgs e)
808811
}
809812
}
810813

811-
private void UpdateJumplist(bool validWorkingDir)
812-
{
813-
if (!EnvUtils.RunningOnWindows() || !TaskbarManager.IsPlatformSupported)
814-
{
815-
return;
816-
}
817-
818-
try
819-
{
820-
if (validWorkingDir)
821-
{
822-
string repositoryDescription = _repositoryDescriptionProvider.Get(Module.WorkingDir);
823-
string baseFolder = Path.Combine(AppSettings.ApplicationDataPath.Value, "Recent");
824-
if (!Directory.Exists(baseFolder))
825-
{
826-
Directory.CreateDirectory(baseFolder);
827-
}
828-
829-
// Remove InvalidPathChars
830-
StringBuilder sb = new StringBuilder(repositoryDescription);
831-
foreach (char c in Path.GetInvalidFileNameChars())
832-
{
833-
sb.Replace(c, '_');
834-
}
835-
836-
string path = Path.Combine(baseFolder, string.Format("{0}.{1}", sb, "gitext"));
837-
File.WriteAllText(path, Module.WorkingDir);
838-
JumpList.AddToRecent(path);
839-
840-
var jumpList = JumpList.CreateJumpListForIndividualWindow(TaskbarManager.Instance.ApplicationId, Handle);
841-
jumpList.ClearAllUserTasks();
842-
843-
// to control which category Recent/Frequent is displayed
844-
jumpList.KnownCategoryToDisplay = JumpListKnownCategoryType.Recent;
845-
846-
jumpList.Refresh();
847-
}
848-
849-
CreateOrUpdateTaskBarButtons(validWorkingDir);
850-
}
851-
catch (System.Runtime.InteropServices.COMException ex)
852-
{
853-
Trace.WriteLine(ex.Message, "UpdateJumplist");
854-
}
855-
}
856-
857-
private void CreateOrUpdateTaskBarButtons(bool validRepo)
858-
{
859-
if (EnvUtils.RunningOnWindows() && TaskbarManager.IsPlatformSupported)
860-
{
861-
if (!_toolbarButtonsCreated)
862-
{
863-
_commitButton = new ThumbnailToolBarButton(MakeIcon(toolStripButton1.Image, 48, true), toolStripButton1.Text);
864-
_commitButton.Click += ToolStripButton1Click;
865-
866-
_pushButton = new ThumbnailToolBarButton(MakeIcon(toolStripButtonPush.Image, 48, true), toolStripButtonPush.Text);
867-
_pushButton.Click += PushToolStripMenuItemClick;
868-
869-
_pullButton = new ThumbnailToolBarButton(MakeIcon(toolStripButtonPull.Image, 48, true), toolStripButtonPull.Text);
870-
_pullButton.Click += PullToolStripMenuItemClick;
871-
872-
_toolbarButtonsCreated = true;
873-
ThumbnailToolBarButton[] buttons = { _commitButton, _pullButton, _pushButton };
874-
875-
// Call this method using reflection. This is a workaround to *not* reference WPF libraries, becuase of how the WindowsAPICodePack was implimented.
876-
TaskbarManager.Instance.ThumbnailToolBars.AddButtons(Handle, buttons);
877-
}
878-
879-
_commitButton.Enabled = validRepo;
880-
_pushButton.Enabled = validRepo;
881-
_pullButton.Enabled = validRepo;
882-
}
883-
}
884-
885-
/// <summary>
886-
/// Converts an image into an icon. This was taken off of the interwebs.
887-
/// It's on a billion different sites and forum posts, so I would say its creative commons by now. -tekmaven
888-
/// </summary>
889-
/// <param name="img">The image that shall become an icon</param>
890-
/// <param name="size">The width and height of the icon. Standard
891-
/// sizes are 16x16, 32x32, 48x48, 64x64.</param>
892-
/// <param name="keepAspectRatio">Whether the image should be squashed into a
893-
/// square or whether whitespace should be put around it.</param>
894-
/// <returns>An icon!!</returns>
895-
private static Icon MakeIcon(Image img, int size, bool keepAspectRatio)
896-
{
897-
Bitmap square = new Bitmap(size, size); // create new bitmap
898-
Graphics g = Graphics.FromImage(square); // allow drawing to it
899-
900-
int x, y, w, h; // dimensions for new image
901-
902-
if (!keepAspectRatio || img.Height == img.Width)
903-
{
904-
// just fill the square
905-
x = y = 0; // set x and y to 0
906-
w = h = size; // set width and height to size
907-
}
908-
else
909-
{
910-
// work out the aspect ratio
911-
float r = img.Width / (float)img.Height;
912-
913-
// set dimensions accordingly to fit inside size^2 square
914-
if (r > 1)
915-
{
916-
// w is bigger, so divide h by r
917-
w = size;
918-
h = (int)(size / r);
919-
x = 0;
920-
y = (size - h) / 2; // center the image
921-
}
922-
else
923-
{
924-
// h is bigger, so multiply w by r
925-
w = (int)(size * r);
926-
h = size;
927-
y = 0;
928-
x = (size - w) / 2; // center the image
929-
}
930-
}
931-
932-
// make the image shrink nicely by using HighQualityBicubic mode
933-
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
934-
g.DrawImage(img, x, y, w, h); // draw image with specified dimensions
935-
g.Flush(); // make sure all drawing operations complete before we get the icon
936-
937-
// following line would work directly on any image, but then
938-
// it wouldn't look as nice.
939-
return Icon.FromHandle(square.GetHicon());
940-
}
941-
942814
private void UpdateStashCount()
943815
{
944816
ThreadHelper.ThrowIfNotOnUIThread();
@@ -3019,50 +2891,13 @@ protected override void Dispose(bool disposing)
30192891
{
30202892
if (disposing)
30212893
{
3022-
if (_commitButton != null)
3023-
{
3024-
_commitButton.Dispose();
3025-
}
3026-
3027-
if (_pushButton != null)
3028-
{
3029-
_pushButton.Dispose();
3030-
}
3031-
3032-
if (_pullButton != null)
3033-
{
3034-
_pullButton.Dispose();
3035-
}
3036-
3037-
if (_submodulesStatusSequence != null)
3038-
{
3039-
_submodulesStatusSequence.Dispose();
3040-
}
3041-
3042-
if (_formBrowseMenus != null)
3043-
{
3044-
_formBrowseMenus.Dispose();
3045-
}
3046-
3047-
if (_filterRevisionsHelper != null)
3048-
{
3049-
_filterRevisionsHelper.Dispose();
3050-
}
3051-
3052-
if (_filterBranchHelper != null)
3053-
{
3054-
_filterBranchHelper.Dispose();
3055-
}
3056-
3057-
if (components != null)
3058-
{
3059-
components.Dispose();
3060-
}
3061-
3062-
if (_gitStatusMonitor != null)
3063-
{
3064-
_gitStatusMonitor.Dispose();
3065-
}
2894+
_submodulesStatusSequence?.Dispose();
2895+
_formBrowseMenus?.Dispose();
2896+
_filterRevisionsHelper?.Dispose();
2897+
_filterBranchHelper?.Dispose();
2898+
components?.Dispose();
2899+
_gitStatusMonitor?.Dispose();
2900+
_windowsJumpListManager?.Dispose();
30662901
}
30672902

30682903
base.Dispose(disposing);

‎GitUI/GitUI.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,9 @@
11001100
<Compile Include="WebBrowserEmulationMode.cs" />
11011101
<Compile Include="WindowPositionList.cs" />
11021102
<Compile Include="CommandsDialogs\CommitDialog\WordWrapper.cs" />
1103+
<Compile Include="WindowsJumpListManager.cs" />
1104+
<Compile Include="WindowsThumbnailToolbarButton.cs" />
1105+
<Compile Include="WindowsThumbnailToolbarButtons.cs" />
11031106
</ItemGroup>
11041107
<ItemGroup>
11051108
<EmbeddedResource Include="CommandsDialogs\AboutBox.resx">

0 commit comments

Comments
 (0)
Please sign in to comment.