Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3820 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
23 changed files with 1433 additions and 1 deletions
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// A Separator that is invisible when it is excluded by a condition.
|
||||
/// </summary>
|
||||
sealed class ConditionalSeparator : Separator, IStatusUpdate |
||||
{ |
||||
readonly Codon codon; |
||||
readonly object caller; |
||||
|
||||
public ConditionalSeparator(Codon codon, object caller, bool inToolbar) |
||||
{ |
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
|
||||
if (inToolbar) { |
||||
SetResourceReference(FrameworkElement.StyleProperty, ToolBar.SeparatorStyleKey); |
||||
} |
||||
} |
||||
|
||||
public void UpdateText() |
||||
{ |
||||
} |
||||
|
||||
public void UpdateStatus() |
||||
{ |
||||
if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude) |
||||
this.Visibility = Visibility.Collapsed; |
||||
else |
||||
this.Visibility = Visibility.Visible; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Markup extension that gets a BitmapSource object for a ResourceService bitmap.
|
||||
/// </summary>
|
||||
public class GetBitmapExtension : MarkupExtension |
||||
{ |
||||
public GetBitmapExtension(string key) |
||||
{ |
||||
this.key = key; |
||||
} |
||||
|
||||
protected string key; |
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider) |
||||
{ |
||||
return PresentationResourceService.GetBitmapSource(key); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}</ProjectGuid> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>ICSharpCode.Core.Presentation</RootNamespace> |
||||
<AssemblyName>ICSharpCode.Core.Presentation</AssemblyName> |
||||
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion> |
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
<SourceAnalysisOverrideSettingsFile>"C:\Program Files\SharpDevelop\3.0\bin\..\AddIns\AddIns\Misc\SourceAnalysis\Settings.SourceAnalysis"</SourceAnalysisOverrideSettingsFile> |
||||
<OutputPath>..\..\..\bin\</OutputPath> |
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
||||
<NoStdLib>False</NoStdLib> |
||||
<WarningLevel>4</WarningLevel> |
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
||||
<SignAssembly>True</SignAssembly> |
||||
<AssemblyOriginatorKeyFile>..\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile> |
||||
<DelaySign>False</DelaySign> |
||||
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> |
||||
<RunCodeAnalysis>False</RunCodeAnalysis> |
||||
<CodeAnalysisRules>-Microsoft.Performance#CA1810</CodeAnalysisRules> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>Full</DebugType> |
||||
<Optimize>False</Optimize> |
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
<DebugSymbols>False</DebugSymbols> |
||||
<DebugType>None</DebugType> |
||||
<Optimize>True</Optimize> |
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
||||
<RegisterForComInterop>False</RegisterForComInterop> |
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
||||
<BaseAddress>4194304</BaseAddress> |
||||
<PlatformTarget>AnyCPU</PlatformTarget> |
||||
<FileAlignment>4096</FileAlignment> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
||||
<ItemGroup> |
||||
<Reference Include="PresentationCore"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="PresentationFramework"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="WindowsBase"> |
||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="..\GlobalAssemblyInfo.cs"> |
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
||||
</Compile> |
||||
<Compile Include="ConditionalSeparator.cs" /> |
||||
<Compile Include="GetBitmapExtension.cs" /> |
||||
<Compile Include="IStatusUpdate.cs" /> |
||||
<Compile Include="LocalizeExtension.cs" /> |
||||
<Compile Include="Menu\IMenuItemBuilder.cs" /> |
||||
<Compile Include="Menu\MenuCommand.cs" /> |
||||
<Compile Include="Menu\MenuService.cs" /> |
||||
<Compile Include="Menu\CoreMenuItem.cs" /> |
||||
<Compile Include="NativeMethods.cs" /> |
||||
<Compile Include="PixelSnapper.cs" /> |
||||
<Compile Include="PresentationResourceService.cs" /> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
<Compile Include="SplitButton.cs" /> |
||||
<Compile Include="ToolBar\ToolBarButton.cs" /> |
||||
<Compile Include="ToolBar\ToolBarComboBox.cs" /> |
||||
<Compile Include="ToolBar\ToolBarService.cs" /> |
||||
<Compile Include="ToolBar\ToolBarSplitButton.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\Core\Project\ICSharpCode.Core.csproj"> |
||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
||||
<Name>ICSharpCode.Core</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<Folder Include="Menu" /> |
||||
<Folder Include="themes" /> |
||||
<Folder Include="ToolBar" /> |
||||
<Page Include="themes\Aero.NormalColor.xaml" /> |
||||
<Page Include="themes\generic.xaml" /> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
public interface IStatusUpdate |
||||
{ |
||||
void UpdateText(); |
||||
void UpdateStatus(); |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Markup; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Markup extension that retrieves localized resource strings.
|
||||
/// </summary>
|
||||
public class LocalizeExtension : MarkupExtension |
||||
{ |
||||
public LocalizeExtension(string key) |
||||
{ |
||||
this.key = key; |
||||
} |
||||
|
||||
protected string key; |
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider) |
||||
{ |
||||
return ResourceService.GetString(key); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// A menu item representing an AddIn-Tree element.
|
||||
/// </summary>
|
||||
class CoreMenuItem : MenuItem, IStatusUpdate |
||||
{ |
||||
protected readonly Codon codon; |
||||
protected readonly object caller; |
||||
|
||||
public CoreMenuItem(Codon codon, object caller) |
||||
{ |
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
|
||||
if (codon.Properties.Contains("icon")) { |
||||
try { |
||||
var image = PresentationResourceService.GetImage(codon.Properties["icon"]); |
||||
image.Height = 16; |
||||
this.Icon = new PixelSnapper(image); |
||||
} catch (ResourceNotFoundException) {} |
||||
} |
||||
UpdateText(); |
||||
} |
||||
|
||||
public void UpdateText() |
||||
{ |
||||
if (codon != null) { |
||||
Header = MenuService.ConvertLabel(StringParser.Parse(codon.Properties["label"])); |
||||
} |
||||
} |
||||
|
||||
public virtual void UpdateStatus() |
||||
{ |
||||
if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude) |
||||
this.Visibility = Visibility.Collapsed; |
||||
else |
||||
this.Visibility = Visibility.Visible; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Used to include a dynamically built list of menu items.
|
||||
/// </summary>
|
||||
public interface IMenuItemBuilder |
||||
{ |
||||
ICollection BuildItems(Codon codon, object owner); |
||||
} |
||||
} |
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Diagnostics; |
||||
using System.Threading; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
class CommandWrapper : System.Windows.Input.ICommand |
||||
{ |
||||
bool commandCreated; |
||||
ICommand addInCommand; |
||||
readonly Codon codon; |
||||
readonly object caller; |
||||
|
||||
public CommandWrapper(Codon codon, object caller, bool createCommand) |
||||
{ |
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
if (createCommand) { |
||||
commandCreated = true; |
||||
CreateCommand(); |
||||
} |
||||
} |
||||
|
||||
public CommandWrapper(Codon codon, object caller, ICommand command) |
||||
{ |
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
this.addInCommand = command; |
||||
commandCreated = true; |
||||
} |
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="We're displaying the message to the user.")] |
||||
void CreateCommand() |
||||
{ |
||||
commandCreated = true; |
||||
try { |
||||
string link = codon.Properties["link"]; |
||||
ICommand menuCommand; |
||||
if (link != null && link.Length > 0) { |
||||
if (MenuService.LinkCommandCreator == null) |
||||
throw new NotSupportedException("MenuCommand.LinkCommandCreator is not set, cannot create LinkCommands."); |
||||
menuCommand = MenuService.LinkCommandCreator(codon.Properties["link"]); |
||||
} else { |
||||
menuCommand = (ICommand)codon.AddIn.CreateObject(codon.Properties["class"]); |
||||
} |
||||
if (menuCommand != null) { |
||||
menuCommand.Owner = caller; |
||||
} |
||||
addInCommand = menuCommand; |
||||
} catch (Exception e) { |
||||
MessageService.ShowError(e, "Can't create menu command : " + codon.Id); |
||||
} |
||||
} |
||||
|
||||
public event EventHandler CanExecuteChanged { |
||||
add { CommandManager.RequerySuggested += value; } |
||||
remove { CommandManager.RequerySuggested -= value; } |
||||
} |
||||
|
||||
public void Execute(object parameter) |
||||
{ |
||||
if (!commandCreated) { |
||||
CreateCommand(); |
||||
} |
||||
LoggingService.Debug("Execute " + codon.Id); |
||||
if (CanExecute(parameter)) { |
||||
addInCommand.Run(); |
||||
} |
||||
} |
||||
|
||||
public bool CanExecute(object parameter) |
||||
{ |
||||
//LoggingService.Debug("CanExecute " + codon.Id);
|
||||
if (codon.GetFailedAction(caller) != ConditionFailedAction.Nothing) |
||||
return false; |
||||
if (!commandCreated) |
||||
return true; |
||||
if (addInCommand == null) |
||||
return false; |
||||
IMenuCommand menuCommand = addInCommand as IMenuCommand; |
||||
if (menuCommand != null) { |
||||
return menuCommand.IsEnabled; |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
class MenuCommand : CoreMenuItem |
||||
{ |
||||
public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand) : base(codon, caller) |
||||
{ |
||||
this.Command = new CommandWrapper(codon, caller, createCommand); |
||||
if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { |
||||
KeyGesture kg = MenuService.ParseShortcut(codon.Properties["shortcut"]); |
||||
inputBindingOwner.InputBindings.Add( |
||||
new InputBinding(this.Command, kg) |
||||
); |
||||
this.InputGestureText = kg.GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,157 @@
@@ -0,0 +1,157 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Creates WPF menu controls from the AddIn Tree.
|
||||
/// </summary>
|
||||
public static class MenuService |
||||
{ |
||||
public static void UpdateStatus(IEnumerable menuItems) |
||||
{ |
||||
if (menuItems == null) |
||||
return; |
||||
foreach (object o in menuItems) { |
||||
IStatusUpdate cmi = o as IStatusUpdate; |
||||
if (cmi != null) |
||||
cmi.UpdateStatus(); |
||||
} |
||||
} |
||||
|
||||
public static ContextMenu CreateContextMenu(object owner, string addInTreePath) |
||||
{ |
||||
ContextMenu menu = new ContextMenu(); |
||||
menu.ItemsSource = CreateMenuItems(menu, owner, addInTreePath); |
||||
return menu; |
||||
} |
||||
|
||||
internal static ContextMenu CreateContextMenu(IList subItems) |
||||
{ |
||||
var contextMenu = new ContextMenu() { |
||||
ItemsSource = new object[1] |
||||
}; |
||||
contextMenu.Opened += (sender, args) => { |
||||
contextMenu.ItemsSource = ExpandMenuBuilders(subItems); |
||||
args.Handled = true; |
||||
}; |
||||
return contextMenu; |
||||
} |
||||
|
||||
public static IList CreateMenuItems(UIElement inputBindingOwner, object owner, string addInTreePath) |
||||
{ |
||||
return CreateMenuItems(inputBindingOwner, AddInTree.BuildItems<MenuItemDescriptor>(addInTreePath, owner, false)); |
||||
} |
||||
|
||||
sealed class MenuItemBuilderPlaceholder |
||||
{ |
||||
readonly IMenuItemBuilder builder; |
||||
readonly Codon codon; |
||||
readonly object caller; |
||||
|
||||
public MenuItemBuilderPlaceholder(IMenuItemBuilder builder, Codon codon, object caller) |
||||
{ |
||||
this.builder = builder; |
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
} |
||||
|
||||
public ICollection BuildItems() |
||||
{ |
||||
return builder.BuildItems(codon, caller); |
||||
} |
||||
} |
||||
|
||||
internal static IList CreateMenuItems(UIElement inputBindingOwner, IEnumerable descriptors) |
||||
{ |
||||
ArrayList result = new ArrayList(); |
||||
foreach (MenuItemDescriptor descriptor in descriptors) { |
||||
result.Add(CreateMenuItemFromDescriptor(inputBindingOwner, descriptor)); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
internal static IList ExpandMenuBuilders(ICollection input) |
||||
{ |
||||
ArrayList result = new ArrayList(input.Count); |
||||
foreach (object o in input) { |
||||
MenuItemBuilderPlaceholder p = o as MenuItemBuilderPlaceholder; |
||||
if (p != null) { |
||||
ICollection c = p.BuildItems(); |
||||
if (c != null) |
||||
result.AddRange(c); |
||||
} else { |
||||
result.Add(o); |
||||
IStatusUpdate statusUpdate = o as IStatusUpdate; |
||||
if (statusUpdate != null) { |
||||
statusUpdate.UpdateStatus(); |
||||
statusUpdate.UpdateText(); |
||||
} |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
static object CreateMenuItemFromDescriptor(UIElement inputBindingOwner, MenuItemDescriptor descriptor) |
||||
{ |
||||
Codon codon = descriptor.Codon; |
||||
string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Command"; |
||||
bool createCommand = codon.Properties["loadclasslazy"] == "false"; |
||||
|
||||
switch (type) { |
||||
case "Separator": |
||||
return new ConditionalSeparator(codon, descriptor.Caller, false); |
||||
case "CheckBox": |
||||
return "CheckBox"; |
||||
//return new MenuCheckBox(codon, descriptor.Caller);
|
||||
case "Item": |
||||
case "Command": |
||||
return new MenuCommand(inputBindingOwner, codon, descriptor.Caller, createCommand); |
||||
case "Menu": |
||||
var item = new CoreMenuItem(codon, descriptor.Caller) { |
||||
ItemsSource = new object[1] |
||||
}; |
||||
var subItems = CreateMenuItems(inputBindingOwner, descriptor.SubItems); |
||||
item.SubmenuOpened += (sender, args) => { |
||||
item.ItemsSource = ExpandMenuBuilders(subItems); |
||||
args.Handled = true; |
||||
}; |
||||
return item; |
||||
case "Builder": |
||||
IMenuItemBuilder builder = codon.AddIn.CreateObject(codon.Properties["class"]) as IMenuItemBuilder; |
||||
if (builder == null) |
||||
throw new NotSupportedException("Menu item builder " + codon.Properties["class"] + " does not implement IMenuItemBuilder"); |
||||
return new MenuItemBuilderPlaceholder(builder, descriptor.Codon, descriptor.Caller); |
||||
default: |
||||
throw new System.NotSupportedException("unsupported menu item type : " + type); |
||||
} |
||||
} |
||||
|
||||
public static string ConvertLabel(string label) |
||||
{ |
||||
return label.Replace("_", "__").Replace("&", "_"); |
||||
} |
||||
|
||||
// HACK: find a better way to allow the host app to process link commands
|
||||
public static Converter<string, ICommand> LinkCommandCreator; |
||||
|
||||
/// <summary>
|
||||
/// Creates an KeyGesture for a shortcut.
|
||||
/// </summary>
|
||||
public static KeyGesture ParseShortcut(string text) |
||||
{ |
||||
return (KeyGesture)new KeyGestureConverter().ConvertFromInvariantString(text.Replace(',', '+').Replace('|', '+')); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Drawing; |
||||
using System.Runtime.InteropServices; |
||||
using System.Windows; |
||||
using System.Windows.Interop; |
||||
using System.Windows.Media.Imaging; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
static class NativeMethods |
||||
{ |
||||
[DllImport("gdi32.dll")] |
||||
[return: MarshalAs(UnmanagedType.Bool)] |
||||
public static extern bool DeleteObject(IntPtr hObject); |
||||
} |
||||
} |
@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
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 |
||||
{ |
||||
/// <summary>
|
||||
/// A WPF control that aligns its content on pixel boundaries.
|
||||
/// </summary>
|
||||
public class PixelSnapper : UIElement |
||||
{ |
||||
public PixelSnapper() |
||||
{ |
||||
} |
||||
|
||||
public PixelSnapper(UIElement visualChild) |
||||
: this() |
||||
{ |
||||
this.Child = visualChild; |
||||
} |
||||
|
||||
UIElement _visualChild; |
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the visual child.
|
||||
/// </summary>
|
||||
public UIElement Child { |
||||
get { return _visualChild; } |
||||
set { |
||||
RemoveVisualChild(_visualChild); |
||||
_visualChild = value; |
||||
AddVisualChild(_visualChild); |
||||
InvalidateMeasure(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the visual child.
|
||||
/// </summary>
|
||||
protected override Visual GetVisualChild(int index) |
||||
{ |
||||
if (index == 0 && _visualChild != null) |
||||
return _visualChild; |
||||
else |
||||
throw new ArgumentOutOfRangeException("index"); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the number of visual children.
|
||||
/// </summary>
|
||||
protected override int VisualChildrenCount { |
||||
get { return _visualChild != null ? 1 : 0; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Measure the visual child.
|
||||
/// </summary>
|
||||
protected override Size MeasureCore(Size availableSize) |
||||
{ |
||||
if (_visualChild != null) { |
||||
_visualChild.Measure(availableSize); |
||||
return _visualChild.DesiredSize; |
||||
} else { |
||||
return base.MeasureCore(availableSize); |
||||
} |
||||
} |
||||
|
||||
protected override void ArrangeCore(Rect finalRect) |
||||
{ |
||||
base.ArrangeCore(finalRect); |
||||
if (_visualChild != null) { |
||||
_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 CheckLayout() |
||||
{ |
||||
Point pixelOffset = GetPixelOffset(); |
||||
if (!AreClose(pixelOffset, _pixelOffset)) { |
||||
InvalidateArrange(); |
||||
} |
||||
} |
||||
|
||||
// Gets the matrix that will convert a point from "above" the
|
||||
// coordinate space of a visual into the the coordinate space
|
||||
// "below" the visual.
|
||||
static Matrix GetVisualTransform(Visual v) |
||||
{ |
||||
if (v != null) { |
||||
Matrix m = Matrix.Identity; |
||||
|
||||
Transform transform = VisualTreeHelper.GetTransform(v); |
||||
if (transform != null) { |
||||
m *= transform.Value; |
||||
} |
||||
|
||||
Vector offset = VisualTreeHelper.GetOffset(v); |
||||
m.Translate(offset.X, offset.Y); |
||||
|
||||
return m; |
||||
} |
||||
|
||||
return Matrix.Identity; |
||||
} |
||||
|
||||
static Point ApplyVisualTransform(Point point, Visual v, bool inverse) |
||||
{ |
||||
if (v != null) { |
||||
Matrix visualTransform = GetVisualTransform(v); |
||||
if (inverse) |
||||
visualTransform.Invert(); |
||||
point = visualTransform.Transform(point); |
||||
} |
||||
return point; |
||||
} |
||||
|
||||
private Point GetPixelOffset() |
||||
{ |
||||
Point pixelOffset = new Point(); |
||||
|
||||
PresentationSource ps = PresentationSource.FromVisual(this); |
||||
if (ps != null) { |
||||
Visual rootVisual = ps.RootVisual; |
||||
|
||||
// Transform (0,0) from this element up to pixels.
|
||||
pixelOffset = this.TransformToAncestor(rootVisual).Transform(pixelOffset); |
||||
pixelOffset = ApplyVisualTransform(pixelOffset, rootVisual, false); |
||||
pixelOffset = ps.CompositionTarget.TransformToDevice.Transform(pixelOffset); |
||||
|
||||
// Round the origin to the nearest whole pixel.
|
||||
pixelOffset.X = Math.Round(pixelOffset.X); |
||||
pixelOffset.Y = Math.Round(pixelOffset.Y); |
||||
|
||||
// Transform the whole-pixel back to this element.
|
||||
pixelOffset = ps.CompositionTarget.TransformFromDevice.Transform(pixelOffset); |
||||
pixelOffset = ApplyVisualTransform(pixelOffset, rootVisual, true); |
||||
pixelOffset = rootVisual.TransformToDescendant(this).Transform(pixelOffset); |
||||
} |
||||
|
||||
return pixelOffset; |
||||
} |
||||
|
||||
static bool AreClose(Point point1, Point point2) |
||||
{ |
||||
return AreClose(point1.X, point2.X) && AreClose(point1.Y, point2.Y); |
||||
} |
||||
|
||||
static bool AreClose(double value1, double value2) |
||||
{ |
||||
if (value1 == value2) |
||||
{ |
||||
return true; |
||||
} |
||||
double delta = value1 - value2; |
||||
return ((delta < 1.53E-06) && (delta > -1.53E-06)); |
||||
} |
||||
|
||||
private Point _pixelOffset; |
||||
} |
||||
} |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Drawing; |
||||
using System.Runtime.InteropServices; |
||||
using System.Windows; |
||||
using System.Windows.Interop; |
||||
using System.Windows.Media.Imaging; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Creates WPF BitmapSource objects from images in the ResourceService.
|
||||
/// </summary>
|
||||
public static class PresentationResourceService |
||||
{ |
||||
static readonly Dictionary<string, BitmapSource> bitmapCache = new Dictionary<string, BitmapSource>(); |
||||
|
||||
static PresentationResourceService() |
||||
{ |
||||
ResourceService.ClearCaches += ResourceService_ClearCaches; |
||||
} |
||||
|
||||
static void ResourceService_ClearCaches(object sender, EventArgs e) |
||||
{ |
||||
lock (bitmapCache) { |
||||
bitmapCache.Clear(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new System.Windows.Controls.Image object containing the image with the
|
||||
/// specified resource name.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name of the requested bitmap.
|
||||
/// </param>
|
||||
/// <exception cref="ResourceNotFoundException">
|
||||
/// Is thrown when the GlobalResource manager can't find a requested resource.
|
||||
/// </exception>
|
||||
public static System.Windows.Controls.Image GetImage(string name) |
||||
{ |
||||
return new System.Windows.Controls.Image { |
||||
Source = GetBitmapSource(name) |
||||
}; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new PixelSnapper object containing the image with the
|
||||
/// specified resource name.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name of the requested bitmap.
|
||||
/// </param>
|
||||
/// <exception cref="ResourceNotFoundException">
|
||||
/// Is thrown when the GlobalResource manager can't find a requested resource.
|
||||
/// </exception>
|
||||
public static PixelSnapper GetPixelSnappedImage(string name) |
||||
{ |
||||
return new PixelSnapper(GetImage(name)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns a BitmapSource from the resource database, it handles localization
|
||||
/// transparent for the user.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name of the requested bitmap.
|
||||
/// </param>
|
||||
/// <exception cref="ResourceNotFoundException">
|
||||
/// Is thrown when the GlobalResource manager can't find a requested resource.
|
||||
/// </exception>
|
||||
public static BitmapSource GetBitmapSource(string name) |
||||
{ |
||||
lock (bitmapCache) { |
||||
BitmapSource bs; |
||||
if (bitmapCache.TryGetValue(name, out bs)) |
||||
return bs; |
||||
System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)ResourceService.GetImageResource(name); |
||||
if (bmp == null) { |
||||
throw new ResourceNotFoundException(name); |
||||
} |
||||
IntPtr hBitmap = bmp.GetHbitmap(); |
||||
try { |
||||
bs = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, |
||||
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); |
||||
bs.Freeze(); |
||||
bitmapCache[name] = bs; |
||||
} finally { |
||||
NativeMethods.DeleteObject(hBitmap); |
||||
} |
||||
return bs; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
using System.Windows; |
||||
using System.Windows.Markup; |
||||
|
||||
[assembly: CLSCompliant(true)] |
||||
[assembly: StringFreezing()] |
||||
|
||||
[assembly: AssemblyTitle("ICSharpCode.Core.Presentation")] |
||||
[assembly: AssemblyDescription("ICSharpCode.Core, Windows Presentation Foundation implementation")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
[assembly: ThemeInfo( |
||||
ResourceDictionaryLocation.SourceAssembly, //where theme specific resource dictionaries are located
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
)] |
||||
|
||||
[assembly: XmlnsPrefix("http://icsharpcode.net/sharpdevelop/core", "core")] |
||||
[assembly: XmlnsDefinition("http://icsharpcode.net/sharpdevelop/core", "ICSharpCode.Core.Presentation")] |
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Windows.Shapes; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// A button with drop-down menu.
|
||||
/// </summary>
|
||||
public class SplitButton : ButtonBase |
||||
{ |
||||
public static readonly DependencyProperty DropDownMenuProperty |
||||
= DependencyProperty.Register("DropDownMenu", typeof(ContextMenu), |
||||
typeof(SplitButton), new FrameworkPropertyMetadata(null)); |
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] |
||||
protected static readonly DependencyPropertyKey IsDropDownMenuOpenPropertyKey |
||||
= DependencyProperty.RegisterReadOnly("IsDropDownMenuOpen", typeof(bool), |
||||
typeof(SplitButton), new FrameworkPropertyMetadata(false)); |
||||
|
||||
public static readonly DependencyProperty IsDropDownMenuOpenProperty = IsDropDownMenuOpenPropertyKey.DependencyProperty; |
||||
|
||||
static SplitButton() |
||||
{ |
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(SplitButton), new FrameworkPropertyMetadata(typeof(SplitButton))); |
||||
} |
||||
|
||||
public ContextMenu DropDownMenu { |
||||
get { return (ContextMenu)GetValue(DropDownMenuProperty); } |
||||
set { SetValue(DropDownMenuProperty, value); } |
||||
} |
||||
|
||||
public bool IsDropDownMenuOpen { |
||||
get { return (bool)GetValue(IsDropDownMenuOpenProperty); } |
||||
protected set { SetValue(IsDropDownMenuOpenPropertyKey, value); } |
||||
} |
||||
|
||||
FrameworkElement dropDownButton; |
||||
|
||||
public override void OnApplyTemplate() |
||||
{ |
||||
base.OnApplyTemplate(); |
||||
dropDownButton = (FrameworkElement)Template.FindName("PART_DropDownButton", this); |
||||
} |
||||
|
||||
bool IsOverDropDownButton(MouseEventArgs e) |
||||
{ |
||||
if (dropDownButton == null) |
||||
return false; |
||||
return e.GetPosition(dropDownButton).X >= 0; |
||||
} |
||||
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
||||
{ |
||||
if (IsOverDropDownButton(e)) { |
||||
e.Handled = true; |
||||
if (DropDownMenu != null) { |
||||
DropDownMenu.Placement = PlacementMode.Bottom; |
||||
DropDownMenu.PlacementTarget = this; |
||||
DropDownMenu.IsOpen = true; |
||||
DropDownMenu.Closed += DropDownMenu_Closed; |
||||
this.IsDropDownMenuOpen = true; |
||||
} |
||||
} else { |
||||
base.OnMouseLeftButtonDown(e); |
||||
} |
||||
} |
||||
|
||||
void DropDownMenu_Closed(object sender, RoutedEventArgs e) |
||||
{ |
||||
((ContextMenu)sender).Closed -= DropDownMenu_Closed; |
||||
this.IsDropDownMenuOpen = false; |
||||
} |
||||
|
||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) |
||||
{ |
||||
if (!IsMouseCaptured && IsOverDropDownButton(e)) { |
||||
e.Handled = true; |
||||
} else { |
||||
base.OnMouseLeftButtonUp(e); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// A tool bar button based on the AddIn-tree.
|
||||
/// </summary>
|
||||
sealed class ToolBarButton : Button, IStatusUpdate |
||||
{ |
||||
readonly Codon codon; |
||||
readonly object caller; |
||||
|
||||
public ToolBarButton(Codon codon, object caller, bool createCommand) |
||||
{ |
||||
ToolTipService.SetShowOnDisabled(this, true); |
||||
|
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
this.Command = new CommandWrapper(codon, caller, createCommand); |
||||
|
||||
if (codon.Properties.Contains("icon")) { |
||||
var image = PresentationResourceService.GetImage(StringParser.Parse(codon.Properties["icon"])); |
||||
image.Height = 16; |
||||
image.SetResourceReference(StyleProperty, ToolBarService.ImageStyleKey); |
||||
this.Content = new PixelSnapper(image); |
||||
} |
||||
UpdateText(); |
||||
|
||||
SetResourceReference(FrameworkElement.StyleProperty, ToolBar.ButtonStyleKey); |
||||
} |
||||
|
||||
public void UpdateText() |
||||
{ |
||||
if (codon.Properties.Contains("label")){ |
||||
this.Content = StringParser.Parse(codon.Properties["label"]); |
||||
} |
||||
if (codon.Properties.Contains("tooltip")) { |
||||
this.ToolTip = StringParser.Parse(codon.Properties["tooltip"]); |
||||
} |
||||
} |
||||
|
||||
public void UpdateStatus() |
||||
{ |
||||
if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude) |
||||
this.Visibility = Visibility.Collapsed; |
||||
else |
||||
this.Visibility = Visibility.Visible; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
sealed class ToolBarComboBox : ComboBox |
||||
{ |
||||
IComboBoxCommand menuCommand; |
||||
|
||||
public ToolBarComboBox(Codon codon, object caller) |
||||
{ |
||||
if (codon == null) |
||||
throw new ArgumentNullException("codon"); |
||||
this.IsEditable = false; |
||||
menuCommand = (IComboBoxCommand)codon.AddIn.CreateObject(codon.Properties["class"]); |
||||
menuCommand.Owner = this; |
||||
|
||||
SetResourceReference(FrameworkElement.StyleProperty, ToolBar.ComboBoxStyleKey); |
||||
} |
||||
|
||||
protected override void OnSelectionChanged(SelectionChangedEventArgs e) |
||||
{ |
||||
base.OnSelectionChanged(e); |
||||
menuCommand.Run(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Windows.Controls; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// Creates WPF toolbars from the AddIn Tree.
|
||||
/// </summary>
|
||||
public static class ToolBarService |
||||
{ |
||||
/// <summary>
|
||||
/// Style key used for toolbar images.
|
||||
/// </summary>
|
||||
public static readonly object ImageStyleKey = new object(); |
||||
|
||||
public static void UpdateStatus(IEnumerable toolBarItems) |
||||
{ |
||||
MenuService.UpdateStatus(toolBarItems); |
||||
} |
||||
|
||||
public static IList CreateToolBarItems(object owner, string addInTreePath) |
||||
{ |
||||
return CreateToolBarItems(AddInTree.BuildItems<ToolbarItemDescriptor>(addInTreePath, owner, false)); |
||||
} |
||||
|
||||
static IList CreateToolBarItems(IEnumerable descriptors) |
||||
{ |
||||
ArrayList result = new ArrayList(); |
||||
foreach (ToolbarItemDescriptor descriptor in descriptors) { |
||||
object item = CreateToolBarItemFromDescriptor(descriptor); |
||||
if (item is IMenuItemBuilder) { |
||||
IMenuItemBuilder submenuBuilder = (IMenuItemBuilder)item; |
||||
result.AddRange(submenuBuilder.BuildItems(descriptor.Codon, descriptor.Caller)); |
||||
} else { |
||||
result.Add(item); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
static object CreateToolBarItemFromDescriptor(ToolbarItemDescriptor descriptor) |
||||
{ |
||||
Codon codon = descriptor.Codon; |
||||
object caller = descriptor.Caller; |
||||
string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Item"; |
||||
|
||||
bool createCommand = codon.Properties["loadclasslazy"] == "false"; |
||||
|
||||
switch (type) { |
||||
case "Separator": |
||||
return new ConditionalSeparator(codon, caller, true); |
||||
case "CheckBox": |
||||
return "CheckBox"; |
||||
//return new ToolBarCheckBox(codon, caller);
|
||||
case "Item": |
||||
return new ToolBarButton(codon, caller, createCommand); |
||||
case "ComboBox": |
||||
return new ToolBarComboBox(codon, caller); |
||||
case "TextBox": |
||||
return "TextBox"; |
||||
//return new ToolBarTextBox(codon, caller);
|
||||
case "Label": |
||||
return "Label"; |
||||
//return new ToolBarLabel(codon, caller);
|
||||
case "DropDownButton": |
||||
return "DropDownButton"; |
||||
//return new ToolBarDropDownButton(codon, caller, MenuService.CreateMenuItems(descriptor.SubItems));
|
||||
case "SplitButton": |
||||
return new ToolBarSplitButton(codon, caller, MenuService.CreateMenuItems(null, descriptor.SubItems)); |
||||
case "Builder": |
||||
return codon.AddIn.CreateObject(codon.Properties["class"]); |
||||
default: |
||||
throw new System.NotSupportedException("unsupported menu item type : " + type); |
||||
} |
||||
} |
||||
|
||||
static ToolBar CreateToolBar(object owner, AddInTreeNode treeNode) |
||||
{ |
||||
ToolBar tb = new ToolBar(); |
||||
tb.ItemsSource = CreateToolBarItems(treeNode.BuildChildItems<ToolbarItemDescriptor>(owner)); |
||||
UpdateStatus(tb.ItemsSource); // setting Visible is only possible after the items have been added
|
||||
//new LanguageChangeWatcher(toolStrip);
|
||||
return tb; |
||||
} |
||||
|
||||
public static ToolBar CreateToolBar(object owner, string addInTreePath) |
||||
{ |
||||
return CreateToolBar(owner, AddInTree.GetTreeNode(addInTreePath)); |
||||
} |
||||
|
||||
public static ToolBar[] CreateToolBars(object owner, string addInTreePath) |
||||
{ |
||||
AddInTreeNode treeNode; |
||||
try { |
||||
treeNode = AddInTree.GetTreeNode(addInTreePath); |
||||
} catch (TreePathNotFoundException) { |
||||
return null; |
||||
} |
||||
List<ToolBar> toolBars = new List<ToolBar>(); |
||||
foreach (AddInTreeNode childNode in treeNode.ChildNodes.Values) { |
||||
toolBars.Add(CreateToolBar(owner, childNode)); |
||||
} |
||||
return toolBars.ToArray(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
|
||||
namespace ICSharpCode.Core.Presentation |
||||
{ |
||||
/// <summary>
|
||||
/// A tool bar button based on the AddIn-tree.
|
||||
/// </summary>
|
||||
sealed class ToolBarSplitButton : SplitButton, IStatusUpdate |
||||
{ |
||||
ICommand menuCommand; |
||||
object caller; |
||||
Codon codon; |
||||
|
||||
public ToolBarSplitButton(Codon codon, object caller, IList submenu) |
||||
{ |
||||
ToolTipService.SetShowOnDisabled(this, true); |
||||
|
||||
this.codon = codon; |
||||
this.caller = caller; |
||||
|
||||
if (codon.Properties.Contains("icon")) { |
||||
var image = PresentationResourceService.GetImage(StringParser.Parse(codon.Properties["icon"])); |
||||
image.Height = 16; |
||||
image.SetResourceReference(StyleProperty, ToolBarService.ImageStyleKey); |
||||
this.Content = new PixelSnapper(image); |
||||
} |
||||
|
||||
menuCommand = (ICommand)codon.AddIn.CreateObject(codon.Properties["class"]); |
||||
menuCommand.Owner = this; |
||||
|
||||
this.Command = new CommandWrapper(codon, caller, menuCommand); |
||||
this.DropDownMenu = MenuService.CreateContextMenu(submenu); |
||||
|
||||
UpdateText(); |
||||
} |
||||
|
||||
public void UpdateText() |
||||
{ |
||||
if (codon.Properties.Contains("label")){ |
||||
this.Content = StringParser.Parse(codon.Properties["label"]); |
||||
} |
||||
if (codon.Properties.Contains("tooltip")) { |
||||
this.ToolTip = StringParser.Parse(codon.Properties["tooltip"]); |
||||
} |
||||
} |
||||
|
||||
public void UpdateStatus() |
||||
{ |
||||
if (codon.GetFailedAction(caller) == ConditionFailedAction.Exclude) |
||||
this.Visibility = Visibility.Collapsed; |
||||
else |
||||
this.Visibility = Visibility.Visible; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:local="clr-namespace:ICSharpCode.Core.Presentation" |
||||
> |
||||
<Style TargetType="{x:Type local:SplitButton}"> |
||||
<Setter Property="TextElement.Foreground" Value = "{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> |
||||
<Setter Property="Control.Padding" Value="2,2,2,2"/> |
||||
<Setter Property="Border.BorderThickness" Value="1,1,1,1"/> |
||||
<Setter Property="Panel.Background" Value="Transparent"/> |
||||
<Setter Property="Border.BorderBrush" Value="Transparent"/> |
||||
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Center"/> |
||||
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center"/> |
||||
<Setter Property="Control.HorizontalContentAlignment" Value="Center"/> |
||||
<Setter Property="Control.VerticalContentAlignment" Value="Center"/> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="local:SplitButton" |
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"> |
||||
<Border |
||||
BorderThickness="{TemplateBinding Border.BorderThickness}" |
||||
BorderBrush="{TemplateBinding Border.BorderBrush}" |
||||
Background="{TemplateBinding Panel.Background}" |
||||
Name="OuterBorder" |
||||
SnapsToDevicePixels="True" |
||||
> |
||||
<StackPanel Orientation="Horizontal"> |
||||
<ContentPresenter |
||||
Margin="{TemplateBinding Control.Padding}" |
||||
Content="{TemplateBinding ContentControl.Content}" |
||||
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" |
||||
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" |
||||
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" |
||||
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" |
||||
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> |
||||
<Border |
||||
Name="PART_DropDownButton" |
||||
BorderThickness="1,0,0,0" |
||||
BorderBrush="{Binding ElementName=OuterBorder, Path=BorderBrush}" |
||||
SnapsToDevicePixels="True" |
||||
> |
||||
<Path Margin="2" |
||||
Data = "M0,0 L1,0 0.5,1 z" |
||||
Fill = "{TemplateBinding TextElement.Foreground}" |
||||
Width = "7" |
||||
Height = "3.5" |
||||
Stretch = "Fill"/> |
||||
</Border> |
||||
</StackPanel> |
||||
</Border> |
||||
<ControlTemplate.Triggers> |
||||
<Trigger Property="UIElement.IsMouseOver" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF3399FF" /> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FFC2E0FF"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="#FFC2E0FF"/> |
||||
</Trigger> |
||||
<Trigger Property="UIElement.IsKeyboardFocused" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF3399FF"/> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FFC2E0FF"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="#FFC2E0FF"/> |
||||
</Trigger> |
||||
<Trigger Property="ButtonBase.IsPressed" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF3399FF"/> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FF99CCFF"/> |
||||
</Trigger> |
||||
<Trigger Property="UIElement.IsEnabled" Value="False"> |
||||
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> |
||||
</Trigger> |
||||
<Trigger Property="local:SplitButton.IsDropDownMenuOpen" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" /> |
||||
<Setter Property="Border.BorderBrush" TargetName="PART_DropDownButton" Value="Transparent" /> |
||||
<Setter Property="Border.BorderThickness" TargetName="OuterBorder" Value="1,1,1,0" /> |
||||
<Setter Property="Border.Padding" TargetName="OuterBorder" Value="0,0,0,1" /> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="Transparent"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="Transparent"/> |
||||
</Trigger> |
||||
</ControlTemplate.Triggers> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
</ResourceDictionary> |
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:local="clr-namespace:ICSharpCode.Core.Presentation" |
||||
> |
||||
<Style TargetType="{x:Type local:SplitButton}"> |
||||
<Setter Property="TextElement.Foreground" Value = "{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> |
||||
<Setter Property="Control.Padding" Value="2,2,2,2"/> |
||||
<Setter Property="Border.BorderThickness" Value="1,1,1,1"/> |
||||
<Setter Property="Panel.Background" Value="Transparent"/> |
||||
<Setter Property="Border.BorderBrush" Value="Transparent"/> |
||||
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Center"/> |
||||
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center"/> |
||||
<Setter Property="Control.HorizontalContentAlignment" Value="Center"/> |
||||
<Setter Property="Control.VerticalContentAlignment" Value="Center"/> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="local:SplitButton" |
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"> |
||||
<Border |
||||
BorderThickness="{TemplateBinding Border.BorderThickness}" |
||||
BorderBrush="{TemplateBinding Border.BorderBrush}" |
||||
Background="{TemplateBinding Panel.Background}" |
||||
Name="OuterBorder" |
||||
SnapsToDevicePixels="True" |
||||
> |
||||
<StackPanel Orientation="Horizontal"> |
||||
<ContentPresenter |
||||
Margin="{TemplateBinding Control.Padding}" |
||||
Content="{TemplateBinding ContentControl.Content}" |
||||
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" |
||||
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" |
||||
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" |
||||
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" |
||||
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> |
||||
<Border |
||||
Name="PART_DropDownButton" |
||||
BorderThickness="1,0,0,0" |
||||
BorderBrush="{Binding ElementName=OuterBorder, Path=BorderBrush}" |
||||
SnapsToDevicePixels="True" |
||||
> |
||||
<Path Margin="2" |
||||
Data = "M0,0 L1,0 0.5,1 z" |
||||
Fill = "{TemplateBinding TextElement.Foreground}" |
||||
Width = "7" |
||||
Height = "3.5" |
||||
Stretch = "Fill"/> |
||||
</Border> |
||||
</StackPanel> |
||||
</Border> |
||||
<ControlTemplate.Triggers> |
||||
<Trigger Property="UIElement.IsMouseOver" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF0A246A" /> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FFB6BDD2"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="#FFB6BDD2"/> |
||||
</Trigger> |
||||
<Trigger Property="UIElement.IsKeyboardFocused" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF0A246A"/> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FFB6BDD2"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="#FFB6BDD2"/> |
||||
</Trigger> |
||||
<Trigger Property="ButtonBase.IsPressed" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="#FF0A246A"/> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="#FF8592B5"/> |
||||
</Trigger> |
||||
<Trigger Property="UIElement.IsEnabled" Value="False"> |
||||
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> |
||||
</Trigger> |
||||
<Trigger Property="local:SplitButton.IsDropDownMenuOpen" Value="True"> |
||||
<Setter Property="Border.BorderBrush" TargetName="OuterBorder" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" /> |
||||
<Setter Property="Border.BorderBrush" TargetName="PART_DropDownButton" Value="Transparent" /> |
||||
<Setter Property="Border.BorderThickness" TargetName="OuterBorder" Value="1,1,1,0" /> |
||||
<Setter Property="Border.Padding" TargetName="OuterBorder" Value="0,0,0,1" /> |
||||
<Setter Property="Panel.Background" TargetName="OuterBorder" Value="Transparent"/> |
||||
<Setter Property="Panel.Background" TargetName="PART_DropDownButton" Value="Transparent"/> |
||||
</Trigger> |
||||
</ControlTemplate.Triggers> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
</ResourceDictionary> |
Loading…
Reference in new issue