Implemented editable themes / master themes

This commit is contained in:
Ben
2015-07-05 22:43:17 +01:00
parent 511f503e88
commit bfa2341ab8
20 changed files with 354 additions and 89 deletions

View File

@@ -101,12 +101,12 @@
<Compile Include="Services\ThemeService.cs" />
<Compile Include="ViewModels\IThemeViewModelFactory.cs" />
<Compile Include="ViewModels\ThemeComponentViewModel.cs" />
<Compile Include="ViewModels\ThemeViewModel.cs" />
<Compile Include="ViewModels\ThemeEditorViewModel.cs" />
<Compile Include="Views\ThemeComponentControl.xaml.cs">
<DependentUpon>ThemeComponentControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ThemeControl.xaml.cs">
<DependentUpon>ThemeControl.xaml</DependentUpon>
<Compile Include="Views\ThemeEditorView.xaml.cs">
<DependentUpon>ThemeEditorView.xaml</DependentUpon>
</Compile>
<Compile Include="WindsorInstallers\ProvidersInstaller.cs" />
<Compile Include="WindsorInstallers\ServicesInstaller.cs" />
@@ -132,7 +132,7 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ThemeControl.xaml">
<Page Include="Views\ThemeEditorView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>

View File

@@ -1,4 +1,6 @@
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using AutoMapper;
using Filtration.ObjectModel;
using Filtration.ObjectModel.ThemeEditor;
@@ -9,10 +11,11 @@ namespace Filtration.ThemeEditor.Providers
{
public interface IThemeProvider
{
IThemeViewModel NewThemeForScript(ItemFilterScript script);
IThemeViewModel LoadThemeFromFile(string filePath);
IThemeEditorViewModel NewThemeForScript(ItemFilterScript script);
IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script);
IThemeEditorViewModel LoadThemeFromFile(string filePath);
Theme LoadThemeModelFromFile(string filePath);
void SaveTheme(IThemeViewModel themeViewModel, string filePath);
void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath);
}
internal class ThemeProvider : IThemeProvider
@@ -26,20 +29,35 @@ namespace Filtration.ThemeEditor.Providers
_themePersistenceService = themePersistenceService;
}
public IThemeViewModel NewThemeForScript(ItemFilterScript script)
public IThemeEditorViewModel NewThemeForScript(ItemFilterScript script)
{
var themeComponentViewModels = Mapper.Map<ObservableCollection<ThemeComponentViewModel>>(script.ThemeComponents);
var themeComponentCollection = script.ThemeComponents.Aggregate(new ThemeComponentCollection(),
(c, component) =>
{
c.Add(new ThemeComponent(component.ComponentType, component.ComponentName, component.Color));
return c;
});
var themeViewModel = _themeViewModelFactory.Create();
themeViewModel.Initialise(themeComponentViewModels, true);
themeViewModel.Initialise(themeComponentCollection, true);
themeViewModel.FilePath = "Untitled.filtertheme";
return themeViewModel;
}
public IThemeViewModel LoadThemeFromFile(string filePath)
public IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script)
{
var themeViewModel = _themeViewModelFactory.Create();
themeViewModel.Initialise(script.ThemeComponents, true);
themeViewModel.FilePath = "<Master Theme> " + Path.GetFileName(script.FilePath);
return themeViewModel;
}
public IThemeEditorViewModel LoadThemeFromFile(string filePath)
{
var model = _themePersistenceService.LoadTheme(filePath);
var viewModel = Mapper.Map<IThemeViewModel>(model);
var viewModel = Mapper.Map<IThemeEditorViewModel>(model);
viewModel.FilePath = filePath;
return viewModel;
}
@@ -49,9 +67,9 @@ namespace Filtration.ThemeEditor.Providers
return _themePersistenceService.LoadTheme(filePath);
}
public void SaveTheme(IThemeViewModel themeViewModel, string filePath)
public void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath)
{
var theme = Mapper.Map<Theme>(themeViewModel);
var theme = Mapper.Map<Theme>(themeEditorViewModel);
_themePersistenceService.SaveTheme(theme, filePath);
}
}

View File

@@ -2,7 +2,7 @@
{
public interface IThemeViewModelFactory
{
IThemeViewModel Create();
void Release(IThemeViewModel themeViewModel);
IThemeEditorViewModel Create();
void Release(IThemeEditorViewModel themeEditorViewModel);
}
}

View File

@@ -1,29 +1,36 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Filtration.Common.Services;
using Filtration.Common.ViewModels;
using Filtration.Interface;
using Filtration.ObjectModel.Enums;
using Filtration.ObjectModel.ThemeEditor;
using Filtration.ThemeEditor.Providers;
using GalaSoft.MvvmLight.CommandWpf;
using NLog;
using MessageBox = System.Windows.MessageBox;
namespace Filtration.ThemeEditor.ViewModels
{
public interface IThemeViewModel : IEditableDocument
public interface IThemeEditorViewModel : IEditableDocument
{
void Initialise(ObservableCollection<ThemeComponentViewModel> themeComponentViewModels, bool newTheme);
RelayCommand<ThemeComponentType> AddThemeComponentCommand { get; }
RelayCommand<ThemeComponent> DeleteThemeComponentCommand { get; }
void Initialise(ThemeComponentCollection themeComponentCollection, bool newTheme);
bool EditEnabled { get; }
string Title { get; }
string FilePath { get; set; }
string Filename { get; }
string Name { get; set; }
ObservableCollection<ThemeComponentViewModel> Components { get; set; }
ThemeComponentCollection Components { get; set; }
ThemeComponent SelectedThemeComponent { get; }
}
public class ThemeViewModel : PaneViewModel, IThemeViewModel
public class ThemeEditorViewModel : PaneViewModel, IThemeEditorViewModel
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
@@ -31,15 +38,17 @@ namespace Filtration.ThemeEditor.ViewModels
private readonly IMessageBoxService _messageBoxService;
private bool _filenameIsFake;
private string _filePath;
private ThemeComponent _selectedThemeComponent;
public ThemeViewModel(IThemeProvider themeProvider,
public ThemeEditorViewModel(IThemeProvider themeProvider,
IMessageBoxService messageBoxService)
{
_themeProvider = themeProvider;
_messageBoxService = messageBoxService;
Components = new ObservableCollection<ThemeComponentViewModel>();
AddThemeComponentCommand = new RelayCommand<ThemeComponentType>(OnAddThemeComponentCommand, t => EditEnabled);
DeleteThemeComponentCommand = new RelayCommand<ThemeComponent>(OnDeleteThemeComponentCommand,
t => EditEnabled && SelectedThemeComponent != null);
var icon = new BitmapImage();
icon.BeginInit();
@@ -48,9 +57,17 @@ namespace Filtration.ThemeEditor.ViewModels
IconSource = icon;
}
public void Initialise(ObservableCollection<ThemeComponentViewModel> themeComponentViewModels, bool newTheme)
public RelayCommand<ThemeComponentType> AddThemeComponentCommand { get; private set; }
public RelayCommand<ThemeComponent> DeleteThemeComponentCommand { get; private set; }
public bool EditEnabled
{
Components = themeComponentViewModels;
get { return Components.IsMasterCollection; }
}
public void Initialise(ThemeComponentCollection themeComponentCollection, bool newTheme)
{
Components = themeComponentCollection;
_filenameIsFake = newTheme;
}
@@ -70,12 +87,22 @@ namespace Filtration.ThemeEditor.ViewModels
public string Filename
{
get { return Path.GetFileName(FilePath); }
get { return _filenameIsFake ? FilePath : Path.GetFileName(FilePath); }
}
public string Name { get; set; }
public ObservableCollection<ThemeComponentViewModel> Components { get; set; }
public ThemeComponentCollection Components { get; set; }
public ThemeComponent SelectedThemeComponent
{
get { return _selectedThemeComponent; }
set
{
_selectedThemeComponent = value;
RaisePropertyChanged();
}
}
public void Save()
{
@@ -138,5 +165,19 @@ namespace Filtration.ThemeEditor.ViewModels
{
throw new NotImplementedException();
}
private void OnAddThemeComponentCommand(ThemeComponentType themeComponentType)
{
Components.Add(new ThemeComponent(themeComponentType, "Untitled Component",
new Color {A = 255, R = 255, G = 255, B = 255}));
}
private void OnDeleteThemeComponentCommand(ThemeComponent themeComponent)
{
if (themeComponent == null) return;
themeComponent.TerminateComponent();
Components.Remove(themeComponent);
}
}
}

View File

@@ -3,11 +3,12 @@
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:viewModels="clr-namespace:Filtration.ThemeEditor.ViewModels"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:converters="clr-namespace:Filtration.ThemeEditor.Converters"
xmlns:themeEditor="clr-namespace:Filtration.ObjectModel.ThemeEditor;assembly=Filtration.ObjectModel"
xmlns:views="clr-namespace:Filtration.ThemeEditor.Views"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:ThemeComponentViewModel}"
d:DataContext="{d:DesignInstance Type=themeEditor:ThemeComponent}"
d:DesignHeight="40" d:DesignWidth="200">
<UserControl.Resources>
<converters:ThemeComponentTypeToStringConverter x:Key="ThemeComponentTypeToStringConverter" />
@@ -18,8 +19,30 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate x:Key="EditableComponentNameTemplate">
<TextBox Text="{Binding ComponentName}" />
</DataTemplate>
<DataTemplate x:Key="ViewOnlyComponentNameTemplate">
<TextBlock Text="{Binding ComponentName}" ToolTip="{Binding ComponentName}" />
</DataTemplate>
</Grid.Resources>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding ComponentType, Converter={StaticResource ThemeComponentTypeToStringConverter}}" Foreground="Red" FontSize="10" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding ComponentName}" ToolTip="{Binding ComponentName}" />
<ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.EditEnabled, RelativeSource={RelativeSource AncestorType={x:Type views:ThemeEditorView}}}" Value="true">
<Setter Property="ContentTemplate" Value="{StaticResource EditableComponentNameTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=DataContext.EditEnabled, RelativeSource={RelativeSource AncestorType={x:Type views:ThemeEditorView}}}" Value="false">
<Setter Property="ContentTemplate" Value="{StaticResource ViewOnlyComponentNameTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<xctk:ColorPicker Grid.Row="2" Grid.Column="0" SelectedColor="{Binding Color}" />
</Grid>
</UserControl>

View File

@@ -1,28 +0,0 @@
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;
namespace Filtration.ThemeEditor.Views
{
/// <summary>
/// Interaction logic for ThemeControl.xaml
/// </summary>
public partial class ThemeControl : UserControl
{
public ThemeControl()
{
InitializeComponent();
}
}
}

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="Filtration.ThemeEditor.Views.ThemeControl"
<UserControl x:Class="Filtration.ThemeEditor.Views.ThemeEditorView"
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"
@@ -7,7 +7,7 @@
xmlns:views="clr-namespace:Filtration.ThemeEditor.Views"
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:ThemeViewModel}"
d:DataContext="{d:DesignInstance Type=viewModels:ThemeEditorViewModel}"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<CollectionViewSource Source="{Binding Components}" x:Key="ComponentsViewSource">
@@ -21,13 +21,35 @@
</UserControl.Resources>
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding Source={StaticResource ComponentsViewSource}}" Margin="10">
<ItemsControl.ItemsPanel>
<ListView ItemsSource="{Binding Source={StaticResource ComponentsViewSource}}"
SelectedItem="{Binding SelectedThemeComponent}"
Margin="10"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="#A9BDD8"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.GroupStyle>
</ListView.ItemsPanel>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
@@ -35,13 +57,13 @@
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemTemplate>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<views:ThemeComponentControl DataContext="{Binding}" Margin="10,5,10,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,10 @@
namespace Filtration.ThemeEditor.Views
{
public partial class ThemeEditorView
{
public ThemeEditorView()
{
InitializeComponent();
}
}
}

View File

@@ -11,8 +11,8 @@ namespace Filtration.ThemeEditor.WindsorInstallers
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IThemeViewModel>()
.ImplementedBy<ThemeViewModel>()
Component.For<IThemeEditorViewModel>()
.ImplementedBy<ThemeEditorViewModel>()
.LifeStyle.Transient);
container.Register(