/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using dnSpy.Contracts.Images; namespace dnSpy.Contracts.Menus { /// /// Menu item base class, implements /// public abstract class MenuItemBase : IMenuItem { /// public abstract void Execute(IMenuItemContext context); /// public virtual bool IsEnabled(IMenuItemContext context) => true; /// public virtual bool IsVisible(IMenuItemContext context) => true; /// public virtual string? GetHeader(IMenuItemContext context) => null; /// public virtual ImageReference? GetIcon(IMenuItemContext context) => null; /// public virtual string? GetInputGestureText(IMenuItemContext context) => null; /// public virtual bool IsChecked(IMenuItemContext context) => false; } /// /// Menu item base class, implements /// /// Context type public abstract class MenuItemBase : IMenuItem where TContext : class { /// /// Creates the context /// /// Menu item context /// protected abstract TContext? CreateContext(IMenuItemContext context); /// /// Gets the context key. Should be a unique value per class, eg. an /// protected abstract object CachedContextKey { get; } /// /// Gets the cached context /// /// Menu item context /// protected TContext? GetCachedContext(IMenuItemContext context) { var key = CachedContextKey; if (key is null) return CreateContext(context); return context.GetOrCreateState(key, () => CreateContext(context)!); } void IMenuItem.Execute(IMenuItemContext context) { var ctx = GetCachedContext(context); if (ctx is not null) Execute(ctx); } bool IMenuItem.IsEnabled(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null && IsEnabled(ctx); } bool IMenuItem.IsVisible(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null && IsVisible(ctx); } string? IMenuItem.GetHeader(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null ? GetHeader(ctx) : null; } ImageReference? IMenuItem.GetIcon(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null ? GetIcon(ctx) : null; } string? IMenuItem.GetInputGestureText(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null ? GetInputGestureText(ctx) : null; } bool IMenuItem.IsChecked(IMenuItemContext context) { var ctx = GetCachedContext(context); return ctx is not null ? IsChecked(ctx) : false; } /// /// Executes the command /// /// Context public abstract void Execute(TContext context); /// /// Returns true if it's enabled /// /// Context /// public virtual bool IsEnabled(TContext context) => true; /// /// Returns true if it's visible. If false, none of the other methods get called /// /// Context /// public virtual bool IsVisible(TContext context) => true; /// /// Returns the header or null to use the default value from the attribute /// /// Context /// public virtual string? GetHeader(TContext context) => null; /// /// Returns the icon or null to use the default value from the attribute /// /// Context /// public virtual ImageReference? GetIcon(TContext context) => null; /// /// Returns the input gesture text or null to use the default value from the attribute /// /// Context /// public virtual string? GetInputGestureText(TContext context) => null; /// /// Returns true if it's checked /// /// Context /// public virtual bool IsChecked(TContext context) => false; } }