diff --git a/source/AvalonDock.sln b/source/AvalonDock.sln index 598de4ca..c9927a51 100644 --- a/source/AvalonDock.sln +++ b/source/AvalonDock.sln @@ -26,7 +26,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvalonDock.Themes.Aero", "C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AutomationTest", "AutomationTest", "{20876020-CC7D-46BD-9B80-E4F01FC0FD31}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDockTest", "AutomationTest\AvalonDockTest\AvalonDockTest.csproj", "{FE4E16A2-876A-4356-9974-8A89C50B2A5A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvalonDockTest", "AutomationTest\AvalonDockTest\AvalonDockTest.csproj", "{FE4E16A2-876A-4356-9974-8A89C50B2A5A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceLocator", "MLibTest\MLibTest_Components\ServiceLocator\ServiceLocator.csproj", "{38F7F15D-2F13-49E4-B4E6-B9552072AFCD}" EndProject @@ -40,7 +40,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsTestApp", "WinForms EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDocPanelMemoryLeaks", "AvalonDocPanelMemoryLeaks\AvalonDocPanelMemoryLeaks.csproj", "{5543BFED-827A-4404-8066-3FFDB201DDF0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaliburnDockTestApp", "CaliburnDockTestApp\CaliburnDockTestApp.csproj", "{F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaliburnDockTestApp", "CaliburnDockTestApp\CaliburnDockTestApp.csproj", "{F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VS2013Test", "VS2013Test\VS2013Test.csproj", "{12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -244,6 +246,18 @@ Global {F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1}.Release|x64.Build.0 = Release|Any CPU {F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1}.Release|x86.ActiveCfg = Release|Any CPU {F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1}.Release|x86.Build.0 = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|x64.ActiveCfg = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|x64.Build.0 = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|x86.ActiveCfg = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Debug|x86.Build.0 = Debug|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|Any CPU.Build.0 = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|x64.ActiveCfg = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|x64.Build.0 = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|x86.ActiveCfg = Release|Any CPU + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -267,6 +281,7 @@ Global {2433B8AF-0788-4C86-8FDD-E3BCB62E2157} = {1D267DDB-F2DE-4B70-87C1-E93A0C2D73F4} {5543BFED-827A-4404-8066-3FFDB201DDF0} = {1D267DDB-F2DE-4B70-87C1-E93A0C2D73F4} {F8AEE594-DB5E-4DB8-9F45-4969CA5F8EF1} = {1D267DDB-F2DE-4B70-87C1-E93A0C2D73F4} + {12C5DFE9-27AE-4BAB-9050-617F8A7FC52E} = {1D267DDB-F2DE-4B70-87C1-E93A0C2D73F4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {459B8289-CF04-4E70-AEC9-23DC3A6E66F6} diff --git a/source/Components/AvalonDock.Themes.VS2013/BlueBrushs.xaml b/source/Components/AvalonDock.Themes.VS2013/BlueBrushs.xaml index d8a30098..81f99228 100644 --- a/source/Components/AvalonDock.Themes.VS2013/BlueBrushs.xaml +++ b/source/Components/AvalonDock.Themes.VS2013/BlueBrushs.xaml @@ -1,4 +1,4 @@ - + Color="#007ACC" /> + Color="#007ACC" /> + Color="#F1F1F1" /> + Color="#007ACC" /> + Color="#007ACC" /> - - - - - + + + + + - --> - - - - + + + - - + + + - + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - + + + - - + - + - - + - + - - + - - - - - - - - - - - - + + + + + + + + + + + - + - - + - - - - - + + + + - - + - - + + - - - + - - - + + - - + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - + + + + + + + - + + + + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + + + + - + + + + + + + + - + + + + + + + + + + + + + + diff --git a/source/Components/AvalonDock.Themes.VS2013/Themes/Icons/IconGeometry.xaml b/source/Components/AvalonDock.Themes.VS2013/Themes/Icons/IconGeometry.xaml index a94f092e..92f0957c 100644 --- a/source/Components/AvalonDock.Themes.VS2013/Themes/Icons/IconGeometry.xaml +++ b/source/Components/AvalonDock.Themes.VS2013/Themes/Icons/IconGeometry.xaml @@ -1,4 +1,4 @@ - + @@ -6,8 +6,8 @@ - - + + \ No newline at end of file diff --git a/source/VS2013Test/App.xaml b/source/VS2013Test/App.xaml new file mode 100644 index 00000000..9b1b9681 --- /dev/null +++ b/source/VS2013Test/App.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + diff --git a/source/VS2013Test/App.xaml.cs b/source/VS2013Test/App.xaml.cs new file mode 100644 index 00000000..f5747ade --- /dev/null +++ b/source/VS2013Test/App.xaml.cs @@ -0,0 +1,11 @@ +using System.Windows; + +namespace AvalonDock.VS2013Test +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/source/VS2013Test/AssemblyInfo.cs b/source/VS2013Test/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/source/VS2013Test/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/source/VS2013Test/Converters/ActiveDocumentConverter.cs b/source/VS2013Test/Converters/ActiveDocumentConverter.cs new file mode 100644 index 00000000..3131fe74 --- /dev/null +++ b/source/VS2013Test/Converters/ActiveDocumentConverter.cs @@ -0,0 +1,26 @@ +using System; +using System.Windows.Data; +using AvalonDock.VS2013Test.ViewModels; + +namespace AvalonDock.VS2013Test.Converters +{ + + public class ActiveDocumentConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value is FileViewModel) + return value; + + return Binding.DoNothing; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value is FileViewModel) + return value; + + return Binding.DoNothing; + } + } +} diff --git a/source/VS2013Test/Icons/VisualStudioIcon.xaml b/source/VS2013Test/Icons/VisualStudioIcon.xaml new file mode 100644 index 00000000..f5383bf1 --- /dev/null +++ b/source/VS2013Test/Icons/VisualStudioIcon.xaml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/source/VS2013Test/Icons/VisualStudioIcon.xaml.cs b/source/VS2013Test/Icons/VisualStudioIcon.xaml.cs new file mode 100644 index 00000000..9f2d2f07 --- /dev/null +++ b/source/VS2013Test/Icons/VisualStudioIcon.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace VS2013Test.Icons +{ + /// + /// Interaction logic for VisualStudioIcon.xaml + /// + public partial class VisualStudioIcon : UserControl + { + public VisualStudioIcon() + { + InitializeComponent(); + } + } +} diff --git a/source/VS2013Test/LayoutInitializer.cs b/source/VS2013Test/LayoutInitializer.cs new file mode 100644 index 00000000..356156b3 --- /dev/null +++ b/source/VS2013Test/LayoutInitializer.cs @@ -0,0 +1,95 @@ +using System.Linq; +using AvalonDock.Layout; +using AvalonDock.VS2013Test.ViewModels; + +namespace AvalonDock.VS2013Test +{ + class LayoutInitializer : ILayoutUpdateStrategy + { + public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer) + { + //AD wants to add the anchorable into destinationContainer + //just for test provide a new anchorablepane + //if the pane is floating let the manager go ahead + LayoutAnchorablePane destPane = destinationContainer as LayoutAnchorablePane; + if (destinationContainer != null && destinationContainer.FindParent() != null) + return false; + + anchorableToShow.AutoHideWidth = 256; + anchorableToShow.AutoHideHeight = 128; + anchorableToShow.CanShowOnHover = false; + + if (anchorableToShow.Content is ExplorerViewModel) + { + var explorerPane = layout.Descendents().OfType().FirstOrDefault(d => d.Name == "ExplorerPane"); + + if (explorerPane != null) + { + explorerPane.Children.Add(anchorableToShow); + return true; + } + } + + if (anchorableToShow.Content is PropertiesViewModel) + { + var propertiesPane = layout.Descendents().OfType().FirstOrDefault(d => d.Name == "PropertiesPane"); + + if (propertiesPane != null) + { + propertiesPane.Children.Add(anchorableToShow); + return true; + } + } + + if (anchorableToShow.Content is OutputViewModel) + { + var outputPane = layout.Descendents().OfType().FirstOrDefault(d => d.Name == "OutputPane"); + + if (outputPane != null) + { + outputPane.Children.Add(anchorableToShow); + return true; + } + } + + if (anchorableToShow.Content is ToolboxViewModel) + { + var leftGroup = new LayoutAnchorGroup(); + leftGroup.Children.Add(anchorableToShow); + layout.LeftSide.Children.Add(leftGroup); + return true; + } + + if (anchorableToShow.Content is GitChangesViewModel) + { + var rightGroup = new LayoutAnchorGroup(); + rightGroup.Children.Add(anchorableToShow); + layout.RightSide.Children.Add(rightGroup); + return true; + } + + if (anchorableToShow.Content is ErrorViewModel) + { + var bottomGroup = new LayoutAnchorGroup(); + bottomGroup.Children.Add(anchorableToShow); + layout.BottomSide.Children.Add(bottomGroup); + return true; + } + + return false; + } + + public void AfterInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableShown) + { + } + + public bool BeforeInsertDocument(LayoutRoot layout, LayoutDocument anchorableToShow, ILayoutContainer destinationContainer) + { + return false; + } + + public void AfterInsertDocument(LayoutRoot layout, LayoutDocument anchorableShown) + { + } + } +} diff --git a/source/VS2013Test/PanesStyleSelector.cs b/source/VS2013Test/PanesStyleSelector.cs new file mode 100644 index 00000000..c379f6ae --- /dev/null +++ b/source/VS2013Test/PanesStyleSelector.cs @@ -0,0 +1,32 @@ +using System.Windows.Controls; +using System.Windows; +using AvalonDock.VS2013Test.ViewModels; + +namespace AvalonDock.VS2013Test +{ + class PanesStyleSelector : StyleSelector + { + public Style ToolStyle + { + get; + set; + } + + public Style FileStyle + { + get; + set; + } + + public override Style SelectStyle(object item, DependencyObject container) + { + if (item is ToolViewModel) + return ToolStyle; + + if (item is FileViewModel) + return FileStyle; + + return base.SelectStyle(item, container); + } + } +} diff --git a/source/VS2013Test/PanesTemplateSelector.cs b/source/VS2013Test/PanesTemplateSelector.cs new file mode 100644 index 00000000..baf0a821 --- /dev/null +++ b/source/VS2013Test/PanesTemplateSelector.cs @@ -0,0 +1,84 @@ +using System.Windows.Controls; +using System.Windows; +using AvalonDock.Layout; +using AvalonDock.VS2013Test.ViewModels; + +namespace AvalonDock.VS2013Test +{ + class PanesTemplateSelector : DataTemplateSelector + { + public PanesTemplateSelector() + { + } + + public DataTemplate FileViewTemplate + { + get; + set; + } + + public DataTemplate PropertiesViewTemplate + { + get; + set; + } + + public DataTemplate ExplorerViewTemplate + { + get; + set; + } + + public DataTemplate ErrorViewTemplate + { + get; + set; + } + + public DataTemplate OutputViewTemplate + { + get; + set; + } + + public DataTemplate GitChangesViewTemplate + { + get; + set; + } + + public DataTemplate ToolboxViewTemplate + { + get; + set; + } + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + var itemAsLayoutContent = item as LayoutContent; + + if (item is FileViewModel) + return FileViewTemplate; + + if (item is PropertiesViewModel) + return PropertiesViewTemplate; + + if (item is ExplorerViewModel) + return ExplorerViewTemplate; + + if (item is ErrorViewModel) + return ErrorViewTemplate; + + if (item is OutputViewModel) + return OutputViewTemplate; + + if (item is GitChangesViewModel) + return GitChangesViewTemplate; + + if (item is ToolboxViewModel) + return ToolboxViewTemplate; + + return base.SelectTemplate(item, container); + } + } +} diff --git a/source/VS2013Test/RelayCommand.cs b/source/VS2013Test/RelayCommand.cs new file mode 100644 index 00000000..2807f5d0 --- /dev/null +++ b/source/VS2013Test/RelayCommand.cs @@ -0,0 +1,48 @@ +using System; +using System.Windows.Input; + +namespace AvalonDock.VS2013Test +{ + internal class RelayCommand : ICommand + { + #region fields + + readonly Action _execute; + readonly Predicate _canExecute; + + #endregion fields + + #region Constructors + + public RelayCommand(Action execute) : this(execute, null) + { + } + + public RelayCommand(Action execute, Predicate canExecute) + { + _execute = execute ?? throw new ArgumentNullException(nameof(execute)); + _canExecute = canExecute; + } + #endregion Constructors + + #region ICommand Members + + public bool CanExecute(object parameter) + { + return _canExecute?.Invoke(parameter) ?? true; + } + + public event EventHandler CanExecuteChanged + { + add { CommandManager.RequerySuggested += value; } + remove { CommandManager.RequerySuggested -= value; } + } + + public void Execute(object parameter) + { + _execute(parameter); + } + + #endregion ICommand Members + } +} diff --git a/source/VS2013Test/Themes/BlueBrushsExtended.xaml b/source/VS2013Test/Themes/BlueBrushsExtended.xaml new file mode 100644 index 00000000..80c4c66b --- /dev/null +++ b/source/VS2013Test/Themes/BlueBrushsExtended.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/VS2013Test/Themes/Controls/VsResizeGrip.xaml b/source/VS2013Test/Themes/Controls/VsResizeGrip.xaml new file mode 100644 index 00000000..65c8d750 --- /dev/null +++ b/source/VS2013Test/Themes/Controls/VsResizeGrip.xaml @@ -0,0 +1,48 @@ + + + + \ No newline at end of file diff --git a/source/VS2013Test/Themes/DarkBrushsExtended.xaml b/source/VS2013Test/Themes/DarkBrushsExtended.xaml new file mode 100644 index 00000000..71a27586 --- /dev/null +++ b/source/VS2013Test/Themes/DarkBrushsExtended.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/VS2013Test/Themes/Generic.xaml b/source/VS2013Test/Themes/Generic.xaml new file mode 100644 index 00000000..6c9b22e9 --- /dev/null +++ b/source/VS2013Test/Themes/Generic.xaml @@ -0,0 +1,135 @@ + + + + + + + + + + \ No newline at end of file diff --git a/source/VS2013Test/Themes/LightBrushsExtended.xaml b/source/VS2013Test/Themes/LightBrushsExtended.xaml new file mode 100644 index 00000000..101178ad --- /dev/null +++ b/source/VS2013Test/Themes/LightBrushsExtended.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/VS2013Test/VS2013Test.csproj b/source/VS2013Test/VS2013Test.csproj new file mode 100644 index 00000000..85d50ca9 --- /dev/null +++ b/source/VS2013Test/VS2013Test.csproj @@ -0,0 +1,28 @@ + + + + WinExe + net5.0-windows + true + + + + + + + + + + + + + $(DefaultXamlRuntime) + Designer + + + $(DefaultXamlRuntime) + Designer + + + + diff --git a/source/VS2013Test/ViewModels/ErrorViewModel.cs b/source/VS2013Test/ViewModels/ErrorViewModel.cs new file mode 100644 index 00000000..af59325b --- /dev/null +++ b/source/VS2013Test/ViewModels/ErrorViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class ErrorViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public ErrorViewModel() + : base("Error List") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/ExplorerViewModel.cs b/source/VS2013Test/ViewModels/ExplorerViewModel.cs new file mode 100644 index 00000000..4c4fe65d --- /dev/null +++ b/source/VS2013Test/ViewModels/ExplorerViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class ExplorerViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public ExplorerViewModel() + : base("Solution Explorer") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/FileViewModel.cs b/source/VS2013Test/ViewModels/FileViewModel.cs new file mode 100644 index 00000000..25a0ed26 --- /dev/null +++ b/source/VS2013Test/ViewModels/FileViewModel.cs @@ -0,0 +1,176 @@ +using System.IO; +using System.Windows.Input; +using System.Windows.Media; + +namespace AvalonDock.VS2013Test.ViewModels +{ + class FileViewModel : PaneViewModel + { + #region fields + //private static ImageSourceConverter ISC = new ImageSourceConverter(); + private string _filePath = null; + private string _textContent = string.Empty; + private bool _isDirty = false; + private RelayCommand _saveCommand = null; + private RelayCommand _saveAsCommand = null; + private RelayCommand _closeCommand = null; + #endregion fields + + #region constructors + /// + /// Class constructor from file path. + /// + /// + public FileViewModel(string filePath) + { + FilePath = filePath; + Title = FileName; + + //Set the icon only for open documents (just a test) + //IconSource = ISC.ConvertFromInvariantString(@"pack://application:,,/Images/document.png") as ImageSource; + } + + /// + /// Default class constructor + /// + public FileViewModel() + { + IsDirty = true; + Title = FileName; + } + #endregion constructors + + #region Properties + public string FilePath + { + get => _filePath; + set + { + if (_filePath != value) + { + _filePath = value; + RaisePropertyChanged(nameof(FilePath)); + RaisePropertyChanged(nameof(FileName)); + RaisePropertyChanged(nameof(Title)); + + if (File.Exists(_filePath)) + { + _textContent = File.ReadAllText(_filePath); + ContentId = _filePath; + } + } + } + } + + public string FileName + { + get + { + if (FilePath == null) + return "Noname" + (IsDirty ? "*" : ""); + + return System.IO.Path.GetFileName(FilePath) + (IsDirty ? "*" : ""); + } + } + + public string TextContent + { + get => _textContent; + set + { + if (_textContent != value) + { + _textContent = value; + RaisePropertyChanged(nameof(TextContent)); + IsDirty = true; + } + } + } + + public bool IsDirty + { + get => _isDirty; + set + { + if (_isDirty != value) + { + _isDirty = value; + RaisePropertyChanged(nameof(IsDirty)); + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public ICommand SaveCommand + { + get + { + if (_saveCommand == null) + { + _saveCommand = new RelayCommand((p) => OnSave(p), (p) => CanSave(p)); + } + + return _saveCommand; + } + } + + public ICommand SaveAsCommand + { + get + { + if (_saveAsCommand == null) + { + _saveAsCommand = new RelayCommand((p) => OnSaveAs(p), (p) => CanSaveAs(p)); + } + + return _saveAsCommand; + } + } + + public ICommand CloseCommand + { + get + { + if (_closeCommand == null) + { + _closeCommand = new RelayCommand((p) => OnClose(), (p) => CanClose()); + } + + return _closeCommand; + } + } + #endregion Properties + + #region methods + private bool CanClose() + { + return true; + } + + private void OnClose() + { + Workspace.This.Close(this); + } + + private bool CanSave(object parameter) + { + return IsDirty; + } + + private void OnSave(object parameter) + { + Workspace.This.Save(this, false); + } + + private bool CanSaveAs(object parameter) + { + return IsDirty; + } + + private void OnSaveAs(object parameter) + { + Workspace.This.Save(this, true); + } + #endregion methods + } +} diff --git a/source/VS2013Test/ViewModels/GitChangesViewModel.cs b/source/VS2013Test/ViewModels/GitChangesViewModel.cs new file mode 100644 index 00000000..9224fafd --- /dev/null +++ b/source/VS2013Test/ViewModels/GitChangesViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class GitChangesViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public GitChangesViewModel() + : base("Git Changes") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/OutputViewModel.cs b/source/VS2013Test/ViewModels/OutputViewModel.cs new file mode 100644 index 00000000..2d6ad9c4 --- /dev/null +++ b/source/VS2013Test/ViewModels/OutputViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class OutputViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public OutputViewModel() + : base("Output") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/PaneViewModel.cs b/source/VS2013Test/ViewModels/PaneViewModel.cs new file mode 100644 index 00000000..00ff9cc8 --- /dev/null +++ b/source/VS2013Test/ViewModels/PaneViewModel.cs @@ -0,0 +1,76 @@ +using System.Windows.Media; + +namespace AvalonDock.VS2013Test.ViewModels +{ + class PaneViewModel : ViewModelBase + { + #region fields + private string _title = null; + private string _contentId = null; + private bool _isSelected = false; + private bool _isActive = false; + #endregion fields + + #region constructors + public PaneViewModel() + { + } + #endregion constructors + + #region Properties + public string Title + { + get => _title; + set + { + if (_title != value) + { + _title = value; + RaisePropertyChanged(nameof(Title)); + } + } + } + + public ImageSource IconSource { get; protected set; } + + public string ContentId + { + get => _contentId; + set + { + if (_contentId != value) + { + _contentId = value; + RaisePropertyChanged(nameof(ContentId)); + } + } + } + + public bool IsSelected + { + get => _isSelected; + set + { + if (_isSelected != value) + { + _isSelected = value; + RaisePropertyChanged(nameof(IsSelected)); + } + } + } + + public bool IsActive + { + get => _isActive; + set + { + if (_isActive != value) + { + _isActive = value; + RaisePropertyChanged(nameof(IsActive)); + } + } + } + #endregion Properties + } +} diff --git a/source/VS2013Test/ViewModels/PropertiesViewModel.cs b/source/VS2013Test/ViewModels/PropertiesViewModel.cs new file mode 100644 index 00000000..78826713 --- /dev/null +++ b/source/VS2013Test/ViewModels/PropertiesViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class PropertiesViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public PropertiesViewModel() + : base("Properties") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/ToolViewModel.cs b/source/VS2013Test/ViewModels/ToolViewModel.cs new file mode 100644 index 00000000..049818f1 --- /dev/null +++ b/source/VS2013Test/ViewModels/ToolViewModel.cs @@ -0,0 +1,38 @@ +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class ToolViewModel : PaneViewModel + { + #region fields + private bool _isVisible = true; + #endregion fields + + #region constructor + /// + /// Class constructor + /// + /// + public ToolViewModel(string name) + { + Name = name; + Title = name; + } + #endregion constructor + + #region Properties + public string Name { get; private set; } + + public bool IsVisible + { + get => _isVisible; + set + { + if (_isVisible != value) + { + _isVisible = value; + RaisePropertyChanged(nameof(IsVisible)); + } + } + } + #endregion Properties + } +} diff --git a/source/VS2013Test/ViewModels/ToolboxViewModel.cs b/source/VS2013Test/ViewModels/ToolboxViewModel.cs new file mode 100644 index 00000000..616aefe6 --- /dev/null +++ b/source/VS2013Test/ViewModels/ToolboxViewModel.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; +using System.Windows.Media.Imaging; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class ToolboxViewModel : ToolViewModel + { + #region fields + public const string ToolContentId = "FileStatsTool"; + private DateTime _lastModified; + private long _fileSize; + private string _FileName; + private string _FilePath; + #endregion fields + + #region constructors + /// + /// Class constructor + /// + public ToolboxViewModel() + : base("Toolbox") + { + Workspace.This.ActiveDocumentChanged += new EventHandler(OnActiveDocumentChanged); + ContentId = ToolContentId; + } + #endregion constructors + + #region Properties + + public long FileSize + { + get => _fileSize; + protected set + { + if (_fileSize != value) + { + _fileSize = value; + RaisePropertyChanged(nameof(FileSize)); + } + } + } + + public DateTime LastModified + { + get => _lastModified; + protected set + { + if (_lastModified != value) + { + _lastModified = value; + RaisePropertyChanged(nameof(LastModified)); + } + } + } + + public string FileName + { + get => _FileName; + protected set + { + if (_FileName != value) + { + _FileName = value; + RaisePropertyChanged(nameof(FileName)); + } + } + } + + public string FilePath + { + get => _FilePath; + protected set + { + if (_FilePath != value) + { + _FilePath = value; + RaisePropertyChanged(nameof(FilePath)); + } + } + } + + #endregion Properties + + #region methods + private void OnActiveDocumentChanged(object sender, EventArgs e) + { + if (Workspace.This.ActiveDocument != null && + Workspace.This.ActiveDocument.FilePath != null && + File.Exists(Workspace.This.ActiveDocument.FilePath)) + { + var fi = new FileInfo(Workspace.This.ActiveDocument.FilePath); + FileSize = fi.Length; + LastModified = fi.LastWriteTime; + FileName = fi.Name; + FilePath = fi.Directory.FullName; + } + else + { + FileSize = 0; + LastModified = DateTime.MinValue; + FileName = string.Empty; + FilePath = string.Empty; + } + } + #endregion methods + + } +} diff --git a/source/VS2013Test/ViewModels/ViewModelBase.cs b/source/VS2013Test/ViewModels/ViewModelBase.cs new file mode 100644 index 00000000..23e1d88f --- /dev/null +++ b/source/VS2013Test/ViewModels/ViewModelBase.cs @@ -0,0 +1,17 @@ +using System.ComponentModel; + +namespace AvalonDock.VS2013Test.ViewModels +{ + class ViewModelBase : INotifyPropertyChanged + { + + protected virtual void RaisePropertyChanged(string propertyName) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/source/VS2013Test/ViewModels/Workspace.cs b/source/VS2013Test/ViewModels/Workspace.cs new file mode 100644 index 00000000..ba900a74 --- /dev/null +++ b/source/VS2013Test/ViewModels/Workspace.cs @@ -0,0 +1,308 @@ +using AvalonDock.Themes; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Windows; +using System.Windows.Input; + +namespace AvalonDock.VS2013Test.ViewModels +{ + internal class Workspace : ViewModelBase + { + #region fields + + private static Workspace _this = new Workspace(); + private ToolViewModel[] _tools; + private ObservableCollection _files = new ObservableCollection(); + private ReadOnlyObservableCollection _readonyFiles; + private FileViewModel _activeDocument; + private ErrorViewModel _errors; + private PropertiesViewModel _props; + private ExplorerViewModel _explorer; + private OutputViewModel _output; + private GitChangesViewModel _git; + private ToolboxViewModel _toolbox; + private RelayCommand _openCommand; + private RelayCommand _newCommand; + private Tuple _selectedTheme; + + #endregion fields + + #region constructors + + /// + /// Class constructor + /// + public Workspace() + { + SelectedTheme = Themes.First(); + } + + #endregion constructors + + public event EventHandler ActiveDocumentChanged; + + #region properties + + public static Workspace This => _this; + + public ReadOnlyObservableCollection Files + { + get + { + if (_readonyFiles == null) + _readonyFiles = new ReadOnlyObservableCollection(_files); + + return _readonyFiles; + } + } + + public IEnumerable Tools + { + get + { + if (_tools == null) + _tools = new ToolViewModel[] { Explorer, Props, Errors, Output, Git, Toolbox }; + return _tools; + } + } + + public ExplorerViewModel Explorer + { + get + { + if (_explorer == null) + _explorer = new ExplorerViewModel(); + + return _explorer; + } + } + + public PropertiesViewModel Props + { + get + { + if (_props == null) + _props = new PropertiesViewModel(); + + return _props; + } + } + + public ErrorViewModel Errors + { + get + { + if (_errors == null) + _errors = new ErrorViewModel(); + + return _errors; + } + } + + public OutputViewModel Output + { + get + { + if (_output == null) + _output = new OutputViewModel(); + + return _output; + } + } + + public GitChangesViewModel Git + { + get + { + if (_git == null) + _git = new GitChangesViewModel(); + + return _git; + } + } + + public ToolboxViewModel Toolbox + { + get + { + if (_toolbox == null) + _toolbox = new ToolboxViewModel(); + + return _toolbox; + } + } + + public ICommand OpenCommand + { + get + { + if (_openCommand == null) + { + _openCommand = new RelayCommand((p) => OnOpen(p), (p) => CanOpen(p)); + } + + return _openCommand; + } + } + + public ICommand NewCommand + { + get + { + if (_newCommand == null) + { + _newCommand = new RelayCommand((p) => OnNew(p), (p) => CanNew(p)); + } + + return _newCommand; + } + } + + public FileViewModel ActiveDocument + { + get => _activeDocument; + set + { + if (_activeDocument != value) + { + _activeDocument = value; + RaisePropertyChanged(nameof(ActiveDocument)); + if (ActiveDocumentChanged != null) + ActiveDocumentChanged(this, EventArgs.Empty); + } + } + } + + public List> Themes { get; set; } = new List> + { + new Tuple(nameof(Vs2013DarkTheme),new Vs2013DarkTheme()), + new Tuple(nameof(Vs2013LightTheme),new Vs2013LightTheme()), + new Tuple(nameof(Vs2013BlueTheme),new Vs2013BlueTheme()) + }; + + public Tuple SelectedTheme + { + get { return _selectedTheme; } + set + { + _selectedTheme = value; + SwitchExtendedTheme(); + RaisePropertyChanged(nameof(SelectedTheme)); + } + } + + #endregion properties + + #region methods + + private void SwitchExtendedTheme() + { + switch (_selectedTheme.Item1) + { + case "Vs2013DarkTheme": + Application.Current.Resources.MergedDictionaries[0].Source = new Uri("pack://application:,,,/MLib;component/Themes/DarkTheme.xaml"); + Application.Current.Resources.MergedDictionaries[1].Source = new Uri("pack://application:,,,/VS2013Test;component/Themes/DarkBrushsExtended.xaml"); + break; + case "Vs2013LightTheme": + Application.Current.Resources.MergedDictionaries[0].Source = new Uri("pack://application:,,,/MLib;component/Themes/LightTheme.xaml"); + Application.Current.Resources.MergedDictionaries[1].Source = new Uri("pack://application:,,,/VS2013Test;component/Themes/LightBrushsExtended.xaml"); + break; + case "Vs2013BlueTheme": + //TODO: Create new color resources for blue theme + Application.Current.Resources.MergedDictionaries[0].Source = new Uri("pack://application:,,,/MLib;component/Themes/LightTheme.xaml"); + Application.Current.Resources.MergedDictionaries[1].Source = new Uri("pack://application:,,,/VS2013Test;component/Themes/BlueBrushsExtended.xaml"); + break; + default: + break; + } + } + + internal void Close(FileViewModel fileToClose) + { + if (fileToClose.IsDirty) + { + var res = MessageBox.Show(string.Format("Save changes for file '{0}'?", fileToClose.FileName), "AvalonDock Test App", MessageBoxButton.YesNoCancel); + if (res == MessageBoxResult.Cancel) + return; + if (res == MessageBoxResult.Yes) + { + Save(fileToClose); + } + } + + _files.Remove(fileToClose); + } + + internal void Save(FileViewModel fileToSave, bool saveAsFlag = false) + { + string newTitle = string.Empty; + + if (fileToSave.FilePath == null || saveAsFlag) + { + var dlg = new SaveFileDialog(); + if (dlg.ShowDialog().GetValueOrDefault()) + { + fileToSave.FilePath = dlg.FileName; + newTitle = dlg.SafeFileName; + } + } + if (fileToSave.FilePath == null) + { + return; + } + File.WriteAllText(fileToSave.FilePath, fileToSave.TextContent); + ActiveDocument.IsDirty = false; + + if (string.IsNullOrEmpty(newTitle)) return; + ActiveDocument.Title = newTitle; + } + + internal FileViewModel Open(string filepath) + { + var fileViewModel = _files.FirstOrDefault(fm => fm.FilePath == filepath); + if (fileViewModel != null) + return fileViewModel; + + fileViewModel = new FileViewModel(filepath); + _files.Add(fileViewModel); + return fileViewModel; + } + + #region OpenCommand + + private bool CanOpen(object parameter) => true; + + private void OnOpen(object parameter) + { + var dlg = new OpenFileDialog(); + if (dlg.ShowDialog().GetValueOrDefault()) + { + var fileViewModel = Open(dlg.FileName); + ActiveDocument = fileViewModel; + } + } + + #endregion OpenCommand + + #region NewCommand + + private bool CanNew(object parameter) + { + return true; + } + + private void OnNew(object parameter) + { + _files.Add(new FileViewModel()); + ActiveDocument = _files.Last(); + } + + #endregion NewCommand + + #endregion methods + } +} \ No newline at end of file diff --git a/source/VS2013Test/Views/MainView.xaml b/source/VS2013Test/Views/MainView.xaml new file mode 100644 index 00000000..d942ac89 --- /dev/null +++ b/source/VS2013Test/Views/MainView.xaml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +