From 48ff67d4c170bf30d3db444107cfa0e134f1e98d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 16 Aug 2008 17:12:15 +0000 Subject: [PATCH] Converted more MenuItemBuilders to WPF. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0wpf@3388 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Commands/MenuItemBuilders.cs | 118 ++++++++---------- .../Base/Project/Src/Gui/IWorkbenchLayout.cs | 8 ++ .../Gui/Workbench/Layouts/AvalonDockLayout.cs | 18 ++- .../Layouts/AvalonWorkbenchWindow.cs | 2 +- .../Project/Src/Gui/Workbench/WpfWorkbench.cs | 10 +- .../Services/ProjectService/ProjectService.cs | 12 +- .../Menu/MenuService.cs | 7 +- .../PixelSnapper.cs | 10 +- 8 files changed, 100 insertions(+), 85 deletions(-) diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs index 1e8d57624d..c239db7ec6 100644 --- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs +++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs @@ -143,69 +143,63 @@ namespace ICSharpCode.SharpDevelop.Commands } } - public class RecentFilesMenuBuilder : ISubmenuBuilder + public class RecentFilesMenuBuilder : IMenuItemBuilder { - public ToolStripItem[] BuildSubmenu(Codon codon, object owner) + public ICollection BuildItems(Codon codon, object owner) { RecentOpen recentOpen = FileService.RecentOpen; if (recentOpen.RecentFile.Count > 0) { - MenuCommand[] items = new MenuCommand[recentOpen.RecentFile.Count]; + var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFile.Count]; for (int i = 0; i < recentOpen.RecentFile.Count; ++i) { - string accelaratorKeyPrefix = i < 10 ? "&" + ((i + 1) % 10) + " " : ""; - items[i] = new MenuCommand(accelaratorKeyPrefix + recentOpen.RecentFile[i], new EventHandler(LoadRecentFile)); - items[i].Tag = recentOpen.RecentFile[i].ToString(); - items[i].Description = StringParser.Parse(ResourceService.GetString("Dialog.Componnents.RichMenuItem.LoadFileDescription"), - new string[,] { {"FILE", recentOpen.RecentFile[i].ToString()} }); + // variable inside loop, so that anonymous method refers to correct recent file + string recentFile = recentOpen.RecentFile[i]; + string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : ""; + items[i] = new System.Windows.Controls.MenuItem() { + Header = accelaratorKeyPrefix + recentFile + }; + items[i].Click += delegate { + FileService.OpenFile(recentFile); + }; } return items; + } else { + return new [] { new System.Windows.Controls.MenuItem { + Header = StringParser.Parse("${res:Dialog.Componnents.RichMenuItem.NoRecentFilesString}"), + IsEnabled = false + } }; } - - MenuCommand defaultMenu = new MenuCommand("${res:Dialog.Componnents.RichMenuItem.NoRecentFilesString}"); - defaultMenu.Enabled = false; - - return new MenuCommand[] { defaultMenu }; - } - - void LoadRecentFile(object sender, EventArgs e) - { - MenuCommand item = (MenuCommand)sender; - - FileService.OpenFile(item.Tag.ToString()); } } - public class RecentProjectsMenuBuilder : ISubmenuBuilder + public class RecentProjectsMenuBuilder : IMenuItemBuilder { - public ToolStripItem[] BuildSubmenu(Codon codon, object owner) + public ICollection BuildItems(Codon codon, object owner) { RecentOpen recentOpen = FileService.RecentOpen; - if (recentOpen.RecentProject.Count > 0) { - MenuCommand[] items = new MenuCommand[recentOpen.RecentProject.Count]; + if (recentOpen.RecentFile.Count > 0) { + var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFile.Count]; + for (int i = 0; i < recentOpen.RecentProject.Count; ++i) { - string accelaratorKeyPrefix = i < 10 ? "&" + ((i + 1) % 10) + " " : ""; - items[i] = new MenuCommand(accelaratorKeyPrefix + recentOpen.RecentProject[i], new EventHandler(LoadRecentProject)); - items[i].Tag = recentOpen.RecentProject[i].ToString(); - items[i].Description = StringParser.Parse(ResourceService.GetString("Dialog.Componnents.RichMenuItem.LoadProjectDescription"), - new string[,] { {"PROJECT", recentOpen.RecentProject[i].ToString()} }); + // variable inside loop, so that anonymous method refers to correct recent file + string recentProject = recentOpen.RecentProject[i]; + string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : ""; + items[i] = new System.Windows.Controls.MenuItem() { + Header = accelaratorKeyPrefix + recentProject + }; + items[i].Click += delegate { + ProjectService.LoadSolution(recentProject); + }; } return items; + } else { + return new [] { new System.Windows.Controls.MenuItem { + Header = StringParser.Parse("${res:Dialog.Componnents.RichMenuItem.NoRecentProjectsString}"), + IsEnabled = false + } }; } - - MenuCommand defaultMenu = new MenuCommand("${res:Dialog.Componnents.RichMenuItem.NoRecentProjectsString}"); - defaultMenu.Enabled = false; - - return new MenuCommand[] { defaultMenu }; - } - void LoadRecentProject(object sender, EventArgs e) - { - MenuCommand item = (MenuCommand)sender; - - string fileName = item.Tag.ToString(); - - FileUtility.ObservedLoad(new NamedFileOperationDelegate(ProjectService.LoadSolution), fileName); } } @@ -292,40 +286,26 @@ namespace ICSharpCode.SharpDevelop.Commands } } - public class OpenContentsMenuBuilder : ISubmenuBuilder + public class OpenContentsMenuBuilder : IMenuItemBuilder { - - class MyMenuItem : MenuCheckBox - { - IWorkbenchWindow window; - - public MyMenuItem(IWorkbenchWindow window) : base(StringParser.Parse(window.Title)) - { - this.window = window; - } - - protected override void OnClick(EventArgs e) - { - base.OnClick(e); - Checked = true; - window.SelectWindow(); - } - } - - public ToolStripItem[] BuildSubmenu(Codon codon, object owner) + public ICollection BuildItems(Codon codon, object owner) { int windowCount = WorkbenchSingleton.Workbench.WorkbenchWindowCollection.Count; if (windowCount == 0) { - return new ToolStripItem[] {}; + return new object[] {}; } - ToolStripItem[] items = new ToolStripItem[windowCount + 1]; - items[0] = new MenuSeparator(null, null); + var items = new object[windowCount + 1]; + items[0] = new System.Windows.Controls.Separator(); for (int i = 0; i < windowCount; ++i) { IWorkbenchWindow window = WorkbenchSingleton.Workbench.WorkbenchWindowCollection[i]; - MenuCheckBox item = new MyMenuItem(window); - item.Tag = window; - item.Checked = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == window; - item.Description = "Activate this window"; + var item = new System.Windows.Controls.MenuItem() { + IsChecked = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == window, + IsCheckable = true, + Header = StringParser.Parse(window.Title) + }; + item.Click += delegate { + window.SelectWindow(); + }; items[i + 1] = item; } return items; diff --git a/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs b/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs index d5a1cab0e1..11e3008cad 100644 --- a/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs +++ b/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs @@ -6,6 +6,7 @@ // using System; +using System.Collections.Generic; namespace ICSharpCode.SharpDevelop.Gui { @@ -24,6 +25,13 @@ namespace ICSharpCode.SharpDevelop.Gui get; } + /// + /// Gets the open workbench windows. + /// + IList WorkbenchWindows { + get; + } + /// /// The active content. This can be either a IViewContent or a IPadContent, depending on /// where the focus currently is. diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs index ef048d18ad..2293f6d953 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs @@ -26,22 +26,25 @@ namespace ICSharpCode.SharpDevelop.Gui WpfWorkbench workbench; DockingManager dockingManager = new DockingManager(); DocumentPane documentPane = new DocumentPane(); + List workbenchWindows = new List(); internal bool Busy; public DockingManager DockingManager { get { return dockingManager; } } - public DocumentPane DocumentPane { - get { return documentPane; } - } - public AvalonDockLayout() { dockingManager.Content = documentPane; dockingManager.PropertyChanged += dockingManager_PropertyChanged; } + public void OnWorkbenchWindowClosed(AvalonWorkbenchWindow window) + { + workbenchWindows.Remove(window); + documentPane.Items.Remove(window); + } + void dockingManager_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "ActiveContent") { @@ -72,6 +75,12 @@ namespace ICSharpCode.SharpDevelop.Gui } } + public IList WorkbenchWindows { + get { + return workbenchWindows.AsReadOnly(); + } + } + public void Attach(IWorkbench workbench) { if (this.workbench != null) @@ -213,6 +222,7 @@ namespace ICSharpCode.SharpDevelop.Gui public IWorkbenchWindow ShowView(IViewContent content) { AvalonWorkbenchWindow window = new AvalonWorkbenchWindow(this); + workbenchWindows.Add(window); window.ViewContents.Add(content); window.ViewContents.AddRange(content.SecondaryViewContents); documentPane.Items.Add(window); diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs index c30d3391a0..a1edf72afc 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs @@ -342,7 +342,7 @@ namespace ICSharpCode.SharpDevelop.Gui } } - dockLayout.DocumentPane.Items.Remove(this); + dockLayout.OnWorkbenchWindowClosed(this); Dispose(); CommandManager.InvalidateRequerySuggested(); return true; diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs index 66b56b0f38..51b27a5ac9 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs @@ -45,7 +45,6 @@ namespace ICSharpCode.SharpDevelop.Gui public Window MainWindow { get { return this; } } List padViewContentCollection = new List(); - List viewContentCollection = new List(); ToolBar[] toolBars; @@ -101,14 +100,16 @@ namespace ICSharpCode.SharpDevelop.Gui public ICollection ViewContentCollection { get { - return viewContentCollection.AsReadOnly(); + return WorkbenchWindowCollection.SelectMany(w => w.ViewContents).ToList().ToArray(); } } public IList WorkbenchWindowCollection { get { - return viewContentCollection.Select(vc => vc.WorkbenchWindow) - .Distinct().ToList().AsReadOnly(); + if (workbenchLayout != null) + return workbenchLayout.WorkbenchWindows; + else + return new IWorkbenchWindow[0]; } } @@ -231,7 +232,6 @@ namespace ICSharpCode.SharpDevelop.Gui if (content == null) throw new ArgumentNullException("content"); System.Diagnostics.Debug.Assert(WorkbenchLayout != null); - viewContentCollection.Add(content); WorkbenchLayout.ShowView(content); content.WorkbenchWindow.SelectWindow(); diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs index 66935d2193..dc64a2cf26 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs @@ -244,6 +244,11 @@ namespace ICSharpCode.SharpDevelop.Project } public static void LoadSolution(string fileName) + { + FileUtility.ObservedLoad(LoadSolutionInternal, fileName); + } + + static void LoadSolutionInternal(string fileName) { if (!Path.IsPathRooted(fileName)) throw new ArgumentException("Path must be rooted!"); @@ -307,12 +312,17 @@ namespace ICSharpCode.SharpDevelop.Project /// Load a single project as solution. /// public static void LoadProject(string fileName) + { + FileUtility.ObservedLoad(LoadSolutionInternal, fileName); + } + + static void LoadProjectInternal(string fileName) { if (!Path.IsPathRooted(fileName)) throw new ArgumentException("Path must be rooted!"); string solutionFile = Path.ChangeExtension(fileName, ".sln"); if (File.Exists(solutionFile)) { - LoadSolution(solutionFile); + LoadSolutionInternal(solutionFile); if (openSolution != null) { bool found = false; diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs index 6be9a260ec..44bcc0798b 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs @@ -71,9 +71,14 @@ namespace ICSharpCode.Core.Presentation case "Command": return new MenuCommand(inputBindingOwner, codon, descriptor.Caller, createCommand); case "Menu": - return new CoreMenuItem(codon, descriptor.Caller) { + var item = new CoreMenuItem(codon, descriptor.Caller) { ItemsSource = CreateMenuItems(inputBindingOwner, descriptor.SubItems) }; + item.SubmenuOpened += (sender, args) => { + item.ItemsSource = CreateMenuItems(inputBindingOwner, descriptor.SubItems); + args.Handled = true; + }; + return item; case "Builder": return codon.AddIn.CreateObject(codon.Properties["class"]); default: diff --git a/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs b/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs index 45d9a436ca..b5dbe1ae29 100644 --- a/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs +++ b/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs @@ -5,9 +5,11 @@ // $Revision$ // using System; +using System.Threading; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Windows.Threading; namespace ICSharpCode.Core.Presentation { @@ -18,7 +20,6 @@ namespace ICSharpCode.Core.Presentation { public PixelSnapper() { - LayoutUpdated += new EventHandler(OnLayoutUpdated); } public PixelSnapper(UIElement visualChild) @@ -80,13 +81,14 @@ namespace ICSharpCode.Core.Presentation _pixelOffset = GetPixelOffset(); //LoggingService.Debug("Arrange, Pixel Offset=" + _pixelOffset); _visualChild.Arrange(new Rect(new Point(_pixelOffset.X, _pixelOffset.Y), finalRect.Size)); + + // check again after the whole layout pass has finished, maybe we need to move + Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new ThreadStart(CheckLayout)); } } - private void OnLayoutUpdated(object sender, EventArgs e) + private void CheckLayout() { - // This event just means that layout happened somewhere. However, this is - // what we need since layout anywhere could affect our pixel positioning. Point pixelOffset = GetPixelOffset(); if (!AreClose(pixelOffset, _pixelOffset)) { InvalidateArrange();