Moved skin designer from plugin to application. Implemented many things.

This commit is contained in:
2014-10-11 10:38:47 +03:00
parent 180e4bb9fd
commit 7ed85169e8
30 changed files with 638 additions and 1041 deletions

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace RainmeterStudio.Editor.SkinDesigner.Controls
{
public class HoverAdorner : Adorner
{
public HoverAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
// Calculate DPI factor
Matrix matrix = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
double dpiFactor = 1.0 / matrix.M11;
// Rectangle
Rect rect = new Rect(AdornedElement.DesiredSize);
Rect selectionRect = new Rect(rect.X - 1, rect.Y - 1, rect.Width + 2, rect.Height + 2);
// Create pen
Pen pen = new Pen(Brushes.Gray, 1 * dpiFactor);
pen.DashStyle = DashStyles.Dash;
// Create a guidelines set for on-pixel drawing
GuidelineSet guidelines = new GuidelineSet();
guidelines.GuidelinesX.Add(selectionRect.Left + pen.Thickness / 2);
guidelines.GuidelinesX.Add(selectionRect.Right + pen.Thickness / 2);
guidelines.GuidelinesY.Add(selectionRect.Top + pen.Thickness / 2);
guidelines.GuidelinesY.Add(selectionRect.Bottom + pen.Thickness / 2);
// Draw
drawingContext.PushGuidelineSet(guidelines);
drawingContext.DrawRectangle(null, pen, selectionRect);
drawingContext.Pop();
}
}
}

View File

@ -0,0 +1,11 @@
<UserControl x:Class="RainmeterStudio.Editor.SkinDesigner.Controls.MeterControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Canvas Name="canvas">
</Canvas>
</UserControl>

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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;
using RainmeterStudio.Rainmeter;
namespace RainmeterStudio.Editor.SkinDesigner.Controls
{
/// <summary>
/// Interaction logic for MeterControl.xaml
/// </summary>
public partial class MeterControl : UserControl
{
private Skin _skin;
/// <summary>
/// Gets or sets the skin being edited
/// </summary>
public Skin Skin
{
get
{
return Skin;
}
set
{
_skin = value;
Reset();
}
}
/// <summary>
/// Gets an enumerable with the meter items
/// </summary>
public IEnumerable<Meter> Items { get { return Skin.Meters; } }
/// <summary>
/// Gets a collection with the currently selected items
/// </summary>
public ObservableCollection<Meter> SelectedItems { get; private set; }
/// <summary>
/// Gets or sets the currently selected item
/// </summary>
public Meter SelectedItem { get; set; }
/// <summary>
/// Gets or sets the selected item index
/// </summary>
public int SelectedIndex { get; set; }
/// <summary>
/// Initializes the meter control
/// </summary>
public MeterControl()
{
InitializeComponent();
Loaded += MeterControl_Loaded;
}
void MeterControl_Loaded(object sender, RoutedEventArgs e)
{
//AdornerLayer.GetAdornerLayer(ellipse).Add(new SelectAdorner(ellipse));
}
private void Reset()
{
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace RainmeterStudio.Editor.SkinDesigner.Controls
{
public class SelectAdorner : Adorner
{
public SelectAdorner(UIElement adornedElement)
: base(adornedElement)
{
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
// Calculate DPI factor
Matrix matrix = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
double dpiFactor = 1.0 / matrix.M11;
// Rectangle
Rect rect = new Rect(AdornedElement.DesiredSize);
Rect selectionRect = new Rect(rect.X - 1, rect.Y - 1, rect.Width + 2, rect.Height + 2);
// Create pen
Pen pen = new Pen(Brushes.Blue, 1 * dpiFactor);
// Create a guidelines set for on-pixel drawing
GuidelineSet guidelines = new GuidelineSet();
guidelines.GuidelinesX.Add(selectionRect.Left + pen.Thickness / 2);
guidelines.GuidelinesX.Add(selectionRect.Right + pen.Thickness / 2);
guidelines.GuidelinesY.Add(selectionRect.Top + pen.Thickness / 2);
guidelines.GuidelinesY.Add(selectionRect.Bottom + pen.Thickness / 2);
// Draw
drawingContext.PushGuidelineSet(guidelines);
drawingContext.DrawRectangle(null, pen, selectionRect);
drawingContext.Pop();
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RainmeterStudio.Core;
using RainmeterStudio.Core.Editor;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.Editor.SkinDesigner
{
/// <summary>
/// Creates skin designers
/// </summary>
[PluginExport]
public class SkinDesignerFactory : IDocumentEditorFactory
{
/// <inheritdoc />
public IDocumentEditor CreateEditor(IDocument document)
{
return new SkinDesignerUI((SkinDocument)document);
}
/// <inheritdoc />
public bool CanEdit(Type type)
{
return type == typeof(SkinDocument);
}
}
}

View File

@ -0,0 +1,95 @@
<UserControl x:Class="RainmeterStudio.Editor.SkinDesigner.SkinDesignerUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sd="clr-namespace:RainmeterStudio.Editor.SkinDesigner"
xmlns:sdcontrols="clr-namespace:RainmeterStudio.Editor.SkinDesigner.Controls"
xmlns:b="clr-namespace:RainmeterStudio.Business"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<Style x:Key="MeasuresListViewStyle" TargetType="ListView">
<Style.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<Grid>
<TextBlock TextAlignment="Center"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextWrapping="Wrap"
Text="There are no measures in this skin. You can drag measures from the toolbox." />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<b:ImageResourceConverter x:Key="ResourceConverter" />
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<!-- TODO: zoom -->
<ScrollViewer Grid.Column="0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" >
<ScrollViewer.Background>
<ImageBrush ImageSource="/Resources/Graphics/transparent_background.png"
Stretch="None" TileMode="Tile"
AlignmentX="Center" AlignmentY="Center"
Viewport="0,0,16,16"
ViewportUnits="Absolute" />
</ScrollViewer.Background>
<sdcontrols:MeterControl x:Name="meterControl" />
</ScrollViewer>
<GridSplitter Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="LightGray"/>
<Border Grid.Column="1" Background="#eee"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="0,10,0,10"
CornerRadius="0,0,20,0">
<TextBlock Text="Meters">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
<Border Grid.Column="1" Background="#eee"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Padding="0,10,0,10"
CornerRadius="20,0,0,0">
<TextBlock Text="Measures">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90" />
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
<ListView Name="listMeasures" Grid.Column="2"
Style="{StaticResource MeasuresListViewStyle}">
</ListView>
</Grid>
</UserControl>

View File

@ -0,0 +1,102 @@
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;
using RainmeterStudio.Core.Editor;
using RainmeterStudio.Core.Editor.Features;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.Editor.SkinDesigner
{
/// <summary>
/// Interaction logic for SkinDesignerUI.xaml
/// </summary>
public partial class SkinDesignerUI : UserControl, IDocumentEditor, IToolboxProvider
{
private SkinDocument _document;
#region IDocumentEditor
/// <summary>
/// Gets the attached document
/// </summary>
public IDocument AttachedDocument
{
get { return _document; }
}
/// <summary>
/// Gets the Editor UI
/// </summary>
public UIElement EditorUI
{
get { return this; }
}
#endregion
/// <summary>
/// Gets or sets the attached skin document
/// </summary>
public SkinDocument Document
{
get
{
return _document;
}
protected set
{
_document = value;
Reset();
}
}
/// <summary>
/// Initializes the skin designer UI
/// </summary>
/// <param name="document">Skin document to be edited</param>
public SkinDesignerUI(SkinDocument document)
{
InitializeComponent();
Document = document;
}
/// <summary>
/// Reloads everything
/// </summary>
private void Reset()
{
meterControl.Skin = Document.Skin;
}
public IEnumerable<ToolboxItem> ToolboxItems
{
get
{
yield return new ToolboxItem("Item 1");
yield return new ToolboxItem("Item 2");
yield return new ToolboxItem("Item 3");
yield return new ToolboxItem("Item 4");
}
}
public event EventHandler ToolboxItemsChanged;
public void ToolboxItemDrop(ToolboxItem item)
{
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Rainmeter;
namespace RainmeterStudio.Editor.SkinDesigner
{
public class SkinDocument : IDocument
{
private Skin _skin;
/// <summary>
/// Triggered when the value of a property changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#region IDocument
private Reference _reference;
private bool _isDirty;
/// <summary>
/// Gets or sets the reference to this document
/// </summary>
public Reference Reference
{
get
{
return _reference;
}
set
{
_reference = value;
if (PropertyChanged != null)
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Reference"));
}
}
/// <summary>
/// Gets or sets a value indicating if this document has unsaved changes
/// </summary>
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
if (PropertyChanged != null)
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("IsDirty"));
}
}
#endregion
/// <summary>
/// Gets or sets the skin
/// </summary>
public Skin Skin
{
get
{
return _skin;
}
set
{
_skin = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Skin"));
}
}
/// <summary>
/// Initializes this skin document
/// </summary>
public SkinDocument()
{
Skin = new Skin();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RainmeterStudio.Core;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.Editor.SkinDesigner
{
[PluginExport]
public class SkinDocumentEmptyTemplate : IDocumentTemplate
{
public string Name
{
get { return "Skin"; }
}
public string DefaultExtension
{
get { return "rsskin"; }
}
public IEnumerable<Property> Properties
{
get { yield break; }
}
public IDocument CreateDocument()
{
return new SkinDocument();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RainmeterStudio.Core;
using RainmeterStudio.Core.Storage;
namespace RainmeterStudio.Editor.SkinDesigner
{
[PluginExport]
public class SkinStorage : IDocumentStorage
{
public Core.Model.IDocument ReadDocument(string path)
{
return new SkinDocument();
}
public void WriteDocument(Core.Model.IDocument document, string path)
{
}
public bool CanReadDocument(string path)
{
return Path.GetExtension(path) == ".rsskin";
}
public bool CanWriteDocument(Type documentType)
{
return documentType == typeof(SkinDocument);
}
}
}