diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index c5b07ade1..621405501 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -271,6 +271,7 @@ + @@ -551,6 +552,7 @@ + diff --git a/Artemis/Artemis/ItemBehaviours/BindableSelectedItemBehavior.cs b/Artemis/Artemis/ItemBehaviours/BindableSelectedItemBehavior.cs new file mode 100644 index 000000000..5e84d4502 --- /dev/null +++ b/Artemis/Artemis/ItemBehaviours/BindableSelectedItemBehavior.cs @@ -0,0 +1,52 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interactivity; + +namespace Artemis.ItemBehaviours +{ + /// + /// Steve Greatrex - http://stackoverflow.com/a/5118406/5015269 + /// + public class BindableSelectedItemBehavior : Behavior + { + protected override void OnAttached() + { + base.OnAttached(); + + AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged; + } + + protected override void OnDetaching() + { + base.OnDetaching(); + + if (AssociatedObject != null) + AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged; + } + + private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + SelectedItem = e.NewValue; + } + + #region SelectedItem Property + + public object SelectedItem + { + get { return GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof (object), typeof (BindableSelectedItemBehavior), + new UIPropertyMetadata(null, OnSelectedItemChanged)); + + private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + var item = e.NewValue as TreeViewItem; + item?.SetValue(TreeViewItem.IsSelectedProperty, true); + } + + #endregion + } +} \ No newline at end of file diff --git a/Artemis/Artemis/KeyboardProviders/Logitech/Orion.cs b/Artemis/Artemis/KeyboardProviders/Logitech/Orion.cs index 545711dd3..2c5c356db 100644 --- a/Artemis/Artemis/KeyboardProviders/Logitech/Orion.cs +++ b/Artemis/Artemis/KeyboardProviders/Logitech/Orion.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Threading; using System.Windows; using Artemis.KeyboardProviders.Logitech.Utilities; +using Artemis.Properties; using Artemis.Utilities; using Artemis.Utilities.LogitechDll; using Point = System.Drawing.Point; @@ -20,6 +21,7 @@ namespace Artemis.KeyboardProviders.Logitech "If needed, you can select a different keyboard in Artemis under settings."; Height = 6; Width = 21; + PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.g910); KeyboardRegions = new List { new KeyboardRegion("TopRow", new Point(0, 0), new Point(18, 0)), diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Models/Profiles/LayerModel.cs index 971e874b2..6f357c5f2 100644 --- a/Artemis/Artemis/Models/Profiles/LayerModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerModel.cs @@ -11,30 +11,32 @@ namespace Artemis.Models.Profiles public class LayerModel { [XmlIgnore] private readonly LayerDrawer _drawer; + private bool _mustDraw; public LayerModel() { - LayerUserProperties = new LayerPropertiesModel(); - LayerCalculatedProperties = new LayerPropertiesModel(); + UserProps = new LayerPropertiesModel(); + CalcProps = new LayerPropertiesModel(); Children = new List(); LayerConditions = new List(); LayerProperties = new List(); + _mustDraw = true; _drawer = new LayerDrawer(this, 4); } public string Name { get; set; } public LayerType LayerType { get; set; } public bool Enabled { get; set; } - public LayerPropertiesModel LayerUserProperties { get; set; } + public LayerPropertiesModel UserProps { get; set; } public List Children { get; set; } public List LayerConditions { get; set; } public List LayerProperties { get; set; } [XmlIgnore] - public LayerPropertiesModel LayerCalculatedProperties { get; set; } + public LayerPropertiesModel CalcProps { get; set; } [XmlIgnore] public ImageSource LayerImage => _drawer.GetThumbnail(); @@ -46,11 +48,12 @@ namespace Artemis.Models.Profiles public void DrawPreview(DrawingContext c) { - GeneralHelpers.CopyProperties(LayerCalculatedProperties, LayerUserProperties); + GeneralHelpers.CopyProperties(CalcProps, UserProps); if (LayerType == LayerType.KeyboardRectangle || LayerType == LayerType.KeyboardEllipse) - _drawer.Draw(c); + _drawer.Draw(c, _mustDraw); else if (LayerType == LayerType.KeyboardGif) _drawer.DrawGif(c); + _mustDraw = false; } public void Draw(IGameDataModel dataModel, DrawingContext c) @@ -80,9 +83,9 @@ namespace Artemis.Models.Profiles return; } - GeneralHelpers.CopyProperties(LayerCalculatedProperties, LayerUserProperties); + GeneralHelpers.CopyProperties(CalcProps, UserProps); foreach (var dynamicProperty in LayerProperties) - dynamicProperty.ApplyProperty(dataModel, LayerUserProperties, LayerCalculatedProperties); + dynamicProperty.ApplyProperty(dataModel, UserProps, CalcProps); } } diff --git a/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs index 4f8feadae..0e0f40065 100644 --- a/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerPropertiesModel.cs @@ -1,9 +1,11 @@ using System.ComponentModel; +using System.Windows; using System.Windows.Media; using System.Xml.Serialization; namespace Artemis.Models.Profiles { + [XmlInclude(typeof (SolidColorBrush))] [XmlInclude(typeof (LinearGradientBrush))] [XmlInclude(typeof (RadialGradientBrush))] [XmlInclude(typeof (MatrixTransform))] @@ -18,8 +20,14 @@ namespace Artemis.Models.Profiles public LayerAnimation Animation { get; set; } public double AnimationSpeed { get; set; } public Brush Brush { get; set; } + + public Rect GetRect(int scale = 4) + { + return new Rect(X*scale, Y*scale, Width*scale, Height*scale); + } } + public enum LayerAnimation { [Description("None")] None, diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs index 22f46066f..b823d1212 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs @@ -23,7 +23,7 @@ namespace Artemis.Modules.Games.CounterStrike ProfileEditor = new ProfileEditorViewModel(MainManager, GameModel); - GameModel.Profile = ProfileEditor.SelectedProfileModel; + GameModel.Profile = ProfileEditor.SelectedProfile; } public ProfileEditorViewModel ProfileEditor { get; set; } diff --git a/Artemis/Artemis/Properties/Resources.Designer.cs b/Artemis/Artemis/Properties/Resources.Designer.cs index 2d53d553d..8613537d8 100644 --- a/Artemis/Artemis/Properties/Resources.Designer.cs +++ b/Artemis/Artemis/Properties/Resources.Designer.cs @@ -145,6 +145,16 @@ namespace Artemis.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap g910 { + get { + object obj = ResourceManager.GetObject("g910", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/Artemis/Artemis/Properties/Resources.resx b/Artemis/Artemis/Properties/Resources.resx index 2033fd6c4..406c7c0dc 100644 --- a/Artemis/Artemis/Properties/Resources.resx +++ b/Artemis/Artemis/Properties/Resources.resx @@ -157,4 +157,7 @@ ..\resources\keyboards\strafe.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Keyboards\g910.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Artemis/Artemis/Resources/Keyboards/g910.png b/Artemis/Artemis/Resources/Keyboards/g910.png new file mode 100644 index 000000000..07a700606 Binary files /dev/null and b/Artemis/Artemis/Resources/Keyboards/g910.png differ diff --git a/Artemis/Artemis/Utilities/LayerDrawer.cs b/Artemis/Artemis/Utilities/LayerDrawer.cs index ca49b2350..54c68b868 100644 --- a/Artemis/Artemis/Utilities/LayerDrawer.cs +++ b/Artemis/Artemis/Utilities/LayerDrawer.cs @@ -23,22 +23,25 @@ namespace Artemis.Utilities public int Scale { get; set; } - public void Draw(DrawingContext c) + public void Draw(DrawingContext c, bool update = true) { - if (_layerModel.LayerCalculatedProperties.Brush == null) + if (_layerModel.CalcProps.Brush == null || !_layerModel.Enabled) return; + if (!update) + _layerModel.CalcProps.Animation = LayerAnimation.None; + UpdateAnimation(); // Set up variables for this frame - _rectangle = new Rect(_layerModel.LayerCalculatedProperties.X*Scale, - _layerModel.LayerCalculatedProperties.Y*Scale, _layerModel.LayerCalculatedProperties.Width*Scale, - _layerModel.LayerCalculatedProperties.Height*Scale); + _rectangle = new Rect(_layerModel.CalcProps.X*Scale, + _layerModel.CalcProps.Y*Scale, _layerModel.CalcProps.Width*Scale, + _layerModel.CalcProps.Height*Scale); if (_layerModel.LayerType == LayerType.KeyboardRectangle) - _layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawRectangle(c)); + _layerModel.CalcProps.Brush.Dispatcher.Invoke(() => DrawRectangle(c)); else if (_layerModel.LayerType == LayerType.KeyboardEllipse) - _layerModel.LayerCalculatedProperties.Brush.Dispatcher.Invoke(() => DrawEllipse(c)); + _layerModel.CalcProps.Brush.Dispatcher.Invoke(() => DrawEllipse(c)); } private void UpdateAnimation() @@ -47,73 +50,73 @@ namespace Artemis.Utilities return; // Slide right animation - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideRight) + if (_layerModel.CalcProps.Animation == LayerAnimation.SlideRight) { _firstRect = new Rect(new Point(_rectangle.X + _animationProgress, _rectangle.Y), new Size(_rectangle.Width, _rectangle.Height)); _secondRect = new Rect(new Point(_firstRect.X - _rectangle.Width, _rectangle.Y), new Size(_rectangle.Width + 1, _rectangle.Height)); - if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4) + if (_animationProgress > _layerModel.CalcProps.Width*4) _animationProgress = 0; } // Slide left animation - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft) + if (_layerModel.CalcProps.Animation == LayerAnimation.SlideLeft) { _firstRect = new Rect(new Point(_rectangle.X - _animationProgress, _rectangle.Y), new Size(_rectangle.Width + 1, _rectangle.Height)); _secondRect = new Rect(new Point(_firstRect.X + _rectangle.Width, _rectangle.Y), new Size(_rectangle.Width, _rectangle.Height)); - if (_animationProgress > _layerModel.LayerCalculatedProperties.Width*4) + if (_animationProgress > _layerModel.CalcProps.Width*4) _animationProgress = 0; } // Slide down animation - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown) + if (_layerModel.CalcProps.Animation == LayerAnimation.SlideDown) { _firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y + _animationProgress), new Size(_rectangle.Width, _rectangle.Height)); _secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y - _rectangle.Height), new Size(_rectangle.Width, _rectangle.Height)); - if (_animationProgress > _layerModel.LayerCalculatedProperties.Height*4) + if (_animationProgress > _layerModel.CalcProps.Height*4) _animationProgress = 0; } // Slide up animation - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp) + if (_layerModel.CalcProps.Animation == LayerAnimation.SlideUp) { _firstRect = new Rect(new Point(_rectangle.X, _rectangle.Y - _animationProgress), new Size(_rectangle.Width, _rectangle.Height)); _secondRect = new Rect(new Point(_firstRect.X, _firstRect.Y + _rectangle.Height), new Size(_rectangle.Width, _rectangle.Height)); - if (_animationProgress > _layerModel.LayerCalculatedProperties.Height*4) + if (_animationProgress > _layerModel.CalcProps.Height*4) _animationProgress = 0; } // Pulse animation - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.Pulse) + if (_layerModel.CalcProps.Animation == LayerAnimation.Pulse) { - var opac = (Math.Sin(_animationProgress*Math.PI) + 1)*(_layerModel.LayerUserProperties.Opacity/2); - _layerModel.LayerCalculatedProperties.Opacity = opac; + var opac = (Math.Sin(_animationProgress*Math.PI) + 1)*(_layerModel.UserProps.Opacity/2); + _layerModel.CalcProps.Opacity = opac; if (_animationProgress > 2) _animationProgress = 0; - _animationProgress = _animationProgress + _layerModel.LayerCalculatedProperties.AnimationSpeed/2; + _animationProgress = _animationProgress + _layerModel.CalcProps.AnimationSpeed/2; } else { // Update the animation progress - _animationProgress = _animationProgress + _layerModel.LayerCalculatedProperties.AnimationSpeed; + _animationProgress = _animationProgress + _layerModel.CalcProps.AnimationSpeed; } } public BitmapImage GetThumbnail() { - if (_layerModel.LayerUserProperties.Brush == null) + if (_layerModel.UserProps.Brush == null) return null; _rectangle = new Rect(0, 0, 18, 18); @@ -155,14 +158,13 @@ namespace Artemis.Utilities public void DrawRectangle(DrawingContext c) { - //_layerModel.LayerCalculatedProperties.Brush.Opacity = _layerModel.LayerCalculatedProperties.Opacity; - var brush = _layerModel.LayerCalculatedProperties.Brush.CloneCurrentValue(); - brush.Opacity = _layerModel.LayerCalculatedProperties.Opacity; + var brush = _layerModel.CalcProps.Brush.CloneCurrentValue(); + brush.Opacity = _layerModel.CalcProps.Opacity; - if (_layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideDown || - _layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideLeft || - _layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideRight || - _layerModel.LayerCalculatedProperties.Animation == LayerAnimation.SlideUp) + if (_layerModel.CalcProps.Animation == LayerAnimation.SlideDown || + _layerModel.CalcProps.Animation == LayerAnimation.SlideLeft || + _layerModel.CalcProps.Animation == LayerAnimation.SlideRight || + _layerModel.CalcProps.Animation == LayerAnimation.SlideUp) { c.PushClip(new RectangleGeometry(_rectangle)); c.DrawRectangle(brush, null, _firstRect); @@ -177,7 +179,7 @@ namespace Artemis.Utilities public void DrawEllipse(DrawingContext c) { - c.DrawEllipse(_layerModel.LayerCalculatedProperties.Brush, null, + c.DrawEllipse(_layerModel.CalcProps.Brush, null, new Point(_rectangle.Width/2, _rectangle.Height/2), _rectangle.Width, _rectangle.Height); } diff --git a/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs index cd5a2377f..2a6ccd1b0 100644 --- a/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs @@ -110,7 +110,7 @@ namespace Artemis.ViewModels public void PreSelect() { - GeneralHelpers.CopyProperties(ProposedProperties, Layer.LayerUserProperties); + GeneralHelpers.CopyProperties(ProposedProperties, Layer.UserProps); } private void AnimationUiHandler(object sender, PropertyChangedEventArgs e) @@ -128,7 +128,7 @@ namespace Artemis.ViewModels public void Apply() { - GeneralHelpers.CopyProperties(Layer.LayerUserProperties, ProposedProperties); + GeneralHelpers.CopyProperties(Layer.UserProps, ProposedProperties); ProfileProvider.AddOrUpdate(_profile); } diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs index a3f0ffa56..fd95a7da6 100644 --- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Drawing.Imaging; using System.Dynamic; using System.IO; @@ -15,6 +16,7 @@ using Artemis.Managers; using Artemis.Models; using Artemis.Models.Profiles; using Caliburn.Micro; +using MahApps.Metro; namespace Artemis.ViewModels { @@ -22,9 +24,16 @@ namespace Artemis.ViewModels { private readonly GameModel _gameModel; private readonly MainManager _mainManager; + private DateTime _downTime; + private LayerModel _draggingLayer; + private Point? _draggingLayerOffset; private LayerEditorViewModel _editorVm; + private Cursor _keyboardPreviewCursor; + private BindableCollection _layers; private BindableCollection _profileModels; - private ProfileModel _selectedProfileModel; + private bool _resizeSourceRect; + private LayerModel _selectedLayer; + private ProfileModel _selectedProfile; public ProfileEditorViewModel(MainManager mainManager, GameModel gameModel) { @@ -32,7 +41,10 @@ namespace Artemis.ViewModels _gameModel = gameModel; ProfileModels = new BindableCollection(); + Layers = new BindableCollection(); _mainManager.Events.Subscribe(this); + + PropertyChanged += PreviewRefresher; LoadProfiles(); } @@ -47,27 +59,52 @@ namespace Artemis.ViewModels } } - public ProfileModel SelectedProfileModel + public BindableCollection Layers { - get { return _selectedProfileModel; } + get { return _layers; } set { - if (Equals(value, _selectedProfileModel)) return; - _selectedProfileModel = value; - NotifyOfPropertyChange(() => SelectedProfileModel); + if (Equals(value, _layers)) return; + _layers = value; + NotifyOfPropertyChange(() => Layers); } } - public LayerModel SelectedLayer { get; set; } + public LayerModel SelectedLayer + { + get { return _selectedLayer; } + set + { + if (Equals(value, _selectedLayer)) return; + _selectedLayer = value; + NotifyOfPropertyChange(() => SelectedLayer); + } + } + + public ProfileModel SelectedProfile + { + get { return _selectedProfile; } + set + { + if (Equals(value, _selectedProfile)) return; + _selectedProfile = value; + + Layers.Clear(); + Layers.AddRange(_selectedProfile?.Layers); + + NotifyOfPropertyChange(() => SelectedProfile); + NotifyOfPropertyChange(() => CanAddLayer); + } + } public ImageSource KeyboardPreview { get { - if (_selectedProfileModel == null) + if (_selectedProfile == null) return null; - var keyboardRect = _mainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4); + var keyboardRect = ActiveKeyboard.KeyboardRectangle(4); var visual = new DrawingVisual(); using (var drawingContext = visual.RenderOpen()) { @@ -75,12 +112,30 @@ namespace Artemis.ViewModels drawingContext.PushClip(new RectangleGeometry(keyboardRect)); drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect); + // Get the selection color + var penColor = (Color)ThemeManager.DetectAppStyle(Application.Current).Item2.Resources["AccentColor"]; + var pen = new Pen(new SolidColorBrush(penColor), 0.4); + // Draw the layer - foreach (var layerModel in _selectedProfileModel.Layers) + foreach (var layerModel in _selectedProfile.Layers) { - // if (layerModel.Selected) - drawingContext.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.White), 0.5),new Rect(layerModel.LayerUserProperties.X*4,layerModel.LayerUserProperties.Y*4, layerModel.LayerUserProperties.Width*4,layerModel.LayerUserProperties.Height*4)); layerModel.DrawPreview(drawingContext); + if (layerModel != SelectedLayer || !layerModel.Enabled) + continue; + + var layerRect = layerModel.UserProps.GetRect(); + // Draw an outline around the selected layer + drawingContext.DrawRectangle(null, pen, layerRect); + // Draw a resize indicator in the bottom-right + drawingContext.DrawLine(pen, + new Point(layerRect.BottomRight.X - 1, layerRect.BottomRight.Y - 0.5), + new Point(layerRect.BottomRight.X - 1.2, layerRect.BottomRight.Y - 0.7)); + drawingContext.DrawLine(pen, + new Point(layerRect.BottomRight.X - 0.5, layerRect.BottomRight.Y - 1), + new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 1.2)); + drawingContext.DrawLine(pen, + new Point(layerRect.BottomRight.X - 0.5, layerRect.BottomRight.Y - 0.5), + new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7)); } // Remove the clip @@ -98,10 +153,9 @@ namespace Artemis.ViewModels { using (var memory = new MemoryStream()) { - if (_mainManager.KeyboardManager.ActiveKeyboard?.PreviewSettings == null) + if (ActiveKeyboard?.PreviewSettings == null || ActiveKeyboard?.PreviewSettings.Image == null) return null; - - _mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Image.Save(memory, ImageFormat.Png); + ActiveKeyboard.PreviewSettings.Image.Save(memory, ImageFormat.Png); memory.Position = 0; var bitmapImage = new BitmapImage(); @@ -115,22 +169,40 @@ namespace Artemis.ViewModels } } - public PreviewSettings? PreviewSettings + public PreviewSettings? PreviewSettings => ActiveKeyboard?.PreviewSettings; + + public bool CanAddLayer => _selectedProfile != null; + + public Cursor KeyboardPreviewCursor { - get { return _mainManager.KeyboardManager.ActiveKeyboard?.PreviewSettings; } + get { return _keyboardPreviewCursor; } + set + { + if (Equals(value, _keyboardPreviewCursor)) return; + _keyboardPreviewCursor = value; + NotifyOfPropertyChange(() => KeyboardPreviewCursor); + } } + private KeyboardProvider ActiveKeyboard => _mainManager.KeyboardManager.ActiveKeyboard; + public void Handle(ActiveKeyboardChanged message) { NotifyOfPropertyChange(() => KeyboardImage); NotifyOfPropertyChange(() => PreviewSettings); } + private void PreviewRefresher(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "SelectedLayer" || e.PropertyName == "ProfileTree") + NotifyOfPropertyChange(() => KeyboardPreview); + } + private void LoadProfiles() { ProfileModels.Clear(); ProfileModels.AddRange(ProfileProvider.GetAll(_gameModel)); - SelectedProfileModel = ProfileModels.FirstOrDefault(); + SelectedProfile = ProfileModels.FirstOrDefault(); } public async void AddProfile() @@ -148,7 +220,7 @@ namespace Artemis.ViewModels var profile = new ProfileModel { Name = name, - KeyboardName = _mainManager.KeyboardManager.ActiveKeyboard.Name, + KeyboardName = ActiveKeyboard.Name, GameName = _gameModel.Name }; if (ProfileProvider.GetAll().Contains(profile)) @@ -164,13 +236,18 @@ namespace Artemis.ViewModels ProfileProvider.AddOrUpdate(profile); LoadProfiles(); - SelectedProfileModel = profile; + SelectedProfile = profile; + } + + public void ToggleEnabled(LayerModel layer) + { + NotifyOfPropertyChange(() => KeyboardPreview); } public void LayerEditor(LayerModel layer) { IWindowManager manager = new WindowManager(); - _editorVm = new LayerEditorViewModel(_mainManager.KeyboardManager.ActiveKeyboard, SelectedProfileModel, + _editorVm = new LayerEditorViewModel(ActiveKeyboard, SelectedProfile, layer); dynamic settings = new ExpandoObject(); @@ -186,27 +263,125 @@ namespace Artemis.ViewModels public void AddLayer() { - _selectedProfileModel.Layers.Add(new LayerModel + if (_selectedProfile == null) + return; + + var layer = new LayerModel { - Name = "Layer " + (_selectedProfileModel.Layers.Count + 1), - LayerType = LayerType.KeyboardRectangle - }); - NotifyOfPropertyChange(() => SelectedProfileModel); + Name = "Layer " + (_selectedProfile.Layers.Count + 1), + LayerType = LayerType.KeyboardRectangle, + UserProps = new LayerPropertiesModel + { + Brush = new SolidColorBrush(Colors.Red), + Animation = LayerAnimation.None, + Height = 1, + Width = 1, + X = 0, + Y = 0, + Opacity = 1 + } + }; + SelectedProfile.Layers.Add(layer); + Layers.Add(layer); + } + + public void MouseDownKeyboardPreview(MouseButtonEventArgs e) + { + if (e.LeftButton == MouseButtonState.Pressed) + _downTime = DateTime.Now; + } + + public void MouseUpKeyboardPreview(MouseButtonEventArgs e) + { + var timeSinceDown = DateTime.Now - _downTime; + if (timeSinceDown.TotalMilliseconds < 500) + { + var pos = e.GetPosition((Image) e.OriginalSource); + var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width); + var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height); + + var hoverLayer = SelectedProfile.Layers.Where(l => l.Enabled) + .FirstOrDefault(l => l.UserProps.GetRect(1).Contains(x, y)); + if (hoverLayer != null) + SelectedLayer = hoverLayer; + } } public void MouseMoveKeyboardPreview(MouseEventArgs e) { var pos = e.GetPosition((Image) e.OriginalSource); - var realX = - (int) - Math.Round(pos.X/ - (_mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Width/ - _mainManager.KeyboardManager.ActiveKeyboard.Width)); - var realY = - (int) - Math.Round(pos.Y/ - (_mainManager.KeyboardManager.ActiveKeyboard.PreviewSettings.Height/ - _mainManager.KeyboardManager.ActiveKeyboard.Height)); + var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width); + var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height); + var hoverLayer = SelectedProfile.Layers.Where(l => l.Enabled) + .FirstOrDefault(l => l.UserProps.GetRect(1).Contains(x, y)); + + HandleDragging(e, x, y, hoverLayer); + + if (hoverLayer == null) + { + KeyboardPreviewCursor = Cursors.Arrow; + return; + } + + + // Turn the mouse pointer into a hand if hovering over an active layer + if (hoverLayer == SelectedLayer) + { + var layerRect = hoverLayer.UserProps.GetRect(1); + if (Math.Sqrt(Math.Pow(x - layerRect.BottomRight.X, 2) + Math.Pow(y - layerRect.BottomRight.Y, 2)) < 0.6) + KeyboardPreviewCursor = Cursors.SizeNWSE; + else + KeyboardPreviewCursor = Cursors.SizeAll; + } + else + KeyboardPreviewCursor = Cursors.Hand; + } + + private void HandleDragging(MouseEventArgs e, double x, double y, LayerModel hoverLayer) + { + // Reset the dragging state on mouse release + if (e.LeftButton == MouseButtonState.Released || + (_draggingLayer != null && _selectedLayer != _draggingLayer)) + { + _draggingLayerOffset = null; + _draggingLayer = null; + return; + } + + if (SelectedLayer == null) + return; + + // Setup the dragging state on mouse press + if (_draggingLayerOffset == null && hoverLayer != null && e.LeftButton == MouseButtonState.Pressed) + { + var layerRect = hoverLayer.UserProps.GetRect(1); + _draggingLayerOffset = new Point(x - SelectedLayer.UserProps.X, y - SelectedLayer.UserProps.Y); + _draggingLayer = hoverLayer; + if (Math.Sqrt(Math.Pow(x - layerRect.BottomRight.X, 2) + Math.Pow(y - layerRect.BottomRight.Y, 2)) < 0.6) + _resizeSourceRect = true; + else + _resizeSourceRect = false; + } + + if (_draggingLayerOffset == null || _draggingLayer == null || (_draggingLayer != SelectedLayer)) + return; + + // If no setup or reset was done, handle the actual dragging action + if (_resizeSourceRect) + { + _draggingLayer.UserProps.Width = (int) Math.Round(x - _draggingLayer.UserProps.X); + _draggingLayer.UserProps.Height = (int) Math.Round(y - _draggingLayer.UserProps.Y); + if (_draggingLayer.UserProps.Width < 1) + _draggingLayer.UserProps.Width = 1; + if (_draggingLayer.UserProps.Height < 1) + _draggingLayer.UserProps.Height = 1; + } + else + { + _draggingLayer.UserProps.X = (int) Math.Round(x - _draggingLayerOffset.Value.X); + _draggingLayer.UserProps.Y = (int) Math.Round(y - _draggingLayerOffset.Value.Y); + } + NotifyOfPropertyChange(() => KeyboardPreview); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml b/Artemis/Artemis/Views/ProfileEditorView.xaml index 9cfaaa76c..a6ea8ed89 100644 --- a/Artemis/Artemis/Views/ProfileEditorView.xaml +++ b/Artemis/Artemis/Views/ProfileEditorView.xaml @@ -6,6 +6,8 @@ xmlns:local="clr-namespace:Artemis.Views" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" xmlns:cal="http://www.caliburnproject.org" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours" mc:Ignorable="d" d:DesignHeight="482.812" d:DesignWidth="1029.95"> @@ -34,12 +36,14 @@ - + Stretch="Fill" Cursor="{Binding Path=KeyboardPreviewCursor}" + cal:Message.Attach="[Event MouseMove] = [Action MouseMoveKeyboardPreview($eventArgs)]; + [Event MouseDown] = [Action MouseDownKeyboardPreview($eventArgs)]; + [Event MouseUp] = [Action MouseUpKeyboardPreview($eventArgs)]" /> @@ -62,15 +66,17 @@ Margin="10,0,0,0" /> - + + + + - + @@ -79,7 +85,8 @@ - +