From b11a6051dde68d778f9030fa1ebc8c556033168a Mon Sep 17 00:00:00 2001 From: Denis Abt Date: Sat, 11 Jan 2020 18:16:58 +0100 Subject: [PATCH] First release-ready version imo --- ClippyVSPackage/Clippy.cs | 14 +++--- ClippyVSPackage/ClippyVSPackage.cs | 26 ++++++++-- ClippyVSPackage/ClippyVSPackage.csproj | 1 + ClippyVSPackage/ClippyVSSettings.cs | 4 +- ClippyVSPackage/Configurations/Animation.cs | 4 +- ClippyVSPackage/LICENSE.txt | 2 +- ClippyVSPackage/Properties/AssemblyInfo.cs | 2 +- ClippyVSPackage/SpriteContainer.xaml.cs | 41 ++++++++------- ClippyVSPackage/changelog.txt | 1 + ClippyVSPackage/source.extension.vsixmanifest | 50 +++++++++---------- 10 files changed, 85 insertions(+), 60 deletions(-) diff --git a/ClippyVSPackage/Clippy.cs b/ClippyVSPackage/Clippy.cs index df344e1..287312b 100644 --- a/ClippyVSPackage/Clippy.cs +++ b/ClippyVSPackage/Clippy.cs @@ -1,4 +1,5 @@ -using Recoding.ClippyVSPackage.Configurations; +using Microsoft.VisualStudio.Shell; +using Recoding.ClippyVSPackage.Configurations; using System; using System.Collections.Generic; using System.IO; @@ -131,11 +132,11 @@ private void RegisterAnimations() Uri uri = new Uri(animationsResourceUri, UriKind.RelativeOrAbsolute); StreamResourceInfo info = Application.GetResourceStream(uri); - List storedAnimations = Newtonsoft.Json.JsonConvert.DeserializeObject>(StreamToString(info.Stream)); + List storedAnimations = Newtonsoft.Json.JsonConvert.DeserializeObject>(StreamToString(info.Stream)); Animations = new Dictionary>(); - foreach (Animation animation in storedAnimations) + foreach (ClippyAnimation animation in storedAnimations) { DoubleAnimationUsingKeyFrames xDoubleAnimation = new DoubleAnimationUsingKeyFrames(); xDoubleAnimation.FillBehavior = FillBehavior.HoldEnd; @@ -209,8 +210,10 @@ void WPFAnimationsDispatcher_Tick(object sender, EventArgs e) /// public void StartAnimation(ClippyAnimations animationType, bool byPassCurrentAnimation = false) { - Application.Current.MainWindow.Dispatcher.Invoke(new Action(() => + Microsoft.VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async delegate { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + if (!IsAnimating || byPassCurrentAnimation) { IsAnimating = true; @@ -218,11 +221,10 @@ public void StartAnimation(ClippyAnimations animationType, bool byPassCurrentAni clippedImage.BeginAnimation(Canvas.LeftProperty, Animations[animationType.ToString()].Item1); clippedImage.BeginAnimation(Canvas.TopProperty, Animations[animationType.ToString()].Item2); } - }), DispatcherPriority.Send); + }); } - /// /// Reads the content of a stream into a string /// diff --git a/ClippyVSPackage/ClippyVSPackage.cs b/ClippyVSPackage/ClippyVSPackage.cs index 5a04a5c..ec0b463 100644 --- a/ClippyVSPackage/ClippyVSPackage.cs +++ b/ClippyVSPackage/ClippyVSPackage.cs @@ -1,4 +1,5 @@ -using Microsoft.VisualStudio.ComponentModelHost; +using EnvDTE; +using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using System; @@ -26,6 +27,7 @@ public sealed class ClippyVisualStudioPackage : AsyncPackage public ClippyVisualStudioPackage() { Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString())); + } #region Package Members @@ -36,13 +38,14 @@ public ClippyVisualStudioPackage() /// protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) { + Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); base.Initialize(); - Application.Current.MainWindow.ContentRendered += MainWindow_ContentRendered; - + await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + // Add our command handlers for menu (commands must exist in the .vsct file) - OleMenuCommandService mcs = await GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService; + OleMenuCommandService mcs = await GetServiceAsync(typeof(IMenuCommandService)).ConfigureAwait(true) as OleMenuCommandService; if (null != mcs) { // Create the command for the menu item. @@ -50,7 +53,20 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID); mcs.AddCommand(menuItem); } - await Command1.InitializeAsync(this); + await Command1.InitializeAsync(this).ConfigureAwait(true); + } + + private void SolutionEvents_Opened() + { + var componentModel = (IComponentModel)(GetService(typeof(SComponentModel))); + IClippyVSSettings s = componentModel.DefaultExportProvider.GetExportedValue(); + + SpriteContainer container = new SpriteContainer(this); + + if (s.ShowAtStartup) + { + container.Show(); + } } void MainWindow_ContentRendered(object sender, EventArgs e) diff --git a/ClippyVSPackage/ClippyVSPackage.csproj b/ClippyVSPackage/ClippyVSPackage.csproj index b275ed3..955bf3f 100644 --- a/ClippyVSPackage/ClippyVSPackage.csproj +++ b/ClippyVSPackage/ClippyVSPackage.csproj @@ -69,6 +69,7 @@ DEBUG;TRACE prompt 4 + False pdbonly diff --git a/ClippyVSPackage/ClippyVSSettings.cs b/ClippyVSPackage/ClippyVSSettings.cs index 8e30ec6..ddfb7cb 100644 --- a/ClippyVSPackage/ClippyVSSettings.cs +++ b/ClippyVSPackage/ClippyVSSettings.cs @@ -63,7 +63,7 @@ public void Store() writableSettingsStore.SetString(Constants.SettingsCollectionPath, nameof(ShowAtStartup), ShowAtStartup.ToString(CultureInfo.InvariantCulture)); } - catch (Exception ex) + catch (ArgumentException ex) { Debug.Fail(ex.Message); } @@ -87,7 +87,7 @@ private void LoadSettings() this.ShowAtStartup = b; } } - catch (Exception ex) + catch (ArgumentException ex) { Debug.Fail(ex.Message); } diff --git a/ClippyVSPackage/Configurations/Animation.cs b/ClippyVSPackage/Configurations/Animation.cs index 73298fe..0bce008 100644 --- a/ClippyVSPackage/Configurations/Animation.cs +++ b/ClippyVSPackage/Configurations/Animation.cs @@ -5,12 +5,12 @@ namespace Recoding.ClippyVSPackage.Configurations /// /// Represents a single animation, as it is directly mapped from the JSON /// - public class Animation + public class ClippyAnimation { /// /// Default ctor /// - public Animation() + public ClippyAnimation() { Frames = new List(); } diff --git a/ClippyVSPackage/LICENSE.txt b/ClippyVSPackage/LICENSE.txt index a2dfa23..f00acbd 100644 --- a/ClippyVSPackage/LICENSE.txt +++ b/ClippyVSPackage/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License -Eros Fratini +Eros Fratini / Denis Abt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ClippyVSPackage/Properties/AssemblyInfo.cs b/ClippyVSPackage/Properties/AssemblyInfo.cs index 150cec4..f101ec6 100644 --- a/ClippyVSPackage/Properties/AssemblyInfo.cs +++ b/ClippyVSPackage/Properties/AssemblyInfo.cs @@ -6,7 +6,7 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("ClippyVS")] +[assembly: AssemblyTitle("ClippyVS 2019")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Recoding")] diff --git a/ClippyVSPackage/SpriteContainer.xaml.cs b/ClippyVSPackage/SpriteContainer.xaml.cs index ce35eee..1f652e1 100644 --- a/ClippyVSPackage/SpriteContainer.xaml.cs +++ b/ClippyVSPackage/SpriteContainer.xaml.cs @@ -9,6 +9,7 @@ using System.ComponentModel; using System.Diagnostics; using System.Globalization; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -60,10 +61,13 @@ public SpriteContainer(AsyncPackage package) InitializeComponent(); - this.Owner = System.Windows.Application.Current.MainWindow; + this.Owner = Application.Current.MainWindow; this.Topmost = false; #region Register event handlers + if (package == null) + throw new ArgumentException("Package was null"); + IVsActivityLog activityLog = package.GetServiceAsync(typeof(SVsActivityLog)) .ConfigureAwait(true).GetAwaiter().GetResult() as IVsActivityLog; //if (activityLog == null) return; @@ -74,7 +78,7 @@ public SpriteContainer(AsyncPackage package) docEvents = dte.Events.DocumentEvents; buildEvents = dte.Events.BuildEvents; - RegisterToDTEEvents(); + _ = RegisterToDTEEventsAsync(); Owner.LocationChanged += Owner_LocationChanged; Owner.StateChanged += Owner_StateOrSizeChanged; @@ -100,9 +104,9 @@ public SpriteContainer(AsyncPackage package) if (_userSettingsStore.PropertyExists(Constants.SettingsCollectionPath, nameof(RelativeLeft))) storedRelativeLeft = Double.Parse(_userSettingsStore.GetString(Constants.SettingsCollectionPath, nameof(RelativeLeft)), CultureInfo.InvariantCulture); } - catch + catch (Exception e) { - + Debug.Fail(e.Message); } if (!storedRelativeTop.HasValue || !storedRelativeLeft.HasValue) @@ -160,7 +164,7 @@ public SpriteContainer(AsyncPackage package) _clippy.StartAnimation(ClippyAnimations.Idle1_1); } - private void RegisterToDTEEvents() + private async Task RegisterToDTEEventsAsync() { docEvents.DocumentOpening += DocumentEvents_DocumentOpening; docEvents.DocumentSaved += DocumentEvents_DocumentSaved; @@ -168,12 +172,11 @@ private void RegisterToDTEEvents() buildEvents.OnBuildBegin += BuildEvents_OnBuildBegin; buildEvents.OnBuildDone += BuildEvents_OnBuildDone; - - ThreadHelper.ThrowIfNotOnUIThread(); - DTE dte = _package.GetServiceAsync(typeof(DTE)).ConfigureAwait(true).GetAwaiter().GetResult() as EnvDTE.DTE; - if (findEvents != null) + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + DTE dte = await _package.GetServiceAsync(typeof(DTE)).ConfigureAwait(false) as DTE; + if (dte.Events.FindEvents != null) { - findEvents.FindDone += FindEventsClass_FindDone; + dte.Events.FindEvents.FindDone += FindEventsClass_FindDone; } Events2 events2 = dte.Events as Events2; @@ -192,6 +195,8 @@ private void RegisterToDTEEvents() this.csharpProjectItemsEvents.ItemRemoved += ProjectItemsEvents_ItemRemoved; this.csharpProjectItemsEvents.ItemRenamed += ProjectItemsEvents_ItemRenamed; } + + return true; } #region -- IDE Event Handlers -- @@ -303,13 +308,13 @@ private void cmdClose_Click(object sender, RoutedEventArgs e) { while (_clippy.IsAnimating) { } - Dispatcher.Invoke(new Action(() => - { - window.Owner.Focus(); + ThreadHelper.JoinableTaskFactory.Run(async delegate { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + window.Owner.Focus(); window.Close(); - }), DispatcherPriority.Send); + }); }; bgWorker.RunWorkerAsync(); @@ -371,9 +376,9 @@ private void SpriteContainer_LocationChanged(object sender, EventArgs e) { storeRelativeSpritePosition(relativeTop, relativeLeft); } - catch + catch (Exception ex) { - + Debug.Fail(ex.Message); } } @@ -434,9 +439,9 @@ private void storeRelativeSpritePosition(double relativeTop, double relativeLeft _userSettingsStore.SetString(Constants.SettingsCollectionPath, nameof(RelativeTop), relativeTop.ToString(CultureInfo.InvariantCulture)); _userSettingsStore.SetString(Constants.SettingsCollectionPath, nameof(RelativeLeft), relativeLeft.ToString(CultureInfo.InvariantCulture)); } - catch + catch (ArgumentException ae) { - + Debug.Fail(ae.Message); } } } diff --git a/ClippyVSPackage/changelog.txt b/ClippyVSPackage/changelog.txt index 2515c29..6a9b16b 100644 --- a/ClippyVSPackage/changelog.txt +++ b/ClippyVSPackage/changelog.txt @@ -1,6 +1,7 @@ ClippyVS - Changelog -------------------- +0.4 - Ported to VS 2019 and some code cleanup after migration 0.3 - Multimonitor support 0.2.2 - Fixed compatibility with Visual Studio 2015 0.2.1 - Removed the MPF dependency diff --git a/ClippyVSPackage/source.extension.vsixmanifest b/ClippyVSPackage/source.extension.vsixmanifest index 2a1e8ac..c978634 100644 --- a/ClippyVSPackage/source.extension.vsixmanifest +++ b/ClippyVSPackage/source.extension.vsixmanifest @@ -1,28 +1,28 @@  - - - ClippyVS - Clippy is back! - LICENSE.txt - changelog.txt - Resources\Package.ico - Resources\preview.png - adornment, vintage, nostalgia - - - - - - - - - - - - - - - - + + + ClippyVS 2019 + Clippy is back! Now in VS 2019. Thanks Eros Fratini for getting Clippy alive and back, and for letting me port it to Visual Studio 2019. + LICENSE.txt + changelog.txt + Resources\Package.ico + Resources\preview.png + adornment, vintage, nostalgia + + + + + + + + + + + + + + + +