From 8cb2dedb8738e14c7cbc4a0d354f9b43efe5e7b6 Mon Sep 17 00:00:00 2001 From: RKrom Date: Mon, 17 Nov 2014 12:49:06 +0100 Subject: [PATCH] Next step for having the settings of effects stored in the greenshot.ini, using a TypeConverter this seems to work. An important change to the IniValue.cs: here a default value is created when the ini doesn't have a value yet. This used to be just "null". Next step would be that settings forms get a reset/default button. [skip ci] --- .../Configuration/EditorConfiguration.cs | 7 + .../Forms/DropShadowSettingsForm.Designer.cs | 2 +- Greenshot/Forms/DropShadowSettingsForm.cs | 15 +- Greenshot/Forms/ImageEditorForm.cs | 4 +- .../Forms/TornEdgeSettingsForm.Designer.cs | 4 +- Greenshot/Forms/TornEdgeSettingsForm.cs | 13 +- GreenshotPlugin/Core/Effects.cs | 260 +++++++++++++++--- GreenshotPlugin/IniFile/IniValue.cs | 2 +- 8 files changed, 263 insertions(+), 44 deletions(-) diff --git a/Greenshot/Configuration/EditorConfiguration.cs b/Greenshot/Configuration/EditorConfiguration.cs index 9dc0c25f4..451831c03 100644 --- a/Greenshot/Configuration/EditorConfiguration.cs +++ b/Greenshot/Configuration/EditorConfiguration.cs @@ -25,6 +25,7 @@ using System.Drawing; using Greenshot.Drawing.Fields; using GreenshotPlugin.UnmanagedHelpers; using Greenshot.IniFile; +using Greenshot.Core; namespace Greenshot.Configuration { /// @@ -57,6 +58,12 @@ namespace Greenshot.Configuration { [IniProperty("SuppressSaveDialogAtClose", Description="Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue="False")] public bool SuppressSaveDialogAtClose; + [IniProperty("DropShadowEffectSettings", Description = "Settings for the drop shadow effect.")] + public DropShadowEffect DropShadowEffectSettings; + + [IniProperty("TornEdgeEffectSettings", Description = "Settings for the torn edge effect.")] + public TornEdgeEffect TornEdgeEffectSettings; + public override void AfterLoad() { base.AfterLoad(); if (RecentColors == null) { diff --git a/Greenshot/Forms/DropShadowSettingsForm.Designer.cs b/Greenshot/Forms/DropShadowSettingsForm.Designer.cs index 88d73ab04..6f2f0ed74 100644 --- a/Greenshot/Forms/DropShadowSettingsForm.Designer.cs +++ b/Greenshot/Forms/DropShadowSettingsForm.Designer.cs @@ -152,7 +152,7 @@ namespace Greenshot.Forms { this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.TabIndex = 11; this.buttonOK.UseVisualStyleBackColor = true; - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); // // buttonCancel // diff --git a/Greenshot/Forms/DropShadowSettingsForm.cs b/Greenshot/Forms/DropShadowSettingsForm.cs index f9c249dd0..845fc5f96 100644 --- a/Greenshot/Forms/DropShadowSettingsForm.cs +++ b/Greenshot/Forms/DropShadowSettingsForm.cs @@ -27,20 +27,33 @@ using GreenshotPlugin.Core; namespace Greenshot.Forms { public partial class DropShadowSettingsForm : BaseForm { private DropShadowEffect effect; + public DropShadowSettingsForm(DropShadowEffect effect) { this.effect = effect; InitializeComponent(); this.Icon = GreenshotResources.getGreenshotIcon(); + ShowSettings(); + } + + /// + /// Apply the settings from the effect to the view + /// + private void ShowSettings() { trackBar1.Value = (int)(effect.Darkness * 40); offsetX.Value = effect.ShadowOffset.X; offsetY.Value = effect.ShadowOffset.Y; } - private void buttonOK_Click(object sender, EventArgs e) { + private void ButtonOK_Click(object sender, EventArgs e) { effect.Darkness = (float)trackBar1.Value / (float)40; effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value); effect.ShadowSize = (int)thickness.Value; DialogResult = DialogResult.OK; } + + private void ButtonReset_Click(object sender, EventArgs e) { + effect.Reset(); + ShowSettings(); + } } } diff --git a/Greenshot/Forms/ImageEditorForm.cs b/Greenshot/Forms/ImageEditorForm.cs index a4e024c83..ff634c497 100644 --- a/Greenshot/Forms/ImageEditorForm.cs +++ b/Greenshot/Forms/ImageEditorForm.cs @@ -1253,7 +1253,7 @@ namespace Greenshot { /// /// void AddDropshadowToolStripMenuItemClick(object sender, EventArgs e) { - DropShadowEffect dropShadowEffect= new DropShadowEffect(); + DropShadowEffect dropShadowEffect = editorConfiguration.DropShadowEffectSettings; // TODO: Use the dropshadow settings form to make it possible to change the default values DialogResult result = new DropShadowSettingsForm(dropShadowEffect).ShowDialog(this); if (result == DialogResult.OK) { @@ -1283,7 +1283,7 @@ namespace Greenshot { /// /// void TornEdgesToolStripMenuItemClick(object sender, EventArgs e) { - TornEdgeEffect tornEdgeEffect = new TornEdgeEffect(); + TornEdgeEffect tornEdgeEffect = editorConfiguration.TornEdgeEffectSettings; // TODO: Use the dropshadow settings form to make it possible to change the default values DialogResult result = new TornEdgeSettingsForm(tornEdgeEffect).ShowDialog(this); if (result == DialogResult.OK) { diff --git a/Greenshot/Forms/TornEdgeSettingsForm.Designer.cs b/Greenshot/Forms/TornEdgeSettingsForm.Designer.cs index 50a6035f5..db84e8e40 100644 --- a/Greenshot/Forms/TornEdgeSettingsForm.Designer.cs +++ b/Greenshot/Forms/TornEdgeSettingsForm.Designer.cs @@ -166,7 +166,7 @@ namespace Greenshot.Forms { this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.TabIndex = 20; this.buttonOK.UseVisualStyleBackColor = true; - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); // // buttonCancel // @@ -348,7 +348,7 @@ namespace Greenshot.Forms { this.shadowCheckbox.Size = new System.Drawing.Size(110, 17); this.shadowCheckbox.TabIndex = 1; this.shadowCheckbox.UseVisualStyleBackColor = true; - this.shadowCheckbox.CheckedChanged += new System.EventHandler(this.shadowCheckbox_CheckedChanged); + this.shadowCheckbox.CheckedChanged += new System.EventHandler(this.ShadowCheckbox_CheckedChanged); // // TornEdgeSettingsForm // diff --git a/Greenshot/Forms/TornEdgeSettingsForm.cs b/Greenshot/Forms/TornEdgeSettingsForm.cs index d2a7aab72..2d8615add 100644 --- a/Greenshot/Forms/TornEdgeSettingsForm.cs +++ b/Greenshot/Forms/TornEdgeSettingsForm.cs @@ -31,6 +31,10 @@ namespace Greenshot.Forms { this.effect = effect; InitializeComponent(); this.Icon = GreenshotResources.getGreenshotIcon(); + ShowSettings(); + } + + private void ShowSettings() { shadowCheckbox.Checked = effect.GenerateShadow; shadowDarkness.Value = (int)(effect.Darkness * 40); offsetX.Value = effect.ShadowOffset.X; @@ -44,7 +48,7 @@ namespace Greenshot.Forms { left.Checked = effect.Edges[3]; } - private void buttonOK_Click(object sender, EventArgs e) { + private void ButtonOK_Click(object sender, EventArgs e) { effect.Darkness = (float)shadowDarkness.Value / (float)40; effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value); effect.ShadowSize = (int)thickness.Value; @@ -56,7 +60,12 @@ namespace Greenshot.Forms { DialogResult = DialogResult.OK; } - private void shadowCheckbox_CheckedChanged(object sender, EventArgs e) { + private void ButtonReset_Click(object sender, EventArgs e) { + effect.Reset(); + ShowSettings(); + } + + private void ShadowCheckbox_CheckedChanged(object sender, EventArgs e) { thickness.Enabled = shadowCheckbox.Checked; offsetX.Enabled = shadowCheckbox.Checked; offsetY.Enabled = shadowCheckbox.Checked; diff --git a/GreenshotPlugin/Core/Effects.cs b/GreenshotPlugin/Core/Effects.cs index 4ef99332b..2ebcacb5a 100644 --- a/GreenshotPlugin/Core/Effects.cs +++ b/GreenshotPlugin/Core/Effects.cs @@ -22,6 +22,7 @@ using GreenshotPlugin.Core; using log4net; using System; +using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; @@ -32,17 +33,28 @@ namespace Greenshot.Core { /// Interface to describe an effect /// public interface IEffect { + /// + /// Apply this IEffect to the supplied sourceImage. + /// In the process of applying the supplied matrix will be modified to represent the changes. + /// + /// Image to apply the effect to + /// Matrix with the modifications like rotate, translate etc. this can be used to calculate the new location of elements on a canvas + /// new image with applied effect Image Apply(Image sourceImage, Matrix matrix); + + /// + /// Reset all values to their defaults + /// + void Reset(); } /// /// DropShadowEffect /// + [TypeConverter(typeof(EffectConverter))] public class DropShadowEffect : IEffect { public DropShadowEffect() { - Darkness = 0.6f; - ShadowSize = 7; - ShadowOffset = new Point(-1, -1); + Reset(); } public float Darkness { get; @@ -56,32 +68,25 @@ namespace Greenshot.Core { get; set; } + + public virtual void Reset() { + Darkness = 0.6f; + ShadowSize = 7; + ShadowOffset = new Point(-1, -1); + } + public virtual Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateShadow(sourceImage, Darkness, ShadowSize, ShadowOffset, matrix, PixelFormat.Format32bppArgb); } - - public override string ToString() { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Darkness:{0:F2}|ShadowSize:{1}|ShadowOffset:{2},{3}", Darkness, ShadowSize, ShadowOffset.X, ShadowOffset.Y); - return sb.ToString(); - } - - public void ApplySettings(string settings) { - - } } /// /// TornEdgeEffect extends on DropShadowEffect /// + [TypeConverter(typeof(EffectConverter))] public class TornEdgeEffect : DropShadowEffect { public TornEdgeEffect() : base() { - ShadowSize = 7; - ToothHeight = 12; - HorizontalToothRange = 20; - VerticalToothRange = 20; - Edges = new bool[] {true, true, true, true}; - GenerateShadow = true; + Reset(); } public int ToothHeight { get; @@ -104,6 +109,15 @@ namespace Greenshot.Core { set; } + public override void Reset() { + base.Reset(); + ShadowSize = 7; + ToothHeight = 12; + HorizontalToothRange = 20; + VerticalToothRange = 20; + Edges = new bool[] { true, true, true, true }; + GenerateShadow = true; + } public override Image Apply(Image sourceImage, Matrix matrix) { Image tmpTornImage = ImageHelper.CreateTornEdge(sourceImage, ToothHeight, HorizontalToothRange, VerticalToothRange, Edges); if (GenerateShadow) { @@ -113,16 +127,6 @@ namespace Greenshot.Core { } return tmpTornImage; } - - public override string ToString() { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("{0}|GenerateShadow:{1}|ToothHeight:{2}|HorizontalToothRange:{3}|VerticalToothRange:{4}|Edges:{5},{6},{7},{8}", base.ToString(), GenerateShadow, ToothHeight, HorizontalToothRange, VerticalToothRange, Edges[0], Edges[1], Edges[2], Edges[3]); - return sb.ToString(); - } - - public void ApplySettings(string settings) { - - } } /// @@ -132,6 +136,9 @@ namespace Greenshot.Core { public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateGrayscale(sourceImage); } + public void Reset() { + // No settings to reset + } } /// @@ -143,6 +150,9 @@ namespace Greenshot.Core { public MonochromeEffect(byte threshold) { this.threshold = threshold; } + public void Reset() { + // TODO: Modify the threshold to have a default, which is reset here + } public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateMonochrome(sourceImage, threshold); } @@ -153,9 +163,7 @@ namespace Greenshot.Core { /// public class AdjustEffect : IEffect { public AdjustEffect() : base() { - Contrast = 1f; - Brightness = 1f; - Gamma = 1f; + Reset(); } public float Contrast { get; @@ -169,6 +177,11 @@ namespace Greenshot.Core { get; set; } + public void Reset() { + Contrast = 1f; + Brightness = 1f; + Gamma = 1f; + } public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.Adjust(sourceImage, Brightness, Contrast, Gamma); } @@ -180,12 +193,15 @@ namespace Greenshot.Core { public class ReduceColorsEffect : IEffect { private static ILog LOG = LogManager.GetLogger(typeof(ReduceColorsEffect)); public ReduceColorsEffect() : base() { - Colors = 256; + Reset(); } public int Colors { get; set; } + public void Reset() { + Colors = 256; + } public Image Apply(Image sourceImage, Matrix matrix) { using (WuQuantizer quantizer = new WuQuantizer((Bitmap)sourceImage)) { int colorCount = quantizer.GetColorCount(); @@ -208,6 +224,9 @@ namespace Greenshot.Core { public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateNegative(sourceImage); } + public void Reset() { + // No settings to reset + } } /// @@ -215,8 +234,7 @@ namespace Greenshot.Core { /// public class BorderEffect : IEffect { public BorderEffect() { - Width = 2; - Color = Color.Black; + Reset(); } public Color Color { get; @@ -226,6 +244,10 @@ namespace Greenshot.Core { get; set; } + public void Reset() { + Width = 2; + Color = Color.Black; + } public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateBorder(sourceImage, Width, Color, sourceImage.PixelFormat, matrix); } @@ -242,6 +264,9 @@ namespace Greenshot.Core { get; set; } + public void Reset() { + // Angle doesn't have a default value + } public Image Apply(Image sourceImage, Matrix matrix) { RotateFlipType flipType; if (Angle == 90) { @@ -280,6 +305,9 @@ namespace Greenshot.Core { get; set; } + public void Reset() { + // values don't have a default value + } public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.ResizeImage(sourceImage, MaintainAspectRatio, Width, Height, matrix); } @@ -316,8 +344,170 @@ namespace Greenshot.Core { get; set; } + public void Reset() { + // values don't have a default value + } public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.ResizeCanvas(sourceImage, BackgroundColor, Left, Right, Top, Bottom, matrix); } } + + public class EffectConverter : TypeConverter { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { + if (sourceType == typeof(string)) { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { + if (destinationType == typeof(string)) { + return true; + } + if (destinationType == typeof(DropShadowEffect)) { + return true; + } + if (destinationType == typeof(TornEdgeEffect)) { + return true; + } + return base.CanConvertTo(context, destinationType); + } + + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { + // to string + if (destinationType == typeof(string)) { + StringBuilder sb = new StringBuilder(); + if (value.GetType() == typeof(DropShadowEffect)) { + DropShadowEffect effect = value as DropShadowEffect; + RetrieveDropShadowEffectValues(effect, sb); + return sb.ToString(); + } + if (value.GetType() == typeof(TornEdgeEffect)) { + TornEdgeEffect effect = value as TornEdgeEffect; + RetrieveDropShadowEffectValues(effect, sb); + sb.Append("|"); + RetrieveTornEdgeEffectValues(effect, sb); + return sb.ToString(); + } + } + // from string + if (value.GetType() == typeof(string)) { + string settings = value as string; + if (destinationType == typeof(DropShadowEffect)) { + DropShadowEffect effect = new DropShadowEffect(); + ApplyDropShadowEffectValues(settings, effect); + return effect; + } + if (destinationType == typeof(TornEdgeEffect)) { + TornEdgeEffect effect = new TornEdgeEffect(); + ApplyDropShadowEffectValues(settings, effect); + ApplyTornEdgeEffectValues(settings, effect); + return effect; + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { + if (value != null && value.GetType() == typeof(string)) { + string settings = value as string; + if (settings.Contains("ToothHeight")) { + return ConvertTo(context, culture, value, typeof(TornEdgeEffect)); + } else { + return ConvertTo(context, culture, value, typeof(DropShadowEffect)); + } + } + return base.ConvertFrom(context, culture, value); + } + + private void ApplyDropShadowEffectValues(string valuesString, DropShadowEffect effect) { + string[] values = valuesString.Split('|'); + foreach(string nameValuePair in values) { + string[] pair = nameValuePair.Split(':'); + switch (pair[0]) { + case "Darkness" : + float darkness; + if (float.TryParse(pair[1], out darkness)) { + effect.Darkness = darkness; + } + break; + case "ShadowSize": + int shadowSize; + if (int.TryParse(pair[1], out shadowSize)) { + effect.ShadowSize = shadowSize; + } + break; + case "ShadowOffset": + Point shadowOffset = new Point(); + int shadowOffsetX; + int shadowOffsetY; + string[] coordinates = pair[1].Split(','); + if (int.TryParse(coordinates[0], out shadowOffsetX)) { + shadowOffset.X = shadowOffsetX; + } + if (int.TryParse(coordinates[1], out shadowOffsetY)) { + shadowOffset.Y = shadowOffsetY; + } + effect.ShadowOffset = shadowOffset; + break; + } + } + } + + private void ApplyTornEdgeEffectValues(string valuesString, TornEdgeEffect effect) { + string[] values = valuesString.Split('|'); + foreach (string nameValuePair in values) { + string[] pair = nameValuePair.Split(':'); + switch (pair[0]) { + case "GenerateShadow": + bool generateShadow; + if (bool.TryParse(pair[1], out generateShadow)) { + effect.GenerateShadow = generateShadow; + } + break; + case "ToothHeight": + int toothHeight; + if (int.TryParse(pair[1], out toothHeight)) { + effect.ToothHeight = toothHeight; + } + break; + case "HorizontalToothRange": + int horizontalToothRange; + if (int.TryParse(pair[1], out horizontalToothRange)) { + effect.HorizontalToothRange = horizontalToothRange; + } + break; + case "VerticalToothRange": + int verticalToothRange; + if (int.TryParse(pair[1], out verticalToothRange)) { + effect.VerticalToothRange = verticalToothRange; + } + break; + case "Edges": + string[] edges = pair[1].Split(','); + bool edge; + if (bool.TryParse(edges[0], out edge)) { + effect.Edges[0] = edge; + } + if (bool.TryParse(edges[1], out edge)) { + effect.Edges[1] = edge; + } + if (bool.TryParse(edges[2], out edge)) { + effect.Edges[2] = edge; + } + if (bool.TryParse(edges[3], out edge)) { + effect.Edges[3] = edge; + } + break; + } + } + } + + private void RetrieveDropShadowEffectValues(DropShadowEffect effect, StringBuilder sb) { + sb.AppendFormat("Darkness:{0:F2}|ShadowSize:{1}|ShadowOffset:{2},{3}", effect.Darkness, effect.ShadowSize, effect.ShadowOffset.X, effect.ShadowOffset.Y); + } + private void RetrieveTornEdgeEffectValues(TornEdgeEffect effect, StringBuilder sb) { + sb.AppendFormat("GenerateShadow:{0}|ToothHeight:{1}|HorizontalToothRange:{2}|VerticalToothRange:{3}|Edges:{4},{5},{6},{7}", effect.GenerateShadow, effect.ToothHeight, effect.HorizontalToothRange, effect.VerticalToothRange, effect.Edges[0], effect.Edges[1], effect.Edges[2], effect.Edges[3]); + } + } } \ No newline at end of file diff --git a/GreenshotPlugin/IniFile/IniValue.cs b/GreenshotPlugin/IniFile/IniValue.cs index b7376d661..aa4f795a8 100644 --- a/GreenshotPlugin/IniFile/IniValue.cs +++ b/GreenshotPlugin/IniFile/IniValue.cs @@ -305,7 +305,7 @@ namespace Greenshot.IniFile { Value = defaultValueFromConfig; return; } - } else if (propertyValue != null) { + } else if (!string.IsNullOrEmpty(propertyValue)) { if (valueType.IsGenericType && valueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { // We are dealing with a generic type that is nullable valueType = Nullable.GetUnderlyingType(valueType);