mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 17:53:32 +00:00
Implemented clipping modes, hopefully fixed UI freezes on tab switch
This commit is contained in:
parent
6e451c06cd
commit
4667ea21f9
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Threading;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Artemis.Events;
|
using Artemis.Events;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
using Ninject.Extensions.Logging;
|
using Ninject.Extensions.Logging;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace Artemis.Managers
|
namespace Artemis.Managers
|
||||||
{
|
{
|
||||||
@ -108,49 +110,51 @@ namespace Artemis.Managers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_keyboardManager.ActiveKeyboard)
|
if (!Monitor.TryEnter(_keyboardManager.ActiveKeyboard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Skip frame if effect is still initializing
|
||||||
|
if (renderEffect.Initialized == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// ApplyProperties the current effect
|
||||||
|
if (renderEffect.Initialized)
|
||||||
|
renderEffect.Update();
|
||||||
|
|
||||||
|
// Get ActiveEffect's bitmap
|
||||||
|
var bitmap = renderEffect.Initialized
|
||||||
|
? renderEffect.GenerateBitmap()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Draw enabled overlays on top
|
||||||
|
foreach (var overlayModel in _effectManager.EnabledOverlays)
|
||||||
{
|
{
|
||||||
// Skip frame if effect is still initializing
|
overlayModel.Update();
|
||||||
if (renderEffect.Initialized == false)
|
bitmap = bitmap != null
|
||||||
return;
|
? overlayModel.GenerateBitmap(bitmap)
|
||||||
|
: overlayModel.GenerateBitmap();
|
||||||
// ApplyProperties the current effect
|
|
||||||
if (renderEffect.Initialized)
|
|
||||||
renderEffect.Update();
|
|
||||||
|
|
||||||
// Get ActiveEffect's bitmap
|
|
||||||
var bitmap = renderEffect.Initialized
|
|
||||||
? renderEffect.GenerateBitmap()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// Draw enabled overlays on top
|
|
||||||
foreach (var overlayModel in _effectManager.EnabledOverlays)
|
|
||||||
{
|
|
||||||
overlayModel.Update();
|
|
||||||
bitmap = bitmap != null
|
|
||||||
? overlayModel.GenerateBitmap(bitmap)
|
|
||||||
: overlayModel.GenerateBitmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bitmap == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
|
||||||
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
|
|
||||||
using (var g = Graphics.FromImage(fixedBmp))
|
|
||||||
{
|
|
||||||
g.Clear(Color.Black);
|
|
||||||
g.DrawImage(bitmap, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmap = fixedBmp;
|
|
||||||
|
|
||||||
// If it exists, send bitmap to the device
|
|
||||||
_keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap);
|
|
||||||
|
|
||||||
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
|
|
||||||
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
||||||
|
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
|
||||||
|
using (var g = Graphics.FromImage(fixedBmp))
|
||||||
|
{
|
||||||
|
g.Clear(Color.Black);
|
||||||
|
g.DrawImage(bitmap, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = fixedBmp;
|
||||||
|
|
||||||
|
// If it exists, send bitmap to the device
|
||||||
|
_keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap);
|
||||||
|
|
||||||
|
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
|
||||||
|
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||||
|
|
||||||
|
Monitor.Exit(_keyboardManager.ActiveKeyboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ namespace Artemis.Models.Profiles
|
|||||||
return Enabled && Properties.Conditions.All(cm => cm.ConditionMet<T>(dataModel));
|
return Enabled && Properties.Conditions.All(cm => cm.ConditionMet<T>(dataModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw<T>(IGameDataModel dataModel, DrawingContext c, bool preview = false)
|
public void Draw<T>(IGameDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||||
{
|
{
|
||||||
// Don't draw when the layer is disabled
|
// Don't draw when the layer is disabled
|
||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
@ -59,22 +59,21 @@ namespace Artemis.Models.Profiles
|
|||||||
appliedProperties = GeneralHelpers.Clone(Properties);
|
appliedProperties = GeneralHelpers.Clone(Properties);
|
||||||
|
|
||||||
// Update animations on layer types that support them
|
// Update animations on layer types that support them
|
||||||
if (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif)
|
if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) && updateAnimations)
|
||||||
{
|
{
|
||||||
AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties);
|
AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties,
|
||||||
((KeyboardPropertiesModel) appliedProperties).AnimationProgress =
|
(KeyboardPropertiesModel) appliedProperties);
|
||||||
((KeyboardPropertiesModel) Properties).AnimationProgress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Folders are drawn recursively
|
// Folders are drawn recursively
|
||||||
if (LayerType == LayerType.Folder)
|
if (LayerType == LayerType.Folder)
|
||||||
{
|
{
|
||||||
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
||||||
layerModel.Draw<T>(dataModel, c);
|
layerModel.Draw<T>(dataModel, c, preview, updateAnimations);
|
||||||
}
|
}
|
||||||
// All other types are handles by the Drawer helper
|
// All other types are handles by the Drawer helper
|
||||||
else if (LayerType == LayerType.Keyboard)
|
else if (LayerType == LayerType.Keyboard)
|
||||||
Drawer.Draw(c, (KeyboardPropertiesModel) appliedProperties);
|
Drawer.Draw(c, (KeyboardPropertiesModel) Properties, (KeyboardPropertiesModel) appliedProperties);
|
||||||
else if (LayerType == LayerType.KeyboardGif)
|
else if (LayerType == LayerType.KeyboardGif)
|
||||||
GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) appliedProperties, GifImage);
|
GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) appliedProperties, GifImage);
|
||||||
else if (LayerType == LayerType.Mouse)
|
else if (LayerType == LayerType.Mouse)
|
||||||
@ -131,6 +130,15 @@ namespace Artemis.Models.Profiles
|
|||||||
Children[i].Order = i;
|
Children[i].Order = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the layer meets the requirements to be drawn
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool MustDraw()
|
||||||
|
{
|
||||||
|
return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif);
|
||||||
|
}
|
||||||
|
|
||||||
#region IChildItem<Parent> Members
|
#region IChildItem<Parent> Members
|
||||||
|
|
||||||
LayerModel IChildItem<LayerModel>.Parent
|
LayerModel IChildItem<LayerModel>.Parent
|
||||||
|
|||||||
@ -110,7 +110,7 @@ namespace Artemis.Models.Profiles
|
|||||||
Layers[i].Order = i;
|
Layers[i].Order = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IGameDataModel gameDataModel, bool preview = false)
|
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IGameDataModel gameDataModel, bool preview, bool updateAnimations)
|
||||||
{
|
{
|
||||||
Bitmap bitmap = null;
|
Bitmap bitmap = null;
|
||||||
DrawingVisual.Dispatcher.Invoke(delegate
|
DrawingVisual.Dispatcher.Invoke(delegate
|
||||||
@ -124,7 +124,7 @@ namespace Artemis.Models.Profiles
|
|||||||
|
|
||||||
// Draw the layers
|
// Draw the layers
|
||||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||||
layerModel.Draw<T>(gameDataModel, c, preview);
|
layerModel.Draw<T>(gameDataModel, c, preview, updateAnimations);
|
||||||
|
|
||||||
// Remove the clip
|
// Remove the clip
|
||||||
c.Pop();
|
c.Pop();
|
||||||
|
|||||||
@ -24,8 +24,6 @@ namespace Artemis.Models.Profiles.Properties
|
|||||||
public double AnimationSpeed { get; set; }
|
public double AnimationSpeed { get; set; }
|
||||||
public string GifFile { get; set; }
|
public string GifFile { get; set; }
|
||||||
public List<DynamicPropertiesModel> DynamicProperties { get; set; }
|
public List<DynamicPropertiesModel> DynamicProperties { get; set; }
|
||||||
|
|
||||||
[XmlIgnore]
|
|
||||||
public double AnimationProgress { get; set; }
|
public double AnimationProgress { get; set; }
|
||||||
|
|
||||||
public Rect GetRect(int scale = 4)
|
public Rect GetRect(int scale = 4)
|
||||||
|
|||||||
@ -41,7 +41,7 @@ namespace Artemis.Modules.Effects.ProfilePreview
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4);
|
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4);
|
||||||
var image = SelectedProfile.GenerateBitmap<ProfilePreviewDataModel>(keyboardRect, _previewDataModel, true);
|
var image = SelectedProfile.GenerateBitmap<ProfilePreviewDataModel>(keyboardRect, _previewDataModel, true, true);
|
||||||
|
|
||||||
// Draw on top of everything else
|
// Draw on top of everything else
|
||||||
using (var g = Graphics.FromImage(bitmap))
|
using (var g = Graphics.FromImage(bitmap))
|
||||||
|
|||||||
@ -48,7 +48,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
||||||
return Profile.GenerateBitmap<CounterStrikeDataModel>(keyboardRect, GameDataModel);
|
return Profile.GenerateBitmap<CounterStrikeDataModel>(keyboardRect, GameDataModel, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ namespace Artemis.Modules.Games.Dota2
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
||||||
return Profile.GenerateBitmap<Dota2DataModel>(keyboardRect, GameDataModel);
|
return Profile.GenerateBitmap<Dota2DataModel>(keyboardRect, GameDataModel, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,7 @@ namespace Artemis.Modules.Games.RocketLeague
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
||||||
return Profile.GenerateBitmap<RocketLeagueDataModel>(keyboardRect, GameDataModel);
|
return Profile.GenerateBitmap<RocketLeagueDataModel>(keyboardRect, GameDataModel, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ namespace Artemis.Modules.Games.Witcher3
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale);
|
||||||
return Profile.GenerateBitmap<TheWitcherDataModel>(keyboardRect, GameDataModel);
|
return Profile.GenerateBitmap<TheWitcherDataModel>(keyboardRect, GameDataModel, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,42 +1,46 @@
|
|||||||
using System;
|
using Artemis.Models.Profiles.Properties;
|
||||||
using Artemis.Models.Profiles.Properties;
|
|
||||||
|
|
||||||
namespace Artemis.Utilities.Layers
|
namespace Artemis.Utilities.Layers
|
||||||
{
|
{
|
||||||
public static class AnimationUpdater
|
public static class AnimationUpdater
|
||||||
{
|
{
|
||||||
public static void UpdateAnimation(KeyboardPropertiesModel properties)
|
public static void UpdateAnimation(KeyboardPropertiesModel properties, KeyboardPropertiesModel appliedProperties)
|
||||||
{
|
{
|
||||||
const int scale = 4;
|
const int scale = 4;
|
||||||
var progress = properties.AnimationProgress;
|
var animateProperties = properties.Contain ? appliedProperties : properties;
|
||||||
|
var progress = appliedProperties.AnimationProgress;
|
||||||
|
|
||||||
// Horizontal sliding
|
// Horizontal sliding
|
||||||
if (properties.Animation == LayerAnimation.SlideRight || properties.Animation == LayerAnimation.SlideLeft)
|
if (animateProperties.Animation == LayerAnimation.SlideRight ||
|
||||||
|
animateProperties.Animation == LayerAnimation.SlideLeft)
|
||||||
{
|
{
|
||||||
if (progress > properties.Width*scale)
|
if (progress > animateProperties.Width*scale)
|
||||||
progress = 0;
|
progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical sliding
|
// Vertical sliding
|
||||||
if (properties.Animation == LayerAnimation.SlideDown || properties.Animation == LayerAnimation.SlideUp)
|
if (animateProperties.Animation == LayerAnimation.SlideDown ||
|
||||||
|
animateProperties.Animation == LayerAnimation.SlideUp)
|
||||||
{
|
{
|
||||||
if (progress > properties.Height*scale)
|
if (progress > animateProperties.Height*scale)
|
||||||
progress = 0;
|
progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pulse animation
|
// Pulse animation
|
||||||
if (properties.Animation == LayerAnimation.Pulse)
|
if (animateProperties.Animation == LayerAnimation.Pulse)
|
||||||
{
|
{
|
||||||
if (progress > 2)
|
if (progress > 2)
|
||||||
progress = 0;
|
progress = 0;
|
||||||
|
|
||||||
progress = progress + properties.AnimationSpeed/2;
|
progress = progress + animateProperties.AnimationSpeed/2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
progress = progress + properties.AnimationSpeed * 2;
|
progress = progress + animateProperties.AnimationSpeed*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appliedProperties.AnimationProgress = progress;
|
||||||
|
// Store the animation progress in the actual model for the next frame
|
||||||
properties.AnimationProgress = progress;
|
properties.AnimationProgress = progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,54 +14,60 @@ namespace Artemis.Utilities.Layers
|
|||||||
{
|
{
|
||||||
public static class Drawer
|
public static class Drawer
|
||||||
{
|
{
|
||||||
public static void Draw(DrawingContext c, KeyboardPropertiesModel props)
|
public static void Draw(DrawingContext c, KeyboardPropertiesModel props, KeyboardPropertiesModel applied)
|
||||||
{
|
{
|
||||||
if (props.Brush == null)
|
if (applied.Brush == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int scale = 4;
|
const int scale = 4;
|
||||||
|
|
||||||
// Set up variables for this frame
|
// Set up variables for this frame
|
||||||
var rect = new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
var rect = props.Contain
|
||||||
|
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||||
|
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||||
|
|
||||||
var s1 = new Rect();
|
var s1 = new Rect();
|
||||||
var s2 = new Rect();
|
var s2 = new Rect();
|
||||||
|
|
||||||
if (props.Animation == LayerAnimation.SlideRight)
|
if (applied.Animation == LayerAnimation.SlideRight)
|
||||||
{
|
{
|
||||||
s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
|
s1 = new Rect(new Point(rect.X + applied.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
|
||||||
s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height));
|
s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height));
|
||||||
}
|
}
|
||||||
if (props.Animation == LayerAnimation.SlideLeft)
|
if (applied.Animation == LayerAnimation.SlideLeft)
|
||||||
{
|
{
|
||||||
s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y), new Size(rect.Width + 1, rect.Height));
|
s1 = new Rect(new Point(rect.X - applied.AnimationProgress, rect.Y),
|
||||||
|
new Size(rect.Width + 1, rect.Height));
|
||||||
s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
|
s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
|
||||||
}
|
}
|
||||||
if (props.Animation == LayerAnimation.SlideDown)
|
if (applied.Animation == LayerAnimation.SlideDown)
|
||||||
{
|
{
|
||||||
s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height));
|
s1 = new Rect(new Point(rect.X, rect.Y + applied.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||||
s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
|
s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
|
||||||
}
|
}
|
||||||
if (props.Animation == LayerAnimation.SlideUp)
|
if (applied.Animation == LayerAnimation.SlideUp)
|
||||||
{
|
{
|
||||||
s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), new Size(rect.Width, rect.Height));
|
s1 = new Rect(new Point(rect.X, rect.Y - applied.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||||
s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
|
s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
props.Brush.Dispatcher.Invoke(() => DrawRectangle(c, props, rect, s1, s2));
|
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||||
|
|
||||||
|
applied.Brush.Dispatcher.Invoke(() => DrawRectangle(c, applied, clip, rect, s1, s2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel properties, Rect rectangle,
|
private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel properties, Rect clip,
|
||||||
|
Rect rectangle,
|
||||||
Rect slide1, Rect slide2)
|
Rect slide1, Rect slide2)
|
||||||
{
|
{
|
||||||
// Apply the pulse animation
|
// Apply the pulse animation
|
||||||
var brush = properties.Brush.CloneCurrentValue();
|
var brush = properties.Brush.CloneCurrentValue();
|
||||||
brush.Opacity = properties.Opacity;
|
brush.Opacity = properties.Opacity;
|
||||||
if (properties.Animation == LayerAnimation.Pulse)
|
if (properties.Animation == LayerAnimation.Pulse)
|
||||||
brush.Opacity = (Math.Sin(properties.AnimationProgress * Math.PI) + 1) * (properties.Opacity / 2);
|
brush.Opacity = (Math.Sin(properties.AnimationProgress*Math.PI) + 1)*(properties.Opacity/2);
|
||||||
else
|
else
|
||||||
brush.Opacity = properties.Opacity;
|
brush.Opacity = properties.Opacity;
|
||||||
|
|
||||||
// TODO: Implement clipping modes
|
c.PushClip(new RectangleGeometry(clip));
|
||||||
// Most animation types can be drawn regularly
|
// Most animation types can be drawn regularly
|
||||||
if (properties.Animation == LayerAnimation.None ||
|
if (properties.Animation == LayerAnimation.None ||
|
||||||
properties.Animation == LayerAnimation.Grow ||
|
properties.Animation == LayerAnimation.Grow ||
|
||||||
@ -72,11 +78,11 @@ namespace Artemis.Utilities.Layers
|
|||||||
// Sliding animations however, require offsetting two rects
|
// Sliding animations however, require offsetting two rects
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.PushClip(new RectangleGeometry(rectangle));
|
c.PushClip(new RectangleGeometry(clip));
|
||||||
c.DrawRectangle(brush, null, slide1);
|
c.DrawRectangle(brush, null, slide1);
|
||||||
c.DrawRectangle(brush, null, slide2);
|
c.DrawRectangle(brush, null, slide2);
|
||||||
c.Pop();
|
|
||||||
}
|
}
|
||||||
|
c.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel properties, GifImage gifImage,
|
public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel properties, GifImage gifImage,
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
|
||||||
using Artemis.Models.Interfaces;
|
using Artemis.Models.Interfaces;
|
||||||
using Artemis.Models.Profiles;
|
using Artemis.Models.Profiles;
|
||||||
using Artemis.Models.Profiles.Properties;
|
using Artemis.Models.Profiles.Properties;
|
||||||
@ -10,14 +8,12 @@ using Artemis.Services;
|
|||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Screen = Caliburn.Micro.Screen;
|
|
||||||
|
|
||||||
namespace Artemis.ViewModels.LayerEditor
|
namespace Artemis.ViewModels.LayerEditor
|
||||||
{
|
{
|
||||||
public sealed class LayerEditorViewModel : Screen
|
public sealed class LayerEditorViewModel : Screen
|
||||||
{
|
{
|
||||||
private readonly IGameDataModel _gameDataModel;
|
private readonly IGameDataModel _gameDataModel;
|
||||||
private readonly bool _wasEnabled;
|
|
||||||
private LayerModel _layer;
|
private LayerModel _layer;
|
||||||
private LayerPropertiesViewModel _layerPropertiesViewModel;
|
private LayerPropertiesViewModel _layerPropertiesViewModel;
|
||||||
private LayerType _layerType;
|
private LayerType _layerType;
|
||||||
@ -27,10 +23,8 @@ namespace Artemis.ViewModels.LayerEditor
|
|||||||
public LayerEditorViewModel(IGameDataModel gameDataModel, LayerModel layer)
|
public LayerEditorViewModel(IGameDataModel gameDataModel, LayerModel layer)
|
||||||
{
|
{
|
||||||
_gameDataModel = gameDataModel;
|
_gameDataModel = gameDataModel;
|
||||||
_wasEnabled = layer.Enabled;
|
|
||||||
|
|
||||||
Layer = layer;
|
Layer = layer;
|
||||||
Layer.Enabled = false;
|
|
||||||
|
|
||||||
if (Layer.Properties == null)
|
if (Layer.Properties == null)
|
||||||
Layer.SetupProperties();
|
Layer.SetupProperties();
|
||||||
@ -172,11 +166,5 @@ namespace Artemis.ViewModels.LayerEditor
|
|||||||
LayerConditionVms.Remove(layerConditionViewModel);
|
LayerConditionVms.Remove(layerConditionViewModel);
|
||||||
Layer.Properties.Conditions.Remove(layerConditionModel);
|
Layer.Properties.Conditions.Remove(layerConditionModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CanClose(Action<bool> callback)
|
|
||||||
{
|
|
||||||
_layer.Enabled = _wasEnabled;
|
|
||||||
base.CanClose(callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,6 +7,7 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Threading;
|
||||||
using Artemis.DAL;
|
using Artemis.DAL;
|
||||||
using Artemis.Events;
|
using Artemis.Events;
|
||||||
using Artemis.KeyboardProviders;
|
using Artemis.KeyboardProviders;
|
||||||
@ -31,6 +32,7 @@ namespace Artemis.ViewModels
|
|||||||
private LayerModel _draggingLayer;
|
private LayerModel _draggingLayer;
|
||||||
private Point? _draggingLayerOffset;
|
private Point? _draggingLayerOffset;
|
||||||
private LayerEditorViewModel _editorVm;
|
private LayerEditorViewModel _editorVm;
|
||||||
|
private ImageSource _keyboardPreview;
|
||||||
private Cursor _keyboardPreviewCursor;
|
private Cursor _keyboardPreviewCursor;
|
||||||
private BindableCollection<LayerModel> _layers;
|
private BindableCollection<LayerModel> _layers;
|
||||||
private BindableCollection<ProfileModel> _profiles;
|
private BindableCollection<ProfileModel> _profiles;
|
||||||
@ -45,10 +47,13 @@ namespace Artemis.ViewModels
|
|||||||
|
|
||||||
Profiles = new BindableCollection<ProfileModel>();
|
Profiles = new BindableCollection<ProfileModel>();
|
||||||
Layers = new BindableCollection<LayerModel>();
|
Layers = new BindableCollection<LayerModel>();
|
||||||
|
ActiveKeyboard = _mainManager.KeyboardManager.ActiveKeyboard;
|
||||||
|
|
||||||
events.Subscribe(this);
|
events.Subscribe(this);
|
||||||
|
|
||||||
PreviewTimer = new Timer(40);
|
PreviewTimer = new Timer(40);
|
||||||
PreviewTimer.Elapsed += (sender, args) => NotifyOfPropertyChange(() => KeyboardPreview);
|
PreviewTimer.Elapsed += InvokeUpdateKeyboardPreview;
|
||||||
|
|
||||||
|
|
||||||
PropertyChanged += PropertyChangeHandler;
|
PropertyChanged += PropertyChangeHandler;
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
@ -124,59 +129,12 @@ namespace Artemis.ViewModels
|
|||||||
|
|
||||||
public ImageSource KeyboardPreview
|
public ImageSource KeyboardPreview
|
||||||
{
|
{
|
||||||
get
|
get { return _keyboardPreview; }
|
||||||
|
set
|
||||||
{
|
{
|
||||||
if (_selectedProfile == null || ActiveKeyboard == null)
|
if (Equals(value, _keyboardPreview)) return;
|
||||||
return null;
|
_keyboardPreview = value;
|
||||||
|
NotifyOfPropertyChange(() => KeyboardPreview);
|
||||||
var keyboardRect = ActiveKeyboard.KeyboardRectangle(4);
|
|
||||||
var visual = new DrawingVisual();
|
|
||||||
using (var drawingContext = visual.RenderOpen())
|
|
||||||
{
|
|
||||||
// Setup the DrawingVisual's size
|
|
||||||
drawingContext.PushClip(new RectangleGeometry(keyboardRect));
|
|
||||||
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
|
||||||
|
|
||||||
// Draw the layers
|
|
||||||
foreach (var layerModel in _selectedProfile.Layers
|
|
||||||
.OrderByDescending(l => l.Order)
|
|
||||||
.Where(l => l.LayerType == LayerType.Keyboard ||
|
|
||||||
l.LayerType == LayerType.KeyboardGif))
|
|
||||||
{
|
|
||||||
layerModel.Draw<object>(null, drawingContext, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the selection color
|
|
||||||
var color = (Color) ThemeManager.DetectAppStyle(Application.Current).Item2.Resources["AccentColor"];
|
|
||||||
var pen = new Pen(new SolidColorBrush(color), 0.4);
|
|
||||||
|
|
||||||
// Draw the selection outline and resize indicator
|
|
||||||
if (SelectedLayer != null && ShouldDrawLayer(SelectedLayer))
|
|
||||||
{
|
|
||||||
var layerRect = ((KeyboardPropertiesModel) SelectedLayer.Properties).GetRect();
|
|
||||||
// Deflate the rect so that the border is drawn on the inside
|
|
||||||
layerRect.Inflate(-0.2, -0.2);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
drawingContext.Pop();
|
|
||||||
}
|
|
||||||
var image = new DrawingImage(visual.Drawing);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +145,7 @@ namespace Artemis.ViewModels
|
|||||||
public bool CanAddLayer => _selectedProfile != null;
|
public bool CanAddLayer => _selectedProfile != null;
|
||||||
public bool CanRemoveLayer => _selectedProfile != null && _selectedLayer != null;
|
public bool CanRemoveLayer => _selectedProfile != null && _selectedLayer != null;
|
||||||
|
|
||||||
private KeyboardProvider ActiveKeyboard => _mainManager.KeyboardManager.ActiveKeyboard;
|
private KeyboardProvider ActiveKeyboard { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles chaning the active keyboard, updating the preview image and profiles collection
|
/// Handles chaning the active keyboard, updating the preview image and profiles collection
|
||||||
@ -195,6 +153,7 @@ namespace Artemis.ViewModels
|
|||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
public void Handle(ActiveKeyboardChanged message)
|
public void Handle(ActiveKeyboardChanged message)
|
||||||
{
|
{
|
||||||
|
ActiveKeyboard = _mainManager.KeyboardManager.ActiveKeyboard;
|
||||||
NotifyOfPropertyChange(() => KeyboardImage);
|
NotifyOfPropertyChange(() => KeyboardImage);
|
||||||
NotifyOfPropertyChange(() => PreviewSettings);
|
NotifyOfPropertyChange(() => PreviewSettings);
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
@ -401,8 +360,13 @@ namespace Artemis.ViewModels
|
|||||||
var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width);
|
var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width);
|
||||||
var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height);
|
var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height);
|
||||||
|
|
||||||
var hoverLayer = SelectedProfile.Layers.OrderBy(l => l.Order).Where(ShouldDrawLayer)
|
var hoverLayer = SelectedProfile.Layers
|
||||||
.FirstOrDefault(l => ((KeyboardPropertiesModel) l.Properties).GetRect(1).Contains(x, y));
|
.OrderBy(l => l.Order)
|
||||||
|
.Where(l => l.MustDraw())
|
||||||
|
.FirstOrDefault(l => ((KeyboardPropertiesModel) l.Properties)
|
||||||
|
.GetRect(1)
|
||||||
|
.Contains(x, y));
|
||||||
|
|
||||||
SelectedLayer = hoverLayer;
|
SelectedLayer = hoverLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +379,7 @@ namespace Artemis.ViewModels
|
|||||||
var pos = e.GetPosition((Image) e.OriginalSource);
|
var pos = e.GetPosition((Image) e.OriginalSource);
|
||||||
var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width);
|
var x = pos.X/((double) ActiveKeyboard.PreviewSettings.Width/ActiveKeyboard.Width);
|
||||||
var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height);
|
var y = pos.Y/((double) ActiveKeyboard.PreviewSettings.Height/ActiveKeyboard.Height);
|
||||||
var hoverLayer = SelectedProfile.Layers.OrderBy(l => l.Order).Where(ShouldDrawLayer)
|
var hoverLayer = SelectedProfile.Layers.OrderBy(l => l.Order).Where(l => l.MustDraw())
|
||||||
.FirstOrDefault(l => ((KeyboardPropertiesModel) l.Properties).GetRect(1).Contains(x, y));
|
.FirstOrDefault(l => ((KeyboardPropertiesModel) l.Properties).GetRect(1).Contains(x, y));
|
||||||
|
|
||||||
HandleDragging(e, x, y, hoverLayer);
|
HandleDragging(e, x, y, hoverLayer);
|
||||||
@ -440,6 +404,62 @@ namespace Artemis.ViewModels
|
|||||||
KeyboardPreviewCursor = Cursors.Hand;
|
KeyboardPreviewCursor = Cursors.Hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InvokeUpdateKeyboardPreview(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(UpdateKeyboardPreview, DispatcherPriority.ContextIdle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a new image for the keyboard preview
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateKeyboardPreview()
|
||||||
|
{
|
||||||
|
if (_selectedProfile == null || ActiveKeyboard == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var keyboardRect = ActiveKeyboard.KeyboardRectangle(4);
|
||||||
|
var visual = new DrawingVisual();
|
||||||
|
using (var drawingContext = visual.RenderOpen())
|
||||||
|
{
|
||||||
|
// Setup the DrawingVisual's size
|
||||||
|
drawingContext.PushClip(new RectangleGeometry(keyboardRect));
|
||||||
|
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||||
|
|
||||||
|
// Draw the layers
|
||||||
|
foreach (var layer in _selectedProfile.Layers.OrderByDescending(l => l.Order).Where(l => l.MustDraw()))
|
||||||
|
layer.Draw<object>(null, drawingContext, true, false);
|
||||||
|
|
||||||
|
// Get the selection color
|
||||||
|
var color = (Color) ThemeManager.DetectAppStyle(Application.Current).Item2.Resources["AccentColor"];
|
||||||
|
var pen = new Pen(new SolidColorBrush(color), 0.4);
|
||||||
|
|
||||||
|
// Draw the selection outline and resize indicator
|
||||||
|
if (SelectedLayer != null && SelectedLayer.MustDraw())
|
||||||
|
{
|
||||||
|
var layerRect = ((KeyboardPropertiesModel) SelectedLayer.Properties).GetRect();
|
||||||
|
// Deflate the rect so that the border is drawn on the inside
|
||||||
|
layerRect.Inflate(-0.2, -0.2);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
drawingContext.Pop();
|
||||||
|
}
|
||||||
|
KeyboardPreview = new DrawingImage(visual.Drawing);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles dragging the given layer
|
/// Handles dragging the given layer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -496,10 +516,5 @@ namespace Artemis.ViewModels
|
|||||||
draggingProps.Y = (int) Math.Round(y - _draggingLayerOffset.Value.Y);
|
draggingProps.Y = (int) Math.Round(y - _draggingLayerOffset.Value.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ShouldDrawLayer(LayerModel layer)
|
|
||||||
{
|
|
||||||
return layer.Enabled && (layer.LayerType == LayerType.Keyboard || layer.LayerType == LayerType.KeyboardGif);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user