mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Moved skin designer from plugin to application. Implemented many things.
This commit is contained in:
48
RainmeterStudio/Editor/SkinDesigner/Controls/HoverAdorner.cs
Normal file
48
RainmeterStudio/Editor/SkinDesigner/Controls/HoverAdorner.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
30
RainmeterStudio/Editor/SkinDesigner/SkinDesignerFactory.cs
Normal file
30
RainmeterStudio/Editor/SkinDesigner/SkinDesignerFactory.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
95
RainmeterStudio/Editor/SkinDesigner/SkinDesignerUI.xaml
Normal file
95
RainmeterStudio/Editor/SkinDesigner/SkinDesignerUI.xaml
Normal 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>
|
102
RainmeterStudio/Editor/SkinDesigner/SkinDesignerUI.xaml.cs
Normal file
102
RainmeterStudio/Editor/SkinDesigner/SkinDesignerUI.xaml.cs
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
92
RainmeterStudio/Editor/SkinDesigner/SkinDocument.cs
Normal file
92
RainmeterStudio/Editor/SkinDesigner/SkinDocument.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
34
RainmeterStudio/Editor/SkinDesigner/SkinStorage.cs
Normal file
34
RainmeterStudio/Editor/SkinDesigner/SkinStorage.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user