//Copyright 2012-2019 Keysight Technologies
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
using Keysight.OpenTap.Wpf;
using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace OpenTap.Plugins.PluginDevelopment
{
// This example shows how to create a custom IControlProvider implementation.
// This is a WPF specific extension to the Editor application that allows
// adding custom controls to property grids.
//
// In this example it will be shown how to display a picture in the settings of a test step in a generic way.
//
// In practice it should rarely be necessesary to add custom controls, but for some use cases it can be convenient.
// For more flexible and platform independent extensions, consider adding custom annotations instead.
//
///
/// This control provider displays a string as an image when the PictureAttribute is used.
///
[Display("Picture Control Provider", Group: "Example")]
public class PictureControlProvider : IControlProvider
{
/// Select a fairly high order value.
public double Order => 21;
///
/// If the member has a PictureAttribute and it support being a string value, then it can probably be loaded as an image.
///
///
///
public FrameworkElement CreateControl(AnnotationCollection annotation)
{
// [Picture] is used.
bool ispic = annotation.Get()?.Member.HasAttribute() ?? false;
if (ispic == false) return null;
// It is something that acts like a string.
var stringValueProvider = annotation.Get();
if (stringValueProvider == null) return null;
// create a WPF image control.
var img = new Image();
BindingOperations.SetBinding(img, Image.SourceProperty,
new Binding(nameof(IStringValueAnnotation.Value))
{
Source = stringValueProvider,
Converter = new FileToImageConverter() // this converter converts a file path (local or web) to an image source.
});
// ** Performance Notice **
// This way of showing an image is quite slow. If it is a large image from a slow network drive it could cause the GUI to lag whenever the step is selected.
// consider adding in memory caching of that is the case. For brevity this is not shown here.
//
// Get updates when changes happen to the annotation. For example when the value has changed.
var update = annotation.Get(true);
if(update != null)
{
// When the value changes explicitly reload the SourceProperty of the image.
update.RegisterSourceUpdated(img, () => img.GetBindingExpression(Image.SourceProperty).UpdateTarget());
}
return img;
}
/// Slow but simple URI to image converter.
class FileToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string path = (string)value;
if (string.IsNullOrWhiteSpace(path)) return null;
try
{
// this could also be a url.
if (File.Exists(Path.GetFullPath(path)))
path = Path.GetFullPath(path);
}
catch
{
}
try
{
return new BitmapImage(new Uri(path), new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.CacheIfAvailable));
}
catch
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException(); // this is not needed.
}
}
}
/// The PictureAttribute is used to mark that a string should be shown as a picture.
public class PictureAttribute : Attribute
{
}
[Display("Step With Picture", "This test step shows a picture", Groups: new[] { "Examples", "Plugin Development", "GUI" })]
public class StepWithPicture : TestStep
{
[Picture] // 'Picture' should be shown as a picture.
[Layout(LayoutMode.FullRow)] // Hide the name of the setting.
public string Picture { get; set; }
/// The path to the picture, this can be a local file path or a HTTP address.
[FilePath]
[Display("Path")]
public string Path
{
get { return Picture; }
set { Picture = value; }
}
[Browsable(true)]
public void ListAllControlProviders()
{
// it can sometimes be useful to list all plugins of a kind to see the order in which they are used.
Log.Info("Listing Control Providers:");
foreach (var controlProvider in PluginManager.GetPlugins().Select(x => (IControlProvider)Activator.CreateInstance(x)).ToArray().OrderBy(x => x.Order))
{
Log.Info("{0} : {1}", controlProvider.Order, controlProvider.ToString());
}
}
public override void Run()
{
}
}
}