Refactored the editor to be in it's own project, this is a step up to improve maintainability.

This commit is contained in:
Robin Krom 2021-04-14 23:19:31 +02:00
parent 54038a3cbe
commit f084d0e95e
No known key found for this signature in database
GPG key ID: BCC01364F1371490
165 changed files with 20167 additions and 19709 deletions

View file

@ -21,6 +21,7 @@
[Files] [Files]
Source: {#ReleaseDir}\Greenshot.exe; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Greenshot.exe; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Greenshot.Base.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Greenshot.Base.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Greenshot.Editor.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Greenshot.exe.config; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Greenshot.exe.config; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\log4net.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\log4net.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Dapplo.Http*.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Dapplo.Http*.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion

View file

@ -108,7 +108,7 @@
<PackageReference Include="MSBuildTasks" Version="1.5.0.235" GeneratePathProperty="true" DevelopmentDependency="true" /> <PackageReference Include="MSBuildTasks" Version="1.5.0.235" GeneratePathProperty="true" DevelopmentDependency="true" />
</ItemGroup> </ItemGroup>
<Target Name="PostBuild" BeforeTargets="PostBuildEvent" Condition="$(MSBuildProjectName.Contains('Plugin')) And !$(MSBuildProjectName.Contains('Test')) And !$(MSBuildProjectName.Contains('Demo'))"> <Target Name="PostBuild" BeforeTargets="PostBuildEvent" Condition="$(MSBuildProjectName.StartsWith('Greenshot.Plugin.'))">
<Exec Command=" <Exec Command="
xcopy /f /y /d &quot;$(TargetDir)$(TargetName).*&quot; &quot;$(SolutionDir)$(SolutionName)\$(OutDir)&quot;&#xD;&#xA; xcopy /f /y /d &quot;$(TargetDir)$(TargetName).*&quot; &quot;$(SolutionDir)$(SolutionName)\$(OutDir)&quot;&#xD;&#xA;
xcopy /f /y /d &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)$(SolutionName)\$(OutDir)&quot;&#xD;&#xA; xcopy /f /y /d &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)$(SolutionName)\$(OutDir)&quot;&#xD;&#xA;

View file

@ -51,8 +51,8 @@ namespace Greenshot.Base.Controls
{ {
if (_vRefresh == 0) if (_vRefresh == 0)
{ {
// get te hDC of the desktop to get the VREFRESH // get te hDC of the desktop to get the V-REFRESH
using SafeWindowDcHandle desktopHandle = SafeWindowDcHandle.FromDesktop(); using var desktopHandle = SafeWindowDcHandle.FromDesktop();
_vRefresh = GDI32.GetDeviceCaps(desktopHandle, DeviceCaps.VREFRESH); _vRefresh = GDI32.GetDeviceCaps(desktopHandle, DeviceCaps.VREFRESH);
} }
@ -88,6 +88,12 @@ namespace Greenshot.Base.Controls
return milliseconds / VRefresh; return milliseconds / VRefresh;
} }
/// <summary>
/// Calculate the interval for the timer to animate the frames
/// </summary>
/// <returns>Milliseconds for the interval</returns>
protected int Interval() => (int)1000 / VRefresh;
/// <summary> /// <summary>
/// Initialize the animation /// Initialize the animation
/// </summary> /// </summary>
@ -102,13 +108,13 @@ namespace Greenshot.Base.Controls
_timer = new Timer _timer = new Timer
{ {
Interval = 1000 / VRefresh Interval = Interval()
}; };
_timer.Tick += timer_Tick; _timer.Tick += Timer_Tick;
_timer.Start(); _timer.Start();
}; };
// Unregister at close // Un-register at close
FormClosing += delegate { _timer?.Stop(); }; FormClosing += delegate { _timer?.Stop(); };
} }
@ -117,7 +123,7 @@ namespace Greenshot.Base.Controls
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void timer_Tick(object sender, EventArgs e) private void Timer_Tick(object sender, EventArgs e)
{ {
try try
{ {
@ -125,7 +131,7 @@ namespace Greenshot.Base.Controls
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warn("An exception occured while animating:", ex); Log.Warn("An exception occurred while animating:", ex);
} }
} }

View file

@ -21,6 +21,7 @@
using System; using System;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.Interfaces.Plugin;

View file

@ -23,6 +23,7 @@ using System;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using log4net; using log4net;

View file

@ -23,6 +23,7 @@ using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.UnmanagedHelpers; using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Base.UnmanagedHelpers.Enums; using Greenshot.Base.UnmanagedHelpers.Enums;

View file

@ -238,19 +238,19 @@ namespace Greenshot.Base.Core
return true; return true;
} }
if (_queue.Count > 0) if (_queue.Count <= 0)
{ {
First = Current; return false;
CurrentFrameNr = 0;
AnimationLeg<T> nextLeg = _queue.Dequeue();
Last = nextLeg.Destination;
Frames = nextLeg.Frames;
EasingType = nextLeg.EasingType;
EasingMode = nextLeg.EasingMode;
return true;
} }
First = Current;
CurrentFrameNr = 0;
AnimationLeg<T> nextLeg = _queue.Dequeue();
Last = nextLeg.Destination;
Frames = nextLeg.Frames;
EasingType = nextLeg.EasingType;
EasingMode = nextLeg.EasingMode;
return true;
return false;
} }
} }
@ -303,20 +303,21 @@ namespace Greenshot.Base.Core
/// <returns>Rectangle</returns> /// <returns>Rectangle</returns>
public override Rectangle Next() public override Rectangle Next()
{ {
if (NextFrame) if (!NextFrame)
{ {
double easingValue = EasingValue; return Current;
double dx = Last.X - First.X;
double dy = Last.Y - First.Y;
int x = First.X + (int) (easingValue * dx);
int y = First.Y + (int) (easingValue * dy);
double dw = Last.Width - First.Width;
double dh = Last.Height - First.Height;
int width = First.Width + (int) (easingValue * dw);
int height = First.Height + (int) (easingValue * dh);
Current = new Rectangle(x, y, width, height);
} }
double easingValue = EasingValue;
double dx = Last.X - First.X;
double dy = Last.Y - First.Y;
int x = First.X + (int) (easingValue * dx);
int y = First.Y + (int) (easingValue * dy);
double dw = Last.Width - First.Width;
double dh = Last.Height - First.Height;
int width = First.Width + (int) (easingValue * dw);
int height = First.Height + (int) (easingValue * dh);
Current = new Rectangle(x, y, width, height);
return Current; return Current;
} }

View file

@ -80,7 +80,7 @@ namespace Greenshot.Base.Core
} }
finally finally
{ {
// Always dispose, even when a exception occured // Always dispose, even when a exception occurred
value.Dispose(); value.Dispose();
} }
} }

View file

@ -30,6 +30,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.Interfaces.Plugin;

View file

@ -26,57 +26,12 @@ using System.Drawing;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
namespace Greenshot.Base.Core namespace Greenshot.Base.Core
{ {
public enum ClipboardFormat
{
PNG,
DIB,
HTML,
HTMLDATAURL,
BITMAP,
DIBV5
}
public enum OutputFormat
{
bmp,
gif,
jpg,
png,
tiff,
greenshot,
ico
}
public enum WindowCaptureMode
{
Screen,
GDI,
Aero,
AeroTransparent,
Auto
}
public enum BuildStates
{
UNSTABLE,
RELEASE_CANDIDATE,
RELEASE
}
public enum ClickActions
{
DO_NOTHING,
OPEN_LAST_IN_EXPLORER,
OPEN_LAST_IN_EDITOR,
OPEN_SETTINGS,
SHOW_CONTEXT_MENU
}
/// <summary> /// <summary>
/// Description of CoreConfiguration. /// Description of CoreConfiguration.
/// </summary> /// </summary>

View file

@ -1,132 +1,101 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Linq;
using System.Linq; using Greenshot.Base.IniFile;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; namespace Greenshot.Base.Core
using log4net; {
/// <summary>
namespace Greenshot.Helpers /// Helper class to simplify working with destinations.
{ /// </summary>
/// <summary> public static class DestinationHelper
/// Description of DestinationHelper. {
/// </summary> private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public static class DestinationHelper
{ /// <summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper)); /// Method to get all the destinations from the plugins
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); /// </summary>
/// <returns>List of IDestination</returns>
/// <summary> public static IEnumerable<IDestination> GetAllDestinations()
/// Initialize the internal destinations {
/// </summary> return SimpleServiceProvider.Current.GetAllInstances<IDestination>()
public static void RegisterInternalDestinations() .Where(destination => destination.IsActive)
{ .Where(destination => CoreConfig.ExcludeDestinations == null ||
foreach (Type destinationType in InterfaceUtils.GetSubclassesOf(typeof(IDestination), true)) !CoreConfig.ExcludeDestinations.Contains(destination.Designation)).OrderBy(p => p.Priority).ThenBy(p => p.Description);
{ }
// Only take our own
if (!"Greenshot.Destinations".Equals(destinationType.Namespace)) /// <summary>
{ /// Get a destination by a designation
continue; /// </summary>
} /// <param name="designation">Designation of the destination</param>
/// <returns>IDestination or null</returns>
if (destinationType.IsAbstract) continue; public static IDestination GetDestination(string designation)
{
IDestination destination; if (designation == null)
try {
{ return null;
destination = (IDestination) Activator.CreateInstance(destinationType); }
}
catch (Exception e) foreach (IDestination destination in GetAllDestinations())
{ {
Log.ErrorFormat("Can't create instance of {0}", destinationType); if (designation.Equals(destination.Designation))
Log.Error(e); {
continue; return destination;
} }
}
if (destination.IsActive)
{ return null;
Log.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation); }
SimpleServiceProvider.Current.AddService(destination);
} /// <summary>
else /// A simple helper method which will call ExportCapture for the destination with the specified designation
{ /// </summary>
Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation); /// <param name="manuallyInitiated"></param>
} /// <param name="designation">WellKnownDestinations</param>
} /// <param name="surface">ISurface</param>
} /// <param name="captureDetails">ICaptureDetails</param>
public static ExportInformation ExportCapture(bool manuallyInitiated, WellKnownDestinations designation, ISurface surface, ICaptureDetails captureDetails)
/// <summary> {
/// Method to get all the destinations from the plugins return ExportCapture(manuallyInitiated, designation.ToString(), surface, captureDetails);
/// </summary> }
/// <returns>List of IDestination</returns>
public static IEnumerable<IDestination> GetAllDestinations() /// <summary>
{ /// A simple helper method which will call ExportCapture for the destination with the specified designation
return SimpleServiceProvider.Current.GetAllInstances<IDestination>() /// </summary>
.Where(destination => destination.IsActive) /// <param name="manuallyInitiated">bool</param>
.Where(destination => CoreConfig.ExcludeDestinations == null || /// <param name="designation">string</param>
!CoreConfig.ExcludeDestinations.Contains(destination.Designation)).OrderBy(p => p.Priority).ThenBy(p => p.Description); /// <param name="surface">ISurface</param>
} /// <param name="captureDetails">ICaptureDetails</param>
public static ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails)
/// <summary> {
/// Get a destination by a designation IDestination destination = GetDestination(designation);
/// </summary> if (destination != null && destination.IsActive)
/// <param name="designation">Designation of the destination</param> {
/// <returns>IDestination or null</returns> return destination.ExportCapture(manuallyInitiated, surface, captureDetails);
public static IDestination GetDestination(string designation) }
{
if (designation == null) return null;
{ }
return null; }
}
foreach (IDestination destination in GetAllDestinations())
{
if (designation.Equals(destination.Designation))
{
return destination;
}
}
return null;
}
/// <summary>
/// A simple helper method which will call ExportCapture for the destination with the specified designation
/// </summary>
/// <param name="manuallyInitiated"></param>
/// <param name="designation"></param>
/// <param name="surface"></param>
/// <param name="captureDetails"></param>
public static ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails)
{
IDestination destination = GetDestination(designation);
if (destination != null && destination.IsActive)
{
return destination.ExportCapture(manuallyInitiated, surface, captureDetails);
}
return null;
}
}
} }

View file

@ -0,0 +1,35 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Base.Core.Enums
{
/// <summary>
/// This are the defined actions which can be initiated when the menu is clicked
/// </summary>
public enum ClickActions
{
DO_NOTHING,
OPEN_LAST_IN_EXPLORER,
OPEN_LAST_IN_EDITOR,
OPEN_SETTINGS,
SHOW_CONTEXT_MENU
}
}

View file

@ -0,0 +1,36 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Base.Core.Enums
{
/// <summary>
/// These are the supported clipboard formats
/// </summary>
public enum ClipboardFormat
{
PNG,
DIB,
HTML,
HTMLDATAURL,
BITMAP,
DIBV5
}
}

View file

@ -0,0 +1,37 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Base.Core.Enums
{
/// <summary>
/// These are the supported output formats
/// </summary>
public enum OutputFormat
{
bmp,
gif,
jpg,
png,
tiff,
greenshot,
ico
}
}

View file

@ -0,0 +1,35 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Base.Core.Enums
{
/// <summary>
/// These are the possible window capture modes
/// </summary>
public enum WindowCaptureMode
{
Screen,
GDI,
Aero,
AeroTransparent,
Auto
}
}

View file

@ -25,6 +25,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using log4net; using log4net;

View file

@ -32,6 +32,7 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.Interfaces.Plugin;

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interop; using Greenshot.Base.Interop;

View file

@ -1,101 +1,101 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using log4net; using log4net;
namespace Greenshot.Help namespace Greenshot.Base.Help
{ {
/// <summary> /// <summary>
/// Description of HelpFileLoader. /// Description of HelpFileLoader.
/// </summary> /// </summary>
public static class HelpFileLoader public static class HelpFileLoader
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(HelpFileLoader)); private static readonly ILog Log = LogManager.GetLogger(typeof(HelpFileLoader));
private const string ExtHelpUrl = @"https://getgreenshot.org/help/"; private const string ExtHelpUrl = @"https://getgreenshot.org/help/";
public static void LoadHelp() public static void LoadHelp()
{ {
string uri = FindOnlineHelpUrl(Language.CurrentLanguage) ?? Language.HelpFilePath; string uri = FindOnlineHelpUrl(Language.CurrentLanguage) ?? Language.HelpFilePath;
Process.Start(uri); Process.Start(uri);
} }
/// <returns>URL of help file in selected ietf, or (if not present) default ietf, or null (if not present, too. probably indicating that there is no internet connection)</returns> /// <returns>URL of help file in selected ietf, or (if not present) default ietf, or null (if not present, too. probably indicating that there is no internet connection)</returns>
private static string FindOnlineHelpUrl(string currentIETF) private static string FindOnlineHelpUrl(string currentIETF)
{ {
string ret = null; string ret = null;
string extHelpUrlForCurrrentIETF = ExtHelpUrl; string extHelpUrlForCurrrentIETF = ExtHelpUrl;
if (!currentIETF.Equals("en-US")) if (!currentIETF.Equals("en-US"))
{ {
extHelpUrlForCurrrentIETF += currentIETF.ToLower() + "/"; extHelpUrlForCurrrentIETF += currentIETF.ToLower() + "/";
} }
HttpStatusCode? httpStatusCode = GetHttpStatus(extHelpUrlForCurrrentIETF); HttpStatusCode? httpStatusCode = GetHttpStatus(extHelpUrlForCurrrentIETF);
if (httpStatusCode == HttpStatusCode.OK) if (httpStatusCode == HttpStatusCode.OK)
{ {
ret = extHelpUrlForCurrrentIETF; ret = extHelpUrlForCurrrentIETF;
} }
else if (httpStatusCode != null && !extHelpUrlForCurrrentIETF.Equals(ExtHelpUrl)) else if (httpStatusCode != null && !extHelpUrlForCurrrentIETF.Equals(ExtHelpUrl))
{ {
Log.DebugFormat("Localized online help not found at {0}, will try {1} as fallback", extHelpUrlForCurrrentIETF, ExtHelpUrl); Log.DebugFormat("Localized online help not found at {0}, will try {1} as fallback", extHelpUrlForCurrrentIETF, ExtHelpUrl);
httpStatusCode = GetHttpStatus(ExtHelpUrl); httpStatusCode = GetHttpStatus(ExtHelpUrl);
if (httpStatusCode == HttpStatusCode.OK) if (httpStatusCode == HttpStatusCode.OK)
{ {
ret = ExtHelpUrl; ret = ExtHelpUrl;
} }
else else
{ {
Log.WarnFormat("{0} returned status {1}", ExtHelpUrl, httpStatusCode); Log.WarnFormat("{0} returned status {1}", ExtHelpUrl, httpStatusCode);
} }
} }
else if (httpStatusCode == null) else if (httpStatusCode == null)
{ {
Log.Info("Internet connection does not seem to be available, will load help from file system."); Log.Info("Internet connection does not seem to be available, will load help from file system.");
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// Retrieves HTTP status for a given url. /// Retrieves HTTP status for a given url.
/// </summary> /// </summary>
/// <param name="url">URL for which the HTTP status is to be checked</param> /// <param name="url">URL for which the HTTP status is to be checked</param>
/// <returns>An HTTP status code, or null if there is none (probably indicating that there is no internet connection available</returns> /// <returns>An HTTP status code, or null if there is none (probably indicating that there is no internet connection available</returns>
private static HttpStatusCode? GetHttpStatus(string url) private static HttpStatusCode? GetHttpStatus(string url)
{ {
try try
{ {
HttpWebRequest req = NetworkHelper.CreateWebRequest(url); HttpWebRequest req = NetworkHelper.CreateWebRequest(url);
using HttpWebResponse res = (HttpWebResponse) req.GetResponse(); using HttpWebResponse res = (HttpWebResponse) req.GetResponse();
return res.StatusCode; return res.StatusCode;
} }
catch (WebException e) catch (WebException e)
{ {
return ((HttpWebResponse) e.Response)?.StatusCode; return ((HttpWebResponse) e.Response)?.StatusCode;
} }
} }
} }
} }

View file

@ -0,0 +1,48 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
namespace Greenshot.Base.Interfaces
{
/// <summary>
/// This is a temporary solution to provide the CaptureHelper functionality via an interface
/// </summary>
public interface ICaptureHelper
{
/// <summary>
///
/// </summary>
/// <param name="windowToCapture"></param>
/// <returns></returns>
WindowDetails SelectCaptureWindow(WindowDetails windowToCapture);
/// <summary>
/// Capture the specified window
/// </summary>
/// <param name="windowToCapture">WindowDetails</param>
/// <param name="capture">ICapture</param>
/// <param name="coreConfigurationWindowCaptureMode">WindowCaptureMode</param>
/// <returns>ICapture</returns>
ICapture CaptureWindow(WindowDetails windowToCapture, ICapture capture, WindowCaptureMode coreConfigurationWindowCaptureMode);
}
}

View file

@ -0,0 +1,46 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using System.Windows.Forms;
namespace Greenshot.Base.Interfaces
{
public interface IGreenshotMainForm : IWin32Window
{
/// <summary>
/// Create the "capture window from list" list
/// </summary>
/// <param name="menuItem">ToolStripMenuItem</param>
/// <param name="eventHandler">EventHandler</param>
void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler);
/// <summary>
/// This is called indirectly from the context menu "Preferences"
/// </summary>
void ShowSetting();
/// <summary>
/// Show the about window
/// </summary>
void ShowAbout();
}
}

View file

@ -1,14 +1,58 @@
using System.Collections.Generic; /*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace Greenshot.Base.Interfaces namespace Greenshot.Base.Interfaces
{ {
/// <summary>
/// This is the interface of the service locator
/// </summary>
public interface IServiceLocator public interface IServiceLocator
{ {
/// <summary>
/// Get all instances of the specified service
/// </summary>
/// <typeparam name="TService">Service to find</typeparam>
/// <returns>IEnumerable{TService}</returns>
IEnumerable<TService> GetAllInstances<TService>(); IEnumerable<TService> GetAllInstances<TService>();
/// <summary>
/// Get the only instance of the specified service
/// </summary>
/// <typeparam name="TService">Service to find</typeparam>
/// <returns>TService</returns>
TService GetInstance<TService>(); TService GetInstance<TService>();
/// <summary>
/// Add one of more services to the registry
/// </summary>
/// <typeparam name="TService">Type of the service</typeparam>
/// <param name="services">One or more services which need to be added</param>
void AddService<TService>(params TService[] services); void AddService<TService>(params TService[] services);
/// <summary>
/// Add multiple services to the registry
/// </summary>
/// <typeparam name="TService">Type of the service</typeparam>
/// <param name="services">IEnumerable{TService} with services to add</param>
void AddService<TService>(IEnumerable<TService> services); void AddService<TService>(IEnumerable<TService> services);
} }
} }

View file

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums;
using Greenshot.Base.Effects; using Greenshot.Base.Effects;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;

View file

@ -64,6 +64,10 @@ namespace Greenshot.Base.UnmanagedHelpers
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject); public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetPackageFullName(IntPtr hProcess, ref Int32 packageFullNameLength, StringBuilder fullName);
/// <summary> /// <summary>
/// Method to get the process path /// Method to get the process path
/// </summary> /// </summary>

View file

@ -0,0 +1,36 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Greenshot.Base
{
/// <summary>
/// This contains all the well known destinations, make it possible to find them via the service locator
/// </summary>
public enum WellKnownDestinations
{
Clipboard,
EMail,
FileDialog,
FileNoDialog,
Picker,
Printer
}
}

View file

@ -1,181 +1,181 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using Greenshot.Base.Effects; using Greenshot.Base.Effects;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.UnmanagedHelpers.Enums; using Greenshot.Base.UnmanagedHelpers.Enums;
using Greenshot.Base.UnmanagedHelpers.Structs; using Greenshot.Base.UnmanagedHelpers.Structs;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Configuration namespace Greenshot.Editor.Configuration
{ {
/// <summary> /// <summary>
/// Description of CoreConfiguration. /// Description of CoreConfiguration.
/// </summary> /// </summary>
[IniSection("Editor", Description = "Greenshot editor configuration")] [IniSection("Editor", Description = "Greenshot editor configuration")]
public class EditorConfiguration : IniSection public class EditorConfiguration : IniSection
{ {
[IniProperty("RecentColors", Separator = "|", Description = "Last used colors")] [IniProperty("RecentColors", Separator = "|", Description = "Last used colors")]
public List<Color> RecentColors { get; set; } public List<Color> RecentColors { get; set; }
[IniProperty("LastFieldValue", Separator = "|", Description = "Field values, make sure the last used settings are re-used")] [IniProperty("LastFieldValue", Separator = "|", Description = "Field values, make sure the last used settings are re-used")]
public Dictionary<string, object> LastUsedFieldValues { get; set; } public Dictionary<string, object> LastUsedFieldValues { get; set; }
[IniProperty("MatchSizeToCapture", Description = "Match the editor window size to the capture", DefaultValue = "True")] [IniProperty("MatchSizeToCapture", Description = "Match the editor window size to the capture", DefaultValue = "True")]
public bool MatchSizeToCapture { get; set; } public bool MatchSizeToCapture { get; set; }
[IniProperty("WindowPlacementFlags", Description = "Placement flags", DefaultValue = "0")] [IniProperty("WindowPlacementFlags", Description = "Placement flags", DefaultValue = "0")]
public WindowPlacementFlags WindowPlacementFlags { get; set; } public WindowPlacementFlags WindowPlacementFlags { get; set; }
[IniProperty("WindowShowCommand", Description = "Show command", DefaultValue = "Normal")] [IniProperty("WindowShowCommand", Description = "Show command", DefaultValue = "Normal")]
public ShowWindowCommand ShowWindowCommand { get; set; } public ShowWindowCommand ShowWindowCommand { get; set; }
[IniProperty("WindowMinPosition", Description = "Position of minimized window", DefaultValue = "-1,-1")] [IniProperty("WindowMinPosition", Description = "Position of minimized window", DefaultValue = "-1,-1")]
public Point WindowMinPosition { get; set; } public Point WindowMinPosition { get; set; }
[IniProperty("WindowMaxPosition", Description = "Position of maximized window", DefaultValue = "-1,-1")] [IniProperty("WindowMaxPosition", Description = "Position of maximized window", DefaultValue = "-1,-1")]
public Point WindowMaxPosition { get; set; } public Point WindowMaxPosition { get; set; }
[IniProperty("WindowNormalPosition", Description = "Position of normal window", DefaultValue = "100,100,400,400")] [IniProperty("WindowNormalPosition", Description = "Position of normal window", DefaultValue = "100,100,400,400")]
public Rectangle WindowNormalPosition { get; set; } public Rectangle WindowNormalPosition { get; set; }
[IniProperty("ReuseEditor", Description = "Reuse already open editor", DefaultValue = "false")] [IniProperty("ReuseEditor", Description = "Reuse already open editor", DefaultValue = "false")]
public bool ReuseEditor { get; set; } public bool ReuseEditor { get; set; }
[IniProperty("FreehandSensitivity", [IniProperty("FreehandSensitivity",
Description = Description =
"The smaller this number, the less smoothing is used. Decrease for detailed drawing, e.g. when using a pen. Increase for smoother lines. e.g. when you want to draw a smooth line.", "The smaller this number, the less smoothing is used. Decrease for detailed drawing, e.g. when using a pen. Increase for smoother lines. e.g. when you want to draw a smooth line.",
DefaultValue = "3")] DefaultValue = "3")]
public int FreehandSensitivity { get; set; } public int FreehandSensitivity { get; set; }
[IniProperty("SuppressSaveDialogAtClose", Description = "Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue = "False")] [IniProperty("SuppressSaveDialogAtClose", Description = "Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue = "False")]
public bool SuppressSaveDialogAtClose { get; set; } public bool SuppressSaveDialogAtClose { get; set; }
[IniProperty("DropShadowEffectSettings", Description = "Settings for the drop shadow effect.")] [IniProperty("DropShadowEffectSettings", Description = "Settings for the drop shadow effect.")]
public DropShadowEffect DropShadowEffectSettings { get; set; } public DropShadowEffect DropShadowEffectSettings { get; set; }
[IniProperty("TornEdgeEffectSettings", Description = "Settings for the torn edge effect.")] [IniProperty("TornEdgeEffectSettings", Description = "Settings for the torn edge effect.")]
public TornEdgeEffect TornEdgeEffectSettings { get; set; } public TornEdgeEffect TornEdgeEffectSettings { get; set; }
public override void AfterLoad() public override void AfterLoad()
{ {
base.AfterLoad(); base.AfterLoad();
if (RecentColors == null) if (RecentColors == null)
{ {
RecentColors = new List<Color>(); RecentColors = new List<Color>();
} }
} }
/// <param name="requestingType">Type of the class for which to create the field</param> /// <param name="requestingType">Type of the class for which to create the field</param>
/// <param name="fieldType">FieldType of the field to construct</param> /// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="preferredDefaultValue"></param> /// <param name="preferredDefaultValue"></param>
/// <returns>a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope</returns> /// <returns>a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope</returns>
public IField CreateField(Type requestingType, IFieldType fieldType, object preferredDefaultValue) public IField CreateField(Type requestingType, IFieldType fieldType, object preferredDefaultValue)
{ {
string requestingTypeName = requestingType.Name; string requestingTypeName = requestingType.Name;
string requestedField = requestingTypeName + "." + fieldType.Name; string requestedField = requestingTypeName + "." + fieldType.Name;
object fieldValue = preferredDefaultValue; object fieldValue = preferredDefaultValue;
// Check if the configuration exists // Check if the configuration exists
if (LastUsedFieldValues == null) if (LastUsedFieldValues == null)
{ {
LastUsedFieldValues = new Dictionary<string, object>(); LastUsedFieldValues = new Dictionary<string, object>();
} }
// Check if settings for the requesting type exist, if not create! // Check if settings for the requesting type exist, if not create!
if (LastUsedFieldValues.ContainsKey(requestedField)) if (LastUsedFieldValues.ContainsKey(requestedField))
{ {
// Check if a value is set (not null)! // Check if a value is set (not null)!
if (LastUsedFieldValues[requestedField] != null) if (LastUsedFieldValues[requestedField] != null)
{ {
fieldValue = LastUsedFieldValues[requestedField]; fieldValue = LastUsedFieldValues[requestedField];
} }
else else
{ {
// Overwrite null value // Overwrite null value
LastUsedFieldValues[requestedField] = fieldValue; LastUsedFieldValues[requestedField] = fieldValue;
} }
} }
else else
{ {
LastUsedFieldValues.Add(requestedField, fieldValue); LastUsedFieldValues.Add(requestedField, fieldValue);
} }
return new Field(fieldType, requestingType) return new Field(fieldType, requestingType)
{ {
Value = fieldValue Value = fieldValue
}; };
} }
public void UpdateLastFieldValue(IField field) public void UpdateLastFieldValue(IField field)
{ {
string requestedField = field.Scope + "." + field.FieldType.Name; string requestedField = field.Scope + "." + field.FieldType.Name;
// Check if the configuration exists // Check if the configuration exists
if (LastUsedFieldValues == null) if (LastUsedFieldValues == null)
{ {
LastUsedFieldValues = new Dictionary<string, object>(); LastUsedFieldValues = new Dictionary<string, object>();
} }
// check if settings for the requesting type exist, if not create! // check if settings for the requesting type exist, if not create!
if (LastUsedFieldValues.ContainsKey(requestedField)) if (LastUsedFieldValues.ContainsKey(requestedField))
{ {
LastUsedFieldValues[requestedField] = field.Value; LastUsedFieldValues[requestedField] = field.Value;
} }
else else
{ {
LastUsedFieldValues.Add(requestedField, field.Value); LastUsedFieldValues.Add(requestedField, field.Value);
} }
} }
public void ResetEditorPlacement() public void ResetEditorPlacement()
{ {
WindowNormalPosition = new Rectangle(100, 100, 400, 400); WindowNormalPosition = new Rectangle(100, 100, 400, 400);
WindowMaxPosition = new Point(-1, -1); WindowMaxPosition = new Point(-1, -1);
WindowMinPosition = new Point(-1, -1); WindowMinPosition = new Point(-1, -1);
WindowPlacementFlags = 0; WindowPlacementFlags = 0;
ShowWindowCommand = ShowWindowCommand.Normal; ShowWindowCommand = ShowWindowCommand.Normal;
} }
public WindowPlacement GetEditorPlacement() public WindowPlacement GetEditorPlacement()
{ {
WindowPlacement placement = WindowPlacement.Default; WindowPlacement placement = WindowPlacement.Default;
placement.NormalPosition = new RECT(WindowNormalPosition); placement.NormalPosition = new RECT(WindowNormalPosition);
placement.MaxPosition = new POINT(WindowMaxPosition); placement.MaxPosition = new POINT(WindowMaxPosition);
placement.MinPosition = new POINT(WindowMinPosition); placement.MinPosition = new POINT(WindowMinPosition);
placement.ShowCmd = ShowWindowCommand; placement.ShowCmd = ShowWindowCommand;
placement.Flags = WindowPlacementFlags; placement.Flags = WindowPlacementFlags;
return placement; return placement;
} }
public void SetEditorPlacement(WindowPlacement placement) public void SetEditorPlacement(WindowPlacement placement)
{ {
WindowNormalPosition = placement.NormalPosition.ToRectangle(); WindowNormalPosition = placement.NormalPosition.ToRectangle();
WindowMaxPosition = placement.MaxPosition.ToPoint(); WindowMaxPosition = placement.MaxPosition.ToPoint();
WindowMinPosition = placement.MinPosition.ToPoint(); WindowMinPosition = placement.MinPosition.ToPoint();
ShowWindowCommand = placement.ShowCmd; ShowWindowCommand = placement.ShowCmd;
WindowPlacementFlags = placement.Flags; WindowPlacementFlags = placement.Flags;
} }
} }
} }

View file

@ -0,0 +1,82 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System.Diagnostics.CodeAnalysis;
namespace Greenshot.Editor.Configuration
{
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum LangKey
{
none,
contextmenu_capturefullscreen_all,
contextmenu_capturefullscreen_left,
contextmenu_capturefullscreen_top,
contextmenu_capturefullscreen_right,
contextmenu_capturefullscreen_bottom,
contextmenu_captureie,
editor_clipboardfailed,
editor_close_on_save,
editor_close_on_save_title,
editor_copytoclipboard,
editor_cuttoclipboard,
editor_deleteelement,
editor_downonelevel,
editor_downtobottom,
editor_duplicate,
editor_email,
editor_imagesaved,
editor_title,
editor_uponelevel,
editor_uptotop,
editor_undo,
editor_redo,
editor_resetsize,
error,
error_multipleinstances,
error_openfile,
error_openlink,
error_save,
error_save_invalid_chars,
print_error,
quicksettings_destination_file,
settings_destination,
settings_destination_clipboard,
settings_destination_editor,
settings_destination_fileas,
settings_destination_printer,
settings_destination_picker,
settings_filenamepattern,
settings_message_filenamepattern,
settings_printoptions,
settings_tooltip_filenamepattern,
settings_tooltip_language,
settings_tooltip_primaryimageformat,
settings_tooltip_storagelocation,
settings_visualization,
settings_window_capture_mode,
tooltip_firststart,
warning,
warning_hotkeys,
wait_ie_capture,
update_found
}
}

View file

@ -1,49 +1,49 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// Description of BindableToolStripButton. /// Description of BindableToolStripButton.
/// </summary> /// </summary>
public class BindableToolStripButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable public class BindableToolStripButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
[Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
public string LanguageKey { get; set; } public string LanguageKey { get; set; }
public BindableToolStripButton() public BindableToolStripButton()
{ {
CheckedChanged += BindableToolStripButton_CheckedChanged; CheckedChanged += BindableToolStripButton_CheckedChanged;
} }
private void BindableToolStripButton_CheckedChanged(object sender, EventArgs e) private void BindableToolStripButton_CheckedChanged(object sender, EventArgs e)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Checked")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Checked"));
} }
} }
} }

View file

@ -1,49 +1,49 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// A simple ToolStripComboBox implementing INotifyPropertyChanged for data binding /// A simple ToolStripComboBox implementing INotifyPropertyChanged for data binding
/// </summary> /// </summary>
public class BindableToolStripComboBox : ToolStripComboBox, INotifyPropertyChanged, IGreenshotLanguageBindable public class BindableToolStripComboBox : ToolStripComboBox, INotifyPropertyChanged, IGreenshotLanguageBindable
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
[Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
public string LanguageKey { get; set; } public string LanguageKey { get; set; }
public BindableToolStripComboBox() public BindableToolStripComboBox()
{ {
SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged; SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
} }
private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedItem")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedItem"));
} }
} }
} }

View file

@ -1,82 +1,82 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// A simple ToolStripDropDownButton implementing INotifyPropertyChanged for data binding. /// A simple ToolStripDropDownButton implementing INotifyPropertyChanged for data binding.
/// Also, when a DropDownItem is selected, the DropDownButton adopts its Tag and Image. /// Also, when a DropDownItem is selected, the DropDownButton adopts its Tag and Image.
/// The selected tag can be accessed via SelectedTag property. /// The selected tag can be accessed via SelectedTag property.
/// </summary> /// </summary>
public class BindableToolStripDropDownButton : ToolStripDropDownButton, INotifyPropertyChanged, IGreenshotLanguageBindable public class BindableToolStripDropDownButton : ToolStripDropDownButton, INotifyPropertyChanged, IGreenshotLanguageBindable
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
[Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
public string LanguageKey { get; set; } public string LanguageKey { get; set; }
public object SelectedTag public object SelectedTag
{ {
get get
{ {
if (Tag == null && DropDownItems.Count > 0) Tag = DropDownItems[0].Tag; if (Tag == null && DropDownItems.Count > 0) Tag = DropDownItems[0].Tag;
return Tag; return Tag;
} }
set { AdoptFromTag(value); } set { AdoptFromTag(value); }
} }
protected override void OnDropDownItemClicked(ToolStripItemClickedEventArgs e) protected override void OnDropDownItemClicked(ToolStripItemClickedEventArgs e)
{ {
ToolStripItem clickedItem = e.ClickedItem; ToolStripItem clickedItem = e.ClickedItem;
if (Tag == null || !Tag.Equals(clickedItem.Tag)) if (Tag == null || !Tag.Equals(clickedItem.Tag))
{ {
Tag = clickedItem.Tag; Tag = clickedItem.Tag;
Image = clickedItem.Image; Image = clickedItem.Image;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag"));
} }
base.OnDropDownItemClicked(e); base.OnDropDownItemClicked(e);
} }
private void AdoptFromTag(object tag) private void AdoptFromTag(object tag)
{ {
if (Tag == null || !Tag.Equals(tag)) if (Tag == null || !Tag.Equals(tag))
{ {
Tag = tag; Tag = tag;
foreach (ToolStripItem item in DropDownItems) foreach (ToolStripItem item in DropDownItems)
{ {
if (item.Tag != null && item.Tag.Equals(tag)) if (item.Tag != null && item.Tag.Equals(tag))
{ {
Image = item.Image; Image = item.Image;
break; break;
} }
} }
Tag = tag; Tag = tag;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag"));
} }
} }
} }
} }

View file

@ -1,99 +1,99 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
using ColorDialog = Greenshot.Forms.ColorDialog; using ColorDialog = Greenshot.Editor.Forms.ColorDialog;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// Description of ColorButton. /// Description of ColorButton.
/// </summary> /// </summary>
public class ColorButton : Button, IGreenshotLanguageBindable public class ColorButton : Button, IGreenshotLanguageBindable
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
private Color _selectedColor = Color.White; private Color _selectedColor = Color.White;
[Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
public string LanguageKey { get; set; } public string LanguageKey { get; set; }
public ColorButton() public ColorButton()
{ {
Click += ColorButtonClick; Click += ColorButtonClick;
} }
public Color SelectedColor public Color SelectedColor
{ {
get { return _selectedColor; } get { return _selectedColor; }
set set
{ {
_selectedColor = value; _selectedColor = value;
Brush brush; Brush brush;
if (value != Color.Transparent) if (value != Color.Transparent)
{ {
brush = new SolidBrush(value); brush = new SolidBrush(value);
} }
else else
{ {
brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray); brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray);
} }
if (Image != null) if (Image != null)
{ {
using Graphics graphics = Graphics.FromImage(Image); using Graphics graphics = Graphics.FromImage(Image);
graphics.FillRectangle(brush, new Rectangle(4, 17, 16, 3)); graphics.FillRectangle(brush, new Rectangle(4, 17, 16, 3));
} }
// cleanup GDI Object // cleanup GDI Object
brush.Dispose(); brush.Dispose();
Invalidate(); Invalidate();
} }
} }
private void ColorButtonClick(object sender, EventArgs e) private void ColorButtonClick(object sender, EventArgs e)
{ {
var colorDialog = new ColorDialog var colorDialog = new ColorDialog
{ {
Color = SelectedColor Color = SelectedColor
}; };
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel) if (colorDialog.DialogResult == DialogResult.Cancel)
{ {
return; return;
} }
if (colorDialog.Color.Equals(SelectedColor)) if (colorDialog.Color.Equals(SelectedColor))
{ {
return; return;
} }
SelectedColor = colorDialog.Color; SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
} }
} }
} }

View file

@ -1,84 +1,84 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// Prevent having a gradient background in the toolstrip, and the overflow button /// Prevent having a gradient background in the toolstrip, and the overflow button
/// See: https://stackoverflow.com/a/16926979 /// See: https://stackoverflow.com/a/16926979
/// </summary> /// </summary>
internal class CustomProfessionalColorTable : ProfessionalColorTable internal class CustomProfessionalColorTable : ProfessionalColorTable
{ {
public override Color ToolStripGradientBegin public override Color ToolStripGradientBegin
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
public override Color ToolStripGradientMiddle public override Color ToolStripGradientMiddle
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
public override Color ToolStripGradientEnd public override Color ToolStripGradientEnd
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
public override Color OverflowButtonGradientBegin public override Color OverflowButtonGradientBegin
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
public override Color OverflowButtonGradientMiddle public override Color OverflowButtonGradientMiddle
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
public override Color OverflowButtonGradientEnd public override Color OverflowButtonGradientEnd
{ {
get { return SystemColors.Control; } get { return SystemColors.Control; }
} }
} }
/// <summary> /// <summary>
/// ToolStripProfessionalRenderer without having a visual artifact /// ToolStripProfessionalRenderer without having a visual artifact
/// See: https://stackoverflow.com/a/16926979 and https://stackoverflow.com/a/13418840 /// See: https://stackoverflow.com/a/16926979 and https://stackoverflow.com/a/13418840
/// </summary> /// </summary>
public class CustomToolStripProfessionalRenderer : ToolStripProfessionalRenderer public class CustomToolStripProfessionalRenderer : ToolStripProfessionalRenderer
{ {
public CustomToolStripProfessionalRenderer() : base(new CustomProfessionalColorTable()) public CustomToolStripProfessionalRenderer() : base(new CustomProfessionalColorTable())
{ {
RoundedEdges = false; RoundedEdges = false;
} }
/// <summary> /// <summary>
/// By overriding the OnRenderToolStripBorder we can make the ToolStrip without border /// By overriding the OnRenderToolStripBorder we can make the ToolStrip without border
/// </summary> /// </summary>
/// <param name="e"></param> /// <param name="e"></param>
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{ {
// Don't draw a border // Don't draw a border
} }
} }
} }

View file

@ -1,141 +1,141 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// ToolStripComboBox containing installed font families, /// ToolStripComboBox containing installed font families,
/// implementing INotifyPropertyChanged for data binding /// implementing INotifyPropertyChanged for data binding
/// </summary> /// </summary>
public class FontFamilyComboBox : ToolStripComboBox, INotifyPropertyChanged public class FontFamilyComboBox : ToolStripComboBox, INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public FontFamily FontFamily public FontFamily FontFamily
{ {
get { return (FontFamily) SelectedItem; } get { return (FontFamily) SelectedItem; }
set set
{ {
if (!SelectedItem.Equals(value)) if (!SelectedItem.Equals(value))
{ {
SelectedItem = value; SelectedItem = value;
} }
} }
} }
public FontFamilyComboBox() public FontFamilyComboBox()
{ {
if (ComboBox != null) if (ComboBox != null)
{ {
ComboBox.DataSource = FontFamily.Families; ComboBox.DataSource = FontFamily.Families;
ComboBox.DisplayMember = "Name"; ComboBox.DisplayMember = "Name";
SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged; SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
ComboBox.DrawMode = DrawMode.OwnerDrawFixed; ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
ComboBox.DrawItem += ComboBox_DrawItem; ComboBox.DrawItem += ComboBox_DrawItem;
} }
} }
private void ComboBox_DrawItem(object sender, DrawItemEventArgs e) private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
{ {
// DrawBackground handles drawing the background (i.e,. hot-tracked v. not) // DrawBackground handles drawing the background (i.e,. hot-tracked v. not)
// It uses the system colors (Bluish, and and white, by default) // It uses the system colors (Bluish, and and white, by default)
// same as calling e.Graphics.FillRectangle ( SystemBrushes.Highlight, e.Bounds ); // same as calling e.Graphics.FillRectangle ( SystemBrushes.Highlight, e.Bounds );
e.DrawBackground(); e.DrawBackground();
if (e.Index > -1) if (e.Index > -1)
{ {
FontFamily fontFamily = Items[e.Index] as FontFamily; FontFamily fontFamily = Items[e.Index] as FontFamily;
FontStyle fontStyle = FontStyle.Regular; FontStyle fontStyle = FontStyle.Regular;
if (fontFamily != null && !fontFamily.IsStyleAvailable(FontStyle.Regular)) if (fontFamily != null && !fontFamily.IsStyleAvailable(FontStyle.Regular))
{ {
if (fontFamily.IsStyleAvailable(FontStyle.Bold)) if (fontFamily.IsStyleAvailable(FontStyle.Bold))
{ {
fontStyle = FontStyle.Bold; fontStyle = FontStyle.Bold;
} }
else if (fontFamily.IsStyleAvailable(FontStyle.Italic)) else if (fontFamily.IsStyleAvailable(FontStyle.Italic))
{ {
fontStyle = FontStyle.Italic; fontStyle = FontStyle.Italic;
} }
else if (fontFamily.IsStyleAvailable(FontStyle.Strikeout)) else if (fontFamily.IsStyleAvailable(FontStyle.Strikeout))
{ {
fontStyle = FontStyle.Strikeout; fontStyle = FontStyle.Strikeout;
} }
else if (fontFamily.IsStyleAvailable(FontStyle.Underline)) else if (fontFamily.IsStyleAvailable(FontStyle.Underline))
{ {
fontStyle = FontStyle.Underline; fontStyle = FontStyle.Underline;
} }
} }
try try
{ {
if (fontFamily != null) if (fontFamily != null)
{ {
DrawText(e.Graphics, fontFamily, fontStyle, e.Bounds, fontFamily.Name); DrawText(e.Graphics, fontFamily, fontStyle, e.Bounds, fontFamily.Name);
} }
} }
catch catch
{ {
// If the drawing failed, BUG-1770 seems to have a weird case that causes: Font 'Lucida Sans Typewriter' does not support style 'Regular' // If the drawing failed, BUG-1770 seems to have a weird case that causes: Font 'Lucida Sans Typewriter' does not support style 'Regular'
if (fontFamily != null) if (fontFamily != null)
{ {
DrawText(e.Graphics, FontFamily.GenericSansSerif, FontStyle.Regular, e.Bounds, fontFamily.Name); DrawText(e.Graphics, FontFamily.GenericSansSerif, FontStyle.Regular, e.Bounds, fontFamily.Name);
} }
} }
} }
// Uncomment this if you actually like the way the focus rectangle looks // Uncomment this if you actually like the way the focus rectangle looks
//e.DrawFocusRectangle (); //e.DrawFocusRectangle ();
} }
/// <summary> /// <summary>
/// Helper method to draw the string /// Helper method to draw the string
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="fontFamily"></param> /// <param name="fontFamily"></param>
/// <param name="fontStyle"></param> /// <param name="fontStyle"></param>
/// <param name="bounds"></param> /// <param name="bounds"></param>
/// <param name="text"></param> /// <param name="text"></param>
private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text) private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text)
{ {
using Font font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel); using Font font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel);
// Make sure the text is visible by centering it in the line // Make sure the text is visible by centering it in the line
using StringFormat stringFormat = new StringFormat using StringFormat stringFormat = new StringFormat
{ {
LineAlignment = StringAlignment.Center LineAlignment = StringAlignment.Center
}; };
graphics.DrawString(text, font, Brushes.Black, bounds, stringFormat); graphics.DrawString(text, font, Brushes.Black, bounds, stringFormat);
} }
private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
{ {
if (PropertyChanged == null) return; if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs("Text")); PropertyChanged(this, new PropertyChangedEventArgs("Text"));
PropertyChanged(this, new PropertyChangedEventArgs("FontFamily")); PropertyChanged(this, new PropertyChangedEventArgs("FontFamily"));
PropertyChanged(this, new PropertyChangedEventArgs("SelectedIndex")); PropertyChanged(this, new PropertyChangedEventArgs("SelectedIndex"));
PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem")); PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
} }
} }
} }

View file

@ -1,65 +1,65 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.UnmanagedHelpers.Enums; using Greenshot.Base.UnmanagedHelpers.Enums;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// This is an extension of the default MenuStrip and allows us to click it even when the form doesn't have focus. /// This is an extension of the default MenuStrip and allows us to click it even when the form doesn't have focus.
/// See: https://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx /// See: https://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx
/// </summary> /// </summary>
public class MenuStripEx : MenuStrip public class MenuStripEx : MenuStrip
{ {
private enum NativeConstants : uint private enum NativeConstants : uint
{ {
MA_ACTIVATE = 1, MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2, MA_ACTIVATEANDEAT = 2,
} }
private bool _clickThrough; private bool _clickThrough;
/// <summary> /// <summary>
/// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus. /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Default value is false, which is the same behavior provided by the base ToolStrip class. /// Default value is false, which is the same behavior provided by the base ToolStrip class.
/// </remarks> /// </remarks>
public bool ClickThrough public bool ClickThrough
{ {
get { return _clickThrough; } get { return _clickThrough; }
set { _clickThrough = value; } set { _clickThrough = value; }
} }
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
base.WndProc(ref m); base.WndProc(ref m);
var windowsMessage = (WindowsMessages) m.Msg; var windowsMessage = (WindowsMessages) m.Msg;
if (_clickThrough && windowsMessage == WindowsMessages.WM_MOUSEACTIVATE && m.Result == (IntPtr) NativeConstants.MA_ACTIVATEANDEAT) if (_clickThrough && windowsMessage == WindowsMessages.WM_MOUSEACTIVATE && m.Result == (IntPtr) NativeConstants.MA_ACTIVATEANDEAT)
{ {
m.Result = (IntPtr) NativeConstants.MA_ACTIVATE; m.Result = (IntPtr) NativeConstants.MA_ACTIVATE;
} }
} }
} }
} }

View file

@ -1,70 +1,70 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// See: https://nickstips.wordpress.com/2010/03/03/c-panel-resets-scroll-position-after-focus-is-lost-and-regained/ /// See: https://nickstips.wordpress.com/2010/03/03/c-panel-resets-scroll-position-after-focus-is-lost-and-regained/
/// </summary> /// </summary>
public class NonJumpingPanel : Panel public class NonJumpingPanel : Panel
{ {
protected override Point ScrollToControl(Control activeControl) protected override Point ScrollToControl(Control activeControl)
{ {
// Returning the current location prevents the panel from // Returning the current location prevents the panel from
// scrolling to the active control when the panel loses and regains focus // scrolling to the active control when the panel loses and regains focus
return DisplayRectangle.Location; return DisplayRectangle.Location;
} }
/// <summary> /// <summary>
/// Add horizontal scrolling to the panel, when using the wheel and the shift key is pressed /// Add horizontal scrolling to the panel, when using the wheel and the shift key is pressed
/// </summary> /// </summary>
/// <param name="e">MouseEventArgs</param> /// <param name="e">MouseEventArgs</param>
protected override void OnMouseWheel(MouseEventArgs e) protected override void OnMouseWheel(MouseEventArgs e)
{ {
//Check if Scrollbars available and CTRL key pressed -> Zoom IN OUT //Check if Scrollbars available and CTRL key pressed -> Zoom IN OUT
if ((VScroll || HScroll) && (ModifierKeys & Keys.Control) == Keys.Control) if ((VScroll || HScroll) && (ModifierKeys & Keys.Control) == Keys.Control)
{ {
VScroll = false; VScroll = false;
HScroll = false; HScroll = false;
base.OnMouseWheel(e); base.OnMouseWheel(e);
VScroll = true; VScroll = true;
HScroll = true; HScroll = true;
} }
else else
{ {
//Vertical Scoll with SHIFT key pressed //Vertical Scoll with SHIFT key pressed
if (VScroll && (ModifierKeys & Keys.Shift) == Keys.Shift) if (VScroll && (ModifierKeys & Keys.Shift) == Keys.Shift)
{ {
VScroll = false; VScroll = false;
base.OnMouseWheel(e); base.OnMouseWheel(e);
VScroll = true; VScroll = true;
} }
else else
{ {
base.OnMouseWheel(e); base.OnMouseWheel(e);
} }
} }
} }
} }
} }

View file

@ -1,204 +1,204 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.UnmanagedHelpers; using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Base.UnmanagedHelpers.Enums; using Greenshot.Base.UnmanagedHelpers.Enums;
using Greenshot.Forms; using Greenshot.Editor.Forms;
using ColorDialog = Greenshot.Forms.ColorDialog; using ColorDialog = Greenshot.Editor.Forms.ColorDialog;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// This code was supplied by Hi-Coder as a patch for Greenshot /// This code was supplied by Hi-Coder as a patch for Greenshot
/// Needed some modifications to be stable. /// Needed some modifications to be stable.
/// </summary> /// </summary>
public sealed class Pipette : Label, IMessageFilter, IDisposable public sealed class Pipette : Label, IMessageFilter, IDisposable
{ {
private MovableShowColorForm _movableShowColorForm; private MovableShowColorForm _movableShowColorForm;
private bool _dragging; private bool _dragging;
private Cursor _cursor; private Cursor _cursor;
private readonly Bitmap _image; private readonly Bitmap _image;
private const int VkEsc = 27; private const int VkEsc = 27;
public event EventHandler<PipetteUsedArgs> PipetteUsed; public event EventHandler<PipetteUsedArgs> PipetteUsed;
public Pipette() public Pipette()
{ {
BorderStyle = BorderStyle.FixedSingle; BorderStyle = BorderStyle.FixedSingle;
_dragging = false; _dragging = false;
_image = (Bitmap) new ComponentResourceManager(typeof(ColorDialog)).GetObject("pipette.Image"); _image = (Bitmap) new ComponentResourceManager(typeof(ColorDialog)).GetObject("pipette.Image");
Image = _image; Image = _image;
_cursor = CreateCursor(_image, 1, 14); _cursor = CreateCursor(_image, 1, 14);
_movableShowColorForm = new MovableShowColorForm(); _movableShowColorForm = new MovableShowColorForm();
Application.AddMessageFilter(this); Application.AddMessageFilter(this);
} }
/// <summary> /// <summary>
/// Create a cursor from the supplied bitmap & hotspot coordinates /// Create a cursor from the supplied bitmap & hotspot coordinates
/// </summary> /// </summary>
/// <param name="bitmap">Bitmap to create an icon from</param> /// <param name="bitmap">Bitmap to create an icon from</param>
/// <param name="hotspotX">Hotspot X coordinate</param> /// <param name="hotspotX">Hotspot X coordinate</param>
/// <param name="hotspotY">Hotspot Y coordinate</param> /// <param name="hotspotY">Hotspot Y coordinate</param>
/// <returns>Cursor</returns> /// <returns>Cursor</returns>
private static Cursor CreateCursor(Bitmap bitmap, int hotspotX, int hotspotY) private static Cursor CreateCursor(Bitmap bitmap, int hotspotX, int hotspotY)
{ {
using SafeIconHandle iconHandle = new SafeIconHandle(bitmap.GetHicon()); using SafeIconHandle iconHandle = new SafeIconHandle(bitmap.GetHicon());
User32.GetIconInfo(iconHandle, out var iconInfo); User32.GetIconInfo(iconHandle, out var iconInfo);
iconInfo.xHotspot = hotspotX; iconInfo.xHotspot = hotspotX;
iconInfo.yHotspot = hotspotY; iconInfo.yHotspot = hotspotY;
iconInfo.fIcon = false; iconInfo.fIcon = false;
var icon = User32.CreateIconIndirect(ref iconInfo); var icon = User32.CreateIconIndirect(ref iconInfo);
return new Cursor(icon); return new Cursor(icon);
} }
/// <summary> /// <summary>
/// The bulk of the clean-up code is implemented in Dispose(bool) /// The bulk of the clean-up code is implemented in Dispose(bool)
/// </summary> /// </summary>
public new void Dispose() public new void Dispose()
{ {
Dispose(true); Dispose(true);
} }
/// <summary> /// <summary>
/// This Dispose is called from the Dispose and the Destructor. /// This Dispose is called from the Dispose and the Destructor.
/// </summary> /// </summary>
/// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param> /// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
if (_cursor != null) if (_cursor != null)
{ {
_cursor.Dispose(); _cursor.Dispose();
} }
_movableShowColorForm?.Dispose(); _movableShowColorForm?.Dispose();
} }
_movableShowColorForm = null; _movableShowColorForm = null;
_cursor = null; _cursor = null;
base.Dispose(disposing); base.Dispose(disposing);
} }
/// <summary> /// <summary>
/// Handle the mouse down on the Pipette "label", we take the capture and move the zoomer to the current location /// Handle the mouse down on the Pipette "label", we take the capture and move the zoomer to the current location
/// </summary> /// </summary>
/// <param name="e">MouseEventArgs</param> /// <param name="e">MouseEventArgs</param>
protected override void OnMouseDown(MouseEventArgs e) protected override void OnMouseDown(MouseEventArgs e)
{ {
if (e.Button == MouseButtons.Left) if (e.Button == MouseButtons.Left)
{ {
User32.SetCapture(Handle); User32.SetCapture(Handle);
_movableShowColorForm.MoveTo(PointToScreen(new Point(e.X, e.Y))); _movableShowColorForm.MoveTo(PointToScreen(new Point(e.X, e.Y)));
} }
base.OnMouseDown(e); base.OnMouseDown(e);
} }
/// <summary> /// <summary>
/// Handle the mouse up on the Pipette "label", we release the capture and fire the PipetteUsed event /// Handle the mouse up on the Pipette "label", we release the capture and fire the PipetteUsed event
/// </summary> /// </summary>
/// <param name="e">MouseEventArgs</param> /// <param name="e">MouseEventArgs</param>
protected override void OnMouseUp(MouseEventArgs e) protected override void OnMouseUp(MouseEventArgs e)
{ {
if (e.Button == MouseButtons.Left) if (e.Button == MouseButtons.Left)
{ {
//Release Capture should consume MouseUp when canceled with the escape key //Release Capture should consume MouseUp when canceled with the escape key
User32.ReleaseCapture(); User32.ReleaseCapture();
PipetteUsed?.Invoke(this, new PipetteUsedArgs(_movableShowColorForm.color)); PipetteUsed?.Invoke(this, new PipetteUsedArgs(_movableShowColorForm.color));
} }
base.OnMouseUp(e); base.OnMouseUp(e);
} }
/// <summary> /// <summary>
/// Handle the mouse Move event, we move the ColorUnderCursor to the current location. /// Handle the mouse Move event, we move the ColorUnderCursor to the current location.
/// </summary> /// </summary>
/// <param name="e">MouseEventArgs</param> /// <param name="e">MouseEventArgs</param>
protected override void OnMouseMove(MouseEventArgs e) protected override void OnMouseMove(MouseEventArgs e)
{ {
if (_dragging) if (_dragging)
{ {
//display the form on the right side of the cursor by default; //display the form on the right side of the cursor by default;
Point zp = PointToScreen(new Point(e.X, e.Y)); Point zp = PointToScreen(new Point(e.X, e.Y));
_movableShowColorForm.MoveTo(zp); _movableShowColorForm.MoveTo(zp);
} }
base.OnMouseMove(e); base.OnMouseMove(e);
} }
/// <summary> /// <summary>
/// Handle the MouseCaptureChanged event /// Handle the MouseCaptureChanged event
/// </summary> /// </summary>
/// <param name="e"></param> /// <param name="e"></param>
protected override void OnMouseCaptureChanged(EventArgs e) protected override void OnMouseCaptureChanged(EventArgs e)
{ {
if (Capture) if (Capture)
{ {
_dragging = true; _dragging = true;
Image = null; Image = null;
Cursor c = _cursor; Cursor c = _cursor;
Cursor = c; Cursor = c;
_movableShowColorForm.Visible = true; _movableShowColorForm.Visible = true;
} }
else else
{ {
_dragging = false; _dragging = false;
Image = _image; Image = _image;
Cursor = Cursors.Arrow; Cursor = Cursors.Arrow;
_movableShowColorForm.Visible = false; _movableShowColorForm.Visible = false;
} }
Update(); Update();
base.OnMouseCaptureChanged(e); base.OnMouseCaptureChanged(e);
} }
public bool PreFilterMessage(ref Message m) public bool PreFilterMessage(ref Message m)
{ {
if (_dragging) if (_dragging)
{ {
if (m.Msg == (int) WindowsMessages.WM_CHAR) if (m.Msg == (int) WindowsMessages.WM_CHAR)
{ {
if ((int) m.WParam == VkEsc) if ((int) m.WParam == VkEsc)
{ {
User32.ReleaseCapture(); User32.ReleaseCapture();
} }
} }
} }
return false; return false;
} }
} }
public class PipetteUsedArgs : EventArgs public class PipetteUsedArgs : EventArgs
{ {
public Color Color; public Color Color;
public PipetteUsedArgs(Color c) public PipetteUsedArgs(Color c)
{ {
Color = c; Color = c;
} }
} }
} }

View file

@ -1,97 +1,97 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
using ColorDialog = Greenshot.Forms.ColorDialog; using ColorDialog = Greenshot.Editor.Forms.ColorDialog;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
public class ToolStripColorButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable public class ToolStripColorButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
[Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")] [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
public string LanguageKey { get; set; } public string LanguageKey { get; set; }
private Color _selectedColor = Color.Transparent; private Color _selectedColor = Color.Transparent;
public ToolStripColorButton() public ToolStripColorButton()
{ {
Click += ColorButtonClick; Click += ColorButtonClick;
} }
public Color SelectedColor public Color SelectedColor
{ {
get { return _selectedColor; } get { return _selectedColor; }
set set
{ {
_selectedColor = value; _selectedColor = value;
Brush brush; Brush brush;
if (value != Color.Transparent) if (value != Color.Transparent)
{ {
brush = new SolidBrush(value); brush = new SolidBrush(value);
} }
else else
{ {
brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray); brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray);
} }
if (Image != null) if (Image != null)
{ {
using Graphics graphics = Graphics.FromImage(Image); using Graphics graphics = Graphics.FromImage(Image);
graphics.FillRectangle(brush, new Rectangle(0, 13, 16, 3)); graphics.FillRectangle(brush, new Rectangle(0, 13, 16, 3));
} }
// cleanup GDI Object // cleanup GDI Object
brush.Dispose(); brush.Dispose();
Invalidate(); Invalidate();
} }
} }
private void ColorButtonClick(object sender, EventArgs e) private void ColorButtonClick(object sender, EventArgs e)
{ {
var colorDialog = new ColorDialog var colorDialog = new ColorDialog
{ {
Color = SelectedColor Color = SelectedColor
}; };
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel) if (colorDialog.DialogResult == DialogResult.Cancel)
{ {
return; return;
} }
if (colorDialog.Color.Equals(SelectedColor)) if (colorDialog.Color.Equals(SelectedColor))
{ {
return; return;
} }
SelectedColor = colorDialog.Color; SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
} }
} }
} }

View file

@ -1,66 +1,66 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
/// <summary> /// <summary>
/// This is an extension of the default ToolStrip and allows us to click it even when the form doesn't have focus. /// This is an extension of the default ToolStrip and allows us to click it even when the form doesn't have focus.
/// See: https://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx /// See: https://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx
/// </summary> /// </summary>
internal class ToolStripEx : ToolStrip internal class ToolStripEx : ToolStrip
{ {
private const int WM_MOUSEACTIVATE = 0x21; private const int WM_MOUSEACTIVATE = 0x21;
private enum NativeConstants : uint private enum NativeConstants : uint
{ {
MA_ACTIVATE = 1, MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2, MA_ACTIVATEANDEAT = 2,
} }
private bool _clickThrough; private bool _clickThrough;
/// <summary> /// <summary>
/// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus. /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Default value is false, which is the same behavior provided by the base ToolStrip class. /// Default value is false, which is the same behavior provided by the base ToolStrip class.
/// </remarks> /// </remarks>
public bool ClickThrough public bool ClickThrough
{ {
get { return _clickThrough; } get { return _clickThrough; }
set { _clickThrough = value; } set { _clickThrough = value; }
} }
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
base.WndProc(ref m); base.WndProc(ref m);
if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr) NativeConstants.MA_ACTIVATEANDEAT) if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr) NativeConstants.MA_ACTIVATEANDEAT)
{ {
m.Result = (IntPtr) NativeConstants.MA_ACTIVATE; m.Result = (IntPtr) NativeConstants.MA_ACTIVATE;
} }
} }
} }
} }

View file

@ -1,88 +1,88 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.Design; using System.Windows.Forms.Design;
namespace Greenshot.Controls namespace Greenshot.Editor.Controls
{ {
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)] [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripNumericUpDown : ToolStripControlHost, INotifyPropertyChanged public class ToolStripNumericUpDown : ToolStripControlHost, INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public ToolStripNumericUpDown() : base(new NumericUpDown()) public ToolStripNumericUpDown() : base(new NumericUpDown())
{ {
} }
public NumericUpDown NumericUpDown => Control as NumericUpDown; public NumericUpDown NumericUpDown => Control as NumericUpDown;
public decimal Value public decimal Value
{ {
get { return NumericUpDown.Value; } get { return NumericUpDown.Value; }
set { NumericUpDown.Value = value; } set { NumericUpDown.Value = value; }
} }
public decimal Minimum public decimal Minimum
{ {
get { return NumericUpDown.Minimum; } get { return NumericUpDown.Minimum; }
set { NumericUpDown.Minimum = value; } set { NumericUpDown.Minimum = value; }
} }
public decimal Maximum public decimal Maximum
{ {
get { return NumericUpDown.Maximum; } get { return NumericUpDown.Maximum; }
set { NumericUpDown.Maximum = value; } set { NumericUpDown.Maximum = value; }
} }
public decimal Increment public decimal Increment
{ {
get { return NumericUpDown.Increment; } get { return NumericUpDown.Increment; }
set { NumericUpDown.Increment = value; } set { NumericUpDown.Increment = value; }
} }
public int DecimalPlaces public int DecimalPlaces
{ {
get { return NumericUpDown.DecimalPlaces; } get { return NumericUpDown.DecimalPlaces; }
set { NumericUpDown.DecimalPlaces = value; } set { NumericUpDown.DecimalPlaces = value; }
} }
protected override void OnSubscribeControlEvents(Control control) protected override void OnSubscribeControlEvents(Control control)
{ {
base.OnSubscribeControlEvents(control); base.OnSubscribeControlEvents(control);
NumericUpDown.ValueChanged += _valueChanged; NumericUpDown.ValueChanged += _valueChanged;
} }
protected override void OnUnsubscribeControlEvents(Control control) protected override void OnUnsubscribeControlEvents(Control control)
{ {
base.OnUnsubscribeControlEvents(control); base.OnUnsubscribeControlEvents(control);
NumericUpDown.ValueChanged -= _valueChanged; NumericUpDown.ValueChanged -= _valueChanged;
} }
private void _valueChanged(object sender, EventArgs e) private void _valueChanged(object sender, EventArgs e)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
} }
} }
} }

View file

@ -1,154 +1,154 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Forms; using Greenshot.Base.Interfaces.Forms;
using Greenshot.Configuration; using Greenshot.Editor.Configuration;
using Greenshot.Forms; using Greenshot.Editor.Forms;
using log4net; using log4net;
namespace Greenshot.Destinations namespace Greenshot.Editor.Destinations
{ {
/// <summary> /// <summary>
/// Description of EditorDestination. /// Description of EditorDestination.
/// </summary> /// </summary>
public class EditorDestination : AbstractDestination public class EditorDestination : AbstractDestination
{ {
private static readonly ILog LOG = LogManager.GetLogger(typeof(EditorDestination)); private static readonly ILog LOG = LogManager.GetLogger(typeof(EditorDestination));
private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
public const string DESIGNATION = "Editor"; public const string DESIGNATION = "Editor";
private readonly IImageEditor editor; private readonly IImageEditor editor;
private static readonly Image greenshotIcon = GreenshotResources.GetGreenshotIcon().ToBitmap(); private static readonly Image greenshotIcon = GreenshotResources.GetGreenshotIcon().ToBitmap();
public EditorDestination() public EditorDestination()
{ {
// Do not remove, is needed for the framework // Do not remove, is needed for the framework
} }
public EditorDestination(IImageEditor editor) public EditorDestination(IImageEditor editor)
{ {
this.editor = editor; this.editor = editor;
} }
public override string Designation => DESIGNATION; public override string Designation => DESIGNATION;
public override string Description public override string Description
{ {
get get
{ {
if (editor == null) if (editor == null)
{ {
return Language.GetString(LangKey.settings_destination_editor); return Language.GetString(LangKey.settings_destination_editor);
} }
return Language.GetString(LangKey.settings_destination_editor) + " - " + editor.CaptureDetails.Title; return Language.GetString(LangKey.settings_destination_editor) + " - " + editor.CaptureDetails.Title;
} }
} }
public override int Priority => 1; public override int Priority => 1;
public override bool IsDynamic => true; public override bool IsDynamic => true;
public override Image DisplayIcon => greenshotIcon; public override Image DisplayIcon => greenshotIcon;
public override IEnumerable<IDestination> DynamicDestinations() public override IEnumerable<IDestination> DynamicDestinations()
{ {
foreach (IImageEditor someEditor in ImageEditorForm.Editors) foreach (IImageEditor someEditor in ImageEditorForm.Editors)
{ {
yield return new EditorDestination(someEditor); yield return new EditorDestination(someEditor);
} }
} }
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
{ {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
// Make sure we collect the garbage before opening the screenshot // Make sure we collect the garbage before opening the screenshot
GC.Collect(); GC.Collect();
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
bool modified = surface.Modified; bool modified = surface.Modified;
if (editor == null) if (editor == null)
{ {
if (editorConfiguration.ReuseEditor) if (editorConfiguration.ReuseEditor)
{ {
foreach (IImageEditor openedEditor in ImageEditorForm.Editors) foreach (IImageEditor openedEditor in ImageEditorForm.Editors)
{ {
if (openedEditor.Surface.Modified) continue; if (openedEditor.Surface.Modified) continue;
openedEditor.Surface = surface; openedEditor.Surface = surface;
exportInformation.ExportMade = true; exportInformation.ExportMade = true;
break; break;
} }
} }
if (!exportInformation.ExportMade) if (!exportInformation.ExportMade)
{ {
try try
{ {
ImageEditorForm editorForm = new ImageEditorForm(surface, !surface.Modified); // Output made?? ImageEditorForm editorForm = new ImageEditorForm(surface, !surface.Modified); // Output made??
if (!string.IsNullOrEmpty(captureDetails.Filename)) if (!string.IsNullOrEmpty(captureDetails.Filename))
{ {
editorForm.SetImagePath(captureDetails.Filename); editorForm.SetImagePath(captureDetails.Filename);
} }
editorForm.Show(); editorForm.Show();
editorForm.Activate(); editorForm.Activate();
LOG.Debug("Finished opening Editor"); LOG.Debug("Finished opening Editor");
exportInformation.ExportMade = true; exportInformation.ExportMade = true;
} }
catch (Exception e) catch (Exception e)
{ {
LOG.Error(e); LOG.Error(e);
exportInformation.ErrorMessage = e.Message; exportInformation.ErrorMessage = e.Message;
} }
} }
} }
else else
{ {
try try
{ {
using (Image image = surface.GetImageForExport()) using (Image image = surface.GetImageForExport())
{ {
editor.Surface.AddImageContainer(image, 10, 10); editor.Surface.AddImageContainer(image, 10, 10);
} }
exportInformation.ExportMade = true; exportInformation.ExportMade = true;
} }
catch (Exception e) catch (Exception e)
{ {
LOG.Error(e); LOG.Error(e);
exportInformation.ErrorMessage = e.Message; exportInformation.ErrorMessage = e.Message;
} }
} }
ProcessExport(exportInformation, surface); ProcessExport(exportInformation, surface);
// Workaround for the modified flag when using the editor. // Workaround for the modified flag when using the editor.
surface.Modified = modified; surface.Modified = modified;
return exportInformation; return exportInformation;
} }
} }
} }

View file

@ -1,156 +1,156 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing.Adorners; using Greenshot.Base.Interfaces.Drawing.Adorners;
namespace Greenshot.Drawing.Adorners namespace Greenshot.Editor.Drawing.Adorners
{ {
public class AbstractAdorner : IAdorner public class AbstractAdorner : IAdorner
{ {
public virtual EditStatus EditStatus { get; protected set; } = EditStatus.IDLE; public virtual EditStatus EditStatus { get; protected set; } = EditStatus.IDLE;
private static readonly Size DefaultSize = new Size(6, 6); private static readonly Size DefaultSize = new Size(6, 6);
protected Size _size; protected Size _size;
public AbstractAdorner(IDrawableContainer owner) public AbstractAdorner(IDrawableContainer owner)
{ {
_size = DpiHelper.ScaleWithDpi(DefaultSize, 0); _size = DpiHelper.ScaleWithDpi(DefaultSize, 0);
Owner = owner; Owner = owner;
} }
/// <summary> /// <summary>
/// Returns the cursor for when the mouse is over the adorner /// Returns the cursor for when the mouse is over the adorner
/// </summary> /// </summary>
public virtual Cursor Cursor public virtual Cursor Cursor
{ {
get { return Cursors.SizeAll; } get { return Cursors.SizeAll; }
} }
public virtual IDrawableContainer Owner { get; set; } public virtual IDrawableContainer Owner { get; set; }
/// <summary> /// <summary>
/// Test if the point is inside the adorner /// Test if the point is inside the adorner
/// </summary> /// </summary>
/// <param name="point"></param> /// <param name="point"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool HitTest(Point point) public virtual bool HitTest(Point point)
{ {
Rectangle hitBounds = Bounds; Rectangle hitBounds = Bounds;
hitBounds.Inflate(3, 3); hitBounds.Inflate(3, 3);
return hitBounds.Contains(point); return hitBounds.Contains(point);
} }
/// <summary> /// <summary>
/// Handle the mouse down /// Handle the mouse down
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public virtual void MouseDown(object sender, MouseEventArgs mouseEventArgs) public virtual void MouseDown(object sender, MouseEventArgs mouseEventArgs)
{ {
} }
/// <summary> /// <summary>
/// Handle the mouse move /// Handle the mouse move
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public virtual void MouseMove(object sender, MouseEventArgs mouseEventArgs) public virtual void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{ {
} }
/// <summary> /// <summary>
/// Handle the mouse up /// Handle the mouse up
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public virtual void MouseUp(object sender, MouseEventArgs mouseEventArgs) public virtual void MouseUp(object sender, MouseEventArgs mouseEventArgs)
{ {
EditStatus = EditStatus.IDLE; EditStatus = EditStatus.IDLE;
} }
/// <summary> /// <summary>
/// Return the location of the adorner /// Return the location of the adorner
/// </summary> /// </summary>
public virtual Point Location { get; set; } public virtual Point Location { get; set; }
/// <summary> /// <summary>
/// Return the bounds of the Adorner /// Return the bounds of the Adorner
/// </summary> /// </summary>
public virtual Rectangle Bounds public virtual Rectangle Bounds
{ {
get get
{ {
Point location = Location; Point location = Location;
return new Rectangle(location.X - (_size.Width / 2), location.Y - (_size.Height / 2), _size.Width, _size.Height); return new Rectangle(location.X - (_size.Width / 2), location.Y - (_size.Height / 2), _size.Width, _size.Height);
} }
} }
/// <summary> /// <summary>
/// Return the bounds of the Adorner as displayed on the parent Surface /// Return the bounds of the Adorner as displayed on the parent Surface
/// </summary> /// </summary>
protected virtual Rectangle BoundsOnSurface protected virtual Rectangle BoundsOnSurface
{ {
get get
{ {
Point displayLocation = Owner.Parent.ToSurfaceCoordinates(Location); Point displayLocation = Owner.Parent.ToSurfaceCoordinates(Location);
return new Rectangle(displayLocation.X - _size.Width / 2, displayLocation.Y - _size.Height / 2, _size.Width, _size.Height); return new Rectangle(displayLocation.X - _size.Width / 2, displayLocation.Y - _size.Height / 2, _size.Width, _size.Height);
} }
} }
/// <summary> /// <summary>
/// The adorner is active if the edit status is not idle or undrawn /// The adorner is active if the edit status is not idle or undrawn
/// </summary> /// </summary>
public virtual bool IsActive public virtual bool IsActive
{ {
get { return EditStatus != EditStatus.IDLE && EditStatus != EditStatus.UNDRAWN; } get { return EditStatus != EditStatus.IDLE && EditStatus != EditStatus.UNDRAWN; }
} }
/// <summary> /// <summary>
/// Adjust UI elements to the supplied DPI settings /// Adjust UI elements to the supplied DPI settings
/// </summary> /// </summary>
/// <param name="dpi">uint</param> /// <param name="dpi">uint</param>
public void AdjustToDpi(uint dpi) public void AdjustToDpi(uint dpi)
{ {
_size = DpiHelper.ScaleWithDpi(DefaultSize, dpi); _size = DpiHelper.ScaleWithDpi(DefaultSize, dpi);
} }
/// <summary> /// <summary>
/// Draw the adorner /// Draw the adorner
/// </summary> /// </summary>
/// <param name="paintEventArgs">PaintEventArgs</param> /// <param name="paintEventArgs">PaintEventArgs</param>
public virtual void Paint(PaintEventArgs paintEventArgs) public virtual void Paint(PaintEventArgs paintEventArgs)
{ {
} }
/// <summary> /// <summary>
/// We ignore the Transform, as the coordinates are directly bound to those of the owner /// We ignore the Transform, as the coordinates are directly bound to those of the owner
/// </summary> /// </summary>
/// <param name="matrix"></param> /// <param name="matrix"></param>
public virtual void Transform(Matrix matrix) public virtual void Transform(Matrix matrix)
{ {
} }
} }
} }

View file

@ -1,166 +1,166 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Helpers; using System.Drawing;
using System.Drawing; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using System.Windows.Forms;
using System.Windows.Forms; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing.Adorners namespace Greenshot.Editor.Drawing.Adorners
{ {
/// <summary> /// <summary>
/// This is the adorner for the line based containers /// This is the adorner for the line based containers
/// </summary> /// </summary>
public class MoveAdorner : AbstractAdorner public class MoveAdorner : AbstractAdorner
{ {
private Rectangle _boundsBeforeResize = Rectangle.Empty; private Rectangle _boundsBeforeResize = Rectangle.Empty;
private RectangleF _boundsAfterResize = RectangleF.Empty; private RectangleF _boundsAfterResize = RectangleF.Empty;
public Positions Position { get; private set; } public Positions Position { get; private set; }
public MoveAdorner(IDrawableContainer owner, Positions position) : base(owner) public MoveAdorner(IDrawableContainer owner, Positions position) : base(owner)
{ {
Position = position; Position = position;
} }
/// <summary> /// <summary>
/// Returns the cursor for when the mouse is over the adorner /// Returns the cursor for when the mouse is over the adorner
/// </summary> /// </summary>
public override Cursor Cursor => Cursors.SizeAll; public override Cursor Cursor => Cursors.SizeAll;
/// <summary> /// <summary>
/// Handle the mouse down /// Handle the mouse down
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs) public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
{ {
EditStatus = EditStatus.RESIZING; EditStatus = EditStatus.RESIZING;
_boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height); _boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height);
_boundsAfterResize = _boundsBeforeResize; _boundsAfterResize = _boundsBeforeResize;
} }
/// <summary> /// <summary>
/// Handle the mouse move /// Handle the mouse move
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs) public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{ {
if (EditStatus != EditStatus.RESIZING) if (EditStatus != EditStatus.RESIZING)
{ {
return; return;
} }
Owner.Invalidate(); Owner.Invalidate();
Owner.MakeBoundsChangeUndoable(false); Owner.MakeBoundsChangeUndoable(false);
// reset "workbench" rectangle to current bounds // reset "workbench" rectangle to current bounds
_boundsAfterResize.X = _boundsBeforeResize.X; _boundsAfterResize.X = _boundsBeforeResize.X;
_boundsAfterResize.Y = _boundsBeforeResize.Y; _boundsAfterResize.Y = _boundsBeforeResize.Y;
_boundsAfterResize.Width = _boundsBeforeResize.Width; _boundsAfterResize.Width = _boundsBeforeResize.Width;
_boundsAfterResize.Height = _boundsBeforeResize.Height; _boundsAfterResize.Height = _boundsBeforeResize.Height;
// calculate scaled rectangle // calculate scaled rectangle
ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions());
// apply scaled bounds to this DrawableContainer // apply scaled bounds to this DrawableContainer
Owner.ApplyBounds(_boundsAfterResize); Owner.ApplyBounds(_boundsAfterResize);
Owner.Invalidate(); Owner.Invalidate();
} }
/// <summary> /// <summary>
/// Return the location of the adorner /// Return the location of the adorner
/// </summary> /// </summary>
public override Point Location public override Point Location
{ {
get get
{ {
int x = 0, y = 0; int x = 0, y = 0;
switch (Position) switch (Position)
{ {
case Positions.TopLeft: case Positions.TopLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomLeft: case Positions.BottomLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.MiddleLeft: case Positions.MiddleLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top + (Owner.Height / 2); y = Owner.Top + (Owner.Height / 2);
break; break;
case Positions.TopCenter: case Positions.TopCenter:
x = Owner.Left + (Owner.Width / 2); x = Owner.Left + (Owner.Width / 2);
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomCenter: case Positions.BottomCenter:
x = Owner.Left + (Owner.Width / 2); x = Owner.Left + (Owner.Width / 2);
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.TopRight: case Positions.TopRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomRight: case Positions.BottomRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.MiddleRight: case Positions.MiddleRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top + (Owner.Height / 2); y = Owner.Top + (Owner.Height / 2);
break; break;
} }
return new Point(x, y); return new Point(x, y);
} }
} }
/// <summary> /// <summary>
/// Draw the adorner /// Draw the adorner
/// </summary> /// </summary>
/// <param name="paintEventArgs">PaintEventArgs</param> /// <param name="paintEventArgs">PaintEventArgs</param>
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
var bounds = BoundsOnSurface; var bounds = BoundsOnSurface;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();
targetGraphics.CompositingMode = CompositingMode.SourceCopy; targetGraphics.CompositingMode = CompositingMode.SourceCopy;
try try
{ {
targetGraphics.FillRectangle(Brushes.Black, bounds); targetGraphics.FillRectangle(Brushes.Black, bounds);
targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds); targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds);
} }
catch catch
{ {
// Ignore, BUG-2065 // Ignore, BUG-2065
} }
targetGraphics.Restore(state); targetGraphics.Restore(state);
} }
} }
} }

View file

@ -1,186 +1,186 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Helpers; using System.Drawing;
using System.Drawing; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using System.Windows.Forms;
using System.Windows.Forms; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing.Adorners namespace Greenshot.Editor.Drawing.Adorners
{ {
/// <summary> /// <summary>
/// This is the default "legacy" gripper adorner, not the one used for the tail in the speech-bubble /// This is the default "legacy" gripper adorner, not the one used for the tail in the speech-bubble
/// </summary> /// </summary>
public class ResizeAdorner : AbstractAdorner public class ResizeAdorner : AbstractAdorner
{ {
private Rectangle _boundsBeforeResize = Rectangle.Empty; private Rectangle _boundsBeforeResize = Rectangle.Empty;
private RectangleF _boundsAfterResize = RectangleF.Empty; private RectangleF _boundsAfterResize = RectangleF.Empty;
public Positions Position { get; private set; } public Positions Position { get; private set; }
public ResizeAdorner(IDrawableContainer owner, Positions position) : base(owner) public ResizeAdorner(IDrawableContainer owner, Positions position) : base(owner)
{ {
Position = position; Position = position;
} }
/// <summary> /// <summary>
/// Returns the cursor for when the mouse is over the adorner /// Returns the cursor for when the mouse is over the adorner
/// </summary> /// </summary>
public override Cursor Cursor public override Cursor Cursor
{ {
get get
{ {
bool isNotSwitched = Owner.Width >= 0; bool isNotSwitched = Owner.Width >= 0;
if (Owner.Height < 0) if (Owner.Height < 0)
{ {
isNotSwitched = !isNotSwitched; isNotSwitched = !isNotSwitched;
} }
switch (Position) switch (Position)
{ {
case Positions.TopLeft: case Positions.TopLeft:
case Positions.BottomRight: case Positions.BottomRight:
return isNotSwitched ? Cursors.SizeNWSE : Cursors.SizeNESW; return isNotSwitched ? Cursors.SizeNWSE : Cursors.SizeNESW;
case Positions.TopRight: case Positions.TopRight:
case Positions.BottomLeft: case Positions.BottomLeft:
return isNotSwitched ? Cursors.SizeNESW : Cursors.SizeNWSE; return isNotSwitched ? Cursors.SizeNESW : Cursors.SizeNWSE;
case Positions.MiddleLeft: case Positions.MiddleLeft:
case Positions.MiddleRight: case Positions.MiddleRight:
return Cursors.SizeWE; return Cursors.SizeWE;
case Positions.TopCenter: case Positions.TopCenter:
case Positions.BottomCenter: case Positions.BottomCenter:
return Cursors.SizeNS; return Cursors.SizeNS;
default: default:
return Cursors.SizeAll; return Cursors.SizeAll;
} }
} }
} }
/// <summary> /// <summary>
/// Handle the mouse down /// Handle the mouse down
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs) public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
{ {
EditStatus = EditStatus.RESIZING; EditStatus = EditStatus.RESIZING;
_boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height); _boundsBeforeResize = new Rectangle(Owner.Left, Owner.Top, Owner.Width, Owner.Height);
_boundsAfterResize = _boundsBeforeResize; _boundsAfterResize = _boundsBeforeResize;
} }
/// <summary> /// <summary>
/// Handle the mouse move /// Handle the mouse move
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="mouseEventArgs"></param> /// <param name="mouseEventArgs"></param>
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs) public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{ {
if (EditStatus != EditStatus.RESIZING) if (EditStatus != EditStatus.RESIZING)
{ {
return; return;
} }
Owner.Invalidate(); Owner.Invalidate();
Owner.MakeBoundsChangeUndoable(false); Owner.MakeBoundsChangeUndoable(false);
// reset "workbench" rectangle to current bounds // reset "workbench" rectangle to current bounds
_boundsAfterResize.X = _boundsBeforeResize.X; _boundsAfterResize.X = _boundsBeforeResize.X;
_boundsAfterResize.Y = _boundsBeforeResize.Y; _boundsAfterResize.Y = _boundsBeforeResize.Y;
_boundsAfterResize.Width = _boundsBeforeResize.Width; _boundsAfterResize.Width = _boundsBeforeResize.Width;
_boundsAfterResize.Height = _boundsBeforeResize.Height; _boundsAfterResize.Height = _boundsBeforeResize.Height;
// calculate scaled rectangle // calculate scaled rectangle
ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions()); ScaleHelper.Scale(ref _boundsAfterResize, Position, new PointF(mouseEventArgs.X, mouseEventArgs.Y), ScaleHelper.GetScaleOptions());
// apply scaled bounds to this DrawableContainer // apply scaled bounds to this DrawableContainer
Owner.ApplyBounds(_boundsAfterResize); Owner.ApplyBounds(_boundsAfterResize);
Owner.Invalidate(); Owner.Invalidate();
} }
/// <summary> /// <summary>
/// Return the location of the adorner /// Return the location of the adorner
/// </summary> /// </summary>
public override Point Location public override Point Location
{ {
get get
{ {
int x = 0, y = 0; int x = 0, y = 0;
switch (Position) switch (Position)
{ {
case Positions.TopLeft: case Positions.TopLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomLeft: case Positions.BottomLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.MiddleLeft: case Positions.MiddleLeft:
x = Owner.Left; x = Owner.Left;
y = Owner.Top + (Owner.Height / 2); y = Owner.Top + (Owner.Height / 2);
break; break;
case Positions.TopCenter: case Positions.TopCenter:
x = Owner.Left + (Owner.Width / 2); x = Owner.Left + (Owner.Width / 2);
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomCenter: case Positions.BottomCenter:
x = Owner.Left + (Owner.Width / 2); x = Owner.Left + (Owner.Width / 2);
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.TopRight: case Positions.TopRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top; y = Owner.Top;
break; break;
case Positions.BottomRight: case Positions.BottomRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top + Owner.Height; y = Owner.Top + Owner.Height;
break; break;
case Positions.MiddleRight: case Positions.MiddleRight:
x = Owner.Left + Owner.Width; x = Owner.Left + Owner.Width;
y = Owner.Top + (Owner.Height / 2); y = Owner.Top + (Owner.Height / 2);
break; break;
} }
return new Point(x, y); return new Point(x, y);
} }
} }
/// <summary> /// <summary>
/// Draw the adorner /// Draw the adorner
/// </summary> /// </summary>
/// <param name="paintEventArgs">PaintEventArgs</param> /// <param name="paintEventArgs">PaintEventArgs</param>
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
var bounds = BoundsOnSurface; var bounds = BoundsOnSurface;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();
targetGraphics.CompositingMode = CompositingMode.SourceCopy; targetGraphics.CompositingMode = CompositingMode.SourceCopy;
targetGraphics.FillRectangle(Brushes.Black, bounds); targetGraphics.FillRectangle(Brushes.Black, bounds);
targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds); targetGraphics.DrawRectangle(new Pen(Brushes.White), bounds);
targetGraphics.Restore(state); targetGraphics.Restore(state);
} }
} }
} }

View file

@ -24,7 +24,7 @@ using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Adorners namespace Greenshot.Editor.Drawing.Adorners
{ {
/// <summary> /// <summary>
/// This implements the special "gripper" for the Speech-Bubble tail /// This implements the special "gripper" for the Speech-Bubble tail

View file

@ -1,163 +1,163 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of LineContainer. /// Description of LineContainer.
/// </summary> /// </summary>
[Serializable()] [Serializable()]
public class ArrowContainer : LineContainer public class ArrowContainer : LineContainer
{ {
public enum ArrowHeadCombination public enum ArrowHeadCombination
{ {
NONE, NONE,
START_POINT, START_POINT,
END_POINT, END_POINT,
BOTH BOTH
}; };
private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6); private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6);
public ArrowContainer(Surface parent) : base(parent) public ArrowContainer(Surface parent) : base(parent)
{ {
} }
/// <summary> /// <summary>
/// Do not use the base, just override so we have our own defaults /// Do not use the base, just override so we have our own defaults
/// </summary> /// </summary>
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 2); AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.ARROWHEADS, 2); AddField(GetType(), FieldType.ARROWHEADS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent); AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, true); AddField(GetType(), FieldType.SHADOW, true);
AddField(GetType(), FieldType.ARROWHEADS, ArrowHeadCombination.END_POINT); AddField(GetType(), FieldType.ARROWHEADS, ArrowHeadCombination.END_POINT);
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
if (lineThickness > 0) if (lineThickness > 0)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS); ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS);
if (lineThickness > 0) if (lineThickness > 0)
{ {
if (shadow) if (shadow)
{ {
//draw shadow first //draw shadow first
int basealpha = 100; int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
int steps = 5; int steps = 5;
int currentStep = 1; int currentStep = 1;
while (currentStep <= steps) while (currentStep <= steps)
{ {
using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness); using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
SetArrowHeads(heads, shadowCapPen); SetArrowHeads(heads, shadowCapPen);
graphics.DrawLine(shadowCapPen, graphics.DrawLine(shadowCapPen,
Left + currentStep, Left + currentStep,
Top + currentStep, Top + currentStep,
Left + currentStep + Width, Left + currentStep + Width,
Top + currentStep + Height); Top + currentStep + Height);
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
SetArrowHeads(heads, pen); SetArrowHeads(heads, pen);
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height); graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
} }
} }
} }
private void SetArrowHeads(ArrowHeadCombination heads, Pen pen) private void SetArrowHeads(ArrowHeadCombination heads, Pen pen)
{ {
if (heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.START_POINT) if (heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.START_POINT)
{ {
pen.CustomStartCap = ARROW_CAP; pen.CustomStartCap = ARROW_CAP;
} }
if (heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.END_POINT) if (heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.END_POINT)
{ {
pen.CustomEndCap = ARROW_CAP; pen.CustomEndCap = ARROW_CAP;
} }
} }
public override Rectangle DrawingBounds public override Rectangle DrawingBounds
{ {
get get
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(Color.White) using Pen pen = new Pen(Color.White)
{ {
Width = lineThickness Width = lineThickness
}; };
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS), pen); SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS), pen);
using GraphicsPath path = new GraphicsPath(); using GraphicsPath path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height); path.AddLine(Left, Top, Left + Width, Top + Height);
using Matrix matrix = new Matrix(); using Matrix matrix = new Matrix();
Rectangle drawingBounds = Rectangle.Round(path.GetBounds(matrix, pen)); Rectangle drawingBounds = Rectangle.Round(path.GetBounds(matrix, pen));
drawingBounds.Inflate(2, 2); drawingBounds.Inflate(2, 2);
return drawingBounds; return drawingBounds;
} }
return Rectangle.Empty; return Rectangle.Empty;
} }
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10; int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(Color.White) using Pen pen = new Pen(Color.White)
{ {
Width = lineThickness Width = lineThickness
}; };
SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS), pen); SetArrowHeads((ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS), pen);
using GraphicsPath path = new GraphicsPath(); using GraphicsPath path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height); path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen); return path.IsOutlineVisible(x, y, pen);
} }
return false; return false;
} }
} }
} }

View file

@ -1,108 +1,108 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Helpers; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of CropContainer. /// Description of CropContainer.
/// </summary> /// </summary>
public class CropContainer : DrawableContainer public class CropContainer : DrawableContainer
{ {
public CropContainer(Surface parent) : base(parent) public CropContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.FLAGS, FieldFlag.CONFIRMABLE); AddField(GetType(), FieldType.FLAGS, FieldFlag.CONFIRMABLE);
} }
public override void Invalidate() public override void Invalidate()
{ {
_parent?.Invalidate(); _parent?.Invalidate();
} }
/// <summary> /// <summary>
/// We need to override the DrawingBound, return a rectangle in the size of the image, to make sure this element is always draw /// We need to override the DrawingBound, return a rectangle in the size of the image, to make sure this element is always draw
/// (we create a transparent brown over the complete picture) /// (we create a transparent brown over the complete picture)
/// </summary> /// </summary>
public override Rectangle DrawingBounds public override Rectangle DrawingBounds
{ {
get get
{ {
if (_parent?.Image is { } image) if (_parent?.Image is { } image)
{ {
return new Rectangle(0, 0, image.Width, image.Height); return new Rectangle(0, 0, image.Width, image.Height);
} }
return Rectangle.Empty; return Rectangle.Empty;
} }
} }
public override void Draw(Graphics g, RenderMode rm) public override void Draw(Graphics g, RenderMode rm)
{ {
if (_parent == null) if (_parent == null)
{ {
return; return;
} }
using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100)); using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100));
Rectangle cropRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle cropRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
Rectangle selectionRect = new Rectangle(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1); Rectangle selectionRect = new Rectangle(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1);
Size imageSize = _parent.Image.Size; Size imageSize = _parent.Image.Size;
DrawSelectionBorder(g, selectionRect); DrawSelectionBorder(g, selectionRect);
// top // top
g.FillRectangle(cropBrush, new Rectangle(0, 0, imageSize.Width, cropRectangle.Top)); g.FillRectangle(cropBrush, new Rectangle(0, 0, imageSize.Width, cropRectangle.Top));
// left // left
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height)); g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height));
// right // right
g.FillRectangle(cropBrush, g.FillRectangle(cropBrush,
new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, imageSize.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height)); new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, imageSize.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
// bottom // bottom
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, imageSize.Width, imageSize.Height - (cropRectangle.Top + cropRectangle.Height))); g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, imageSize.Width, imageSize.Height - (cropRectangle.Top + cropRectangle.Height)));
} }
/// <summary> /// <summary>
/// No context menu for the CropContainer /// No context menu for the CropContainer
/// </summary> /// </summary>
public override bool HasContextMenu => false; public override bool HasContextMenu => false;
} }
} }

View file

@ -1,128 +1,128 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.IO; using System.Drawing.Drawing2D;
using System.Windows.Forms; using System.IO;
using System.Drawing.Drawing2D; using System.Runtime.Serialization;
using log4net; using System.Windows.Forms;
using System.Runtime.Serialization; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using log4net;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of CursorContainer. /// Description of CursorContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class CursorContainer : DrawableContainer, ICursorContainer public class CursorContainer : DrawableContainer, ICursorContainer
{ {
private static readonly ILog LOG = LogManager.GetLogger(typeof(CursorContainer)); private static readonly ILog LOG = LogManager.GetLogger(typeof(CursorContainer));
protected Cursor cursor; protected Cursor cursor;
public CursorContainer(Surface parent) : base(parent) public CursorContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
public CursorContainer(Surface parent, string filename) : this(parent) public CursorContainer(Surface parent, string filename) : this(parent)
{ {
Load(filename); Load(filename);
} }
public Cursor Cursor public Cursor Cursor
{ {
set set
{ {
if (cursor != null) if (cursor != null)
{ {
cursor.Dispose(); cursor.Dispose();
} }
// Clone cursor (is this correct??) // Clone cursor (is this correct??)
cursor = new Cursor(value.CopyHandle()); cursor = new Cursor(value.CopyHandle());
Width = value.Size.Width; Width = value.Size.Width;
Height = value.Size.Height; Height = value.Size.Height;
} }
get { return cursor; } get { return cursor; }
} }
/// <summary> /// <summary>
/// This Dispose is called from the Dispose and the Destructor. /// This Dispose is called from the Dispose and the Destructor.
/// When disposing==true all non-managed resources should be freed too! /// When disposing==true all non-managed resources should be freed too!
/// </summary> /// </summary>
/// <param name="disposing"></param> /// <param name="disposing"></param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
if (cursor != null) if (cursor != null)
{ {
cursor.Dispose(); cursor.Dispose();
} }
} }
cursor = null; cursor = null;
base.Dispose(disposing); base.Dispose(disposing);
} }
public void Load(string filename) public void Load(string filename)
{ {
if (!File.Exists(filename)) if (!File.Exists(filename))
{ {
return; return;
} }
using Cursor fileCursor = new Cursor(filename); using Cursor fileCursor = new Cursor(filename);
Cursor = fileCursor; Cursor = fileCursor;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width); LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
if (cursor == null) if (cursor == null)
{ {
return; return;
} }
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor; graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.CompositingQuality = CompositingQuality.Default; graphics.CompositingQuality = CompositingQuality.Default;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
cursor.DrawStretched(graphics, Bounds); cursor.DrawStretched(graphics, Bounds);
} }
public override Size DefaultSize => cursor?.Size ?? new Size(16, 16); public override Size DefaultSize => cursor?.Size ?? new Size(16, 16);
} }
} }

View file

@ -1,163 +1,163 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Helpers; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of EllipseContainer. /// Description of EllipseContainer.
/// </summary> /// </summary>
[Serializable()] [Serializable()]
public class EllipseContainer : DrawableContainer public class EllipseContainer : DrawableContainer
{ {
public EllipseContainer(Surface parent) : base(parent) public EllipseContainer(Surface parent) : base(parent)
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 2); AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent); AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, true); AddField(GetType(), FieldType.SHADOW, true);
} }
public override void Draw(Graphics graphics, RenderMode renderMode) public override void Draw(Graphics graphics, RenderMode renderMode)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
DrawEllipse(rect, graphics, renderMode, lineThickness, lineColor, fillColor, shadow); DrawEllipse(rect, graphics, renderMode, lineThickness, lineColor, fillColor, shadow);
} }
/// <summary> /// <summary>
/// This allows another container to draw an ellipse /// This allows another container to draw an ellipse
/// </summary> /// </summary>
/// <param name="rect"></param> /// <param name="rect"></param>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
/// <param name="lineThickness"></param> /// <param name="lineThickness"></param>
/// <param name="lineColor"></param> /// <param name="lineColor"></param>
/// <param name="fillColor"></param> /// <param name="fillColor"></param>
/// <param name="shadow"></param> /// <param name="shadow"></param>
public static void DrawEllipse(Rectangle rect, Graphics graphics, RenderMode renderMode, int lineThickness, Color lineColor, Color fillColor, bool shadow) public static void DrawEllipse(Rectangle rect, Graphics graphics, RenderMode renderMode, int lineThickness, Color lineColor, Color fillColor, bool shadow)
{ {
bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
// draw shadow before anything else // draw shadow before anything else
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) if (shadow && (lineVisible || Colors.IsVisible(fillColor)))
{ {
int basealpha = 100; int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
int steps = 5; int steps = 5;
int currentStep = lineVisible ? 1 : 0; int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) while (currentStep <= steps)
{ {
using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)) using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))
{ {
Width = lineVisible ? lineThickness : 1 Width = lineVisible ? lineThickness : 1
}; };
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(rect.Left + currentStep, rect.Top + currentStep, rect.Width, rect.Height); Rectangle shadowRect = GuiRectangle.GetGuiRectangle(rect.Left + currentStep, rect.Top + currentStep, rect.Width, rect.Height);
graphics.DrawEllipse(shadowPen, shadowRect); graphics.DrawEllipse(shadowPen, shadowRect);
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
//draw the original shape //draw the original shape
if (Colors.IsVisible(fillColor)) if (Colors.IsVisible(fillColor))
{ {
using Brush brush = new SolidBrush(fillColor); using Brush brush = new SolidBrush(fillColor);
graphics.FillEllipse(brush, rect); graphics.FillEllipse(brush, rect);
} }
if (lineVisible) if (lineVisible)
{ {
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
graphics.DrawEllipse(pen, rect); graphics.DrawEllipse(pen, rect);
} }
} }
public override bool Contains(int x, int y) public override bool Contains(int x, int y)
{ {
return EllipseContains(this, x, y); return EllipseContains(this, x, y);
} }
/// <summary> /// <summary>
/// Allow the code to be used externally /// Allow the code to be used externally
/// </summary> /// </summary>
/// <param name="caller"></param> /// <param name="caller"></param>
/// <param name="x"></param> /// <param name="x"></param>
/// <param name="y"></param> /// <param name="y"></param>
/// <returns></returns> /// <returns></returns>
public static bool EllipseContains(DrawableContainer caller, int x, int y) public static bool EllipseContains(DrawableContainer caller, int x, int y)
{ {
double xDistanceFromCenter = x - (caller.Left + caller.Width / 2); double xDistanceFromCenter = x - (caller.Left + caller.Width / 2);
double yDistanceFromCenter = y - (caller.Top + caller.Height / 2); double yDistanceFromCenter = y - (caller.Top + caller.Height / 2);
// ellipse: x^2/a^2 + y^2/b^2 = 1 // ellipse: x^2/a^2 + y^2/b^2 = 1
return Math.Pow(xDistanceFromCenter, 2) / Math.Pow(caller.Width / 2, 2) + Math.Pow(yDistanceFromCenter, 2) / Math.Pow(caller.Height / 2, 2) < 1; return Math.Pow(xDistanceFromCenter, 2) / Math.Pow(caller.Width / 2, 2) + Math.Pow(yDistanceFromCenter, 2) / Math.Pow(caller.Height / 2, 2) < 1;
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10; int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
return EllipseClickableAt(rect, lineThickness, fillColor, x, y); return EllipseClickableAt(rect, lineThickness, fillColor, x, y);
} }
public static bool EllipseClickableAt(Rectangle rect, int lineThickness, Color fillColor, int x, int y) public static bool EllipseClickableAt(Rectangle rect, int lineThickness, Color fillColor, int x, int y)
{ {
// If we clicked inside the rectangle and it's visible we are clickable at. // If we clicked inside the rectangle and it's visible we are clickable at.
if (!Color.Transparent.Equals(fillColor)) if (!Color.Transparent.Equals(fillColor))
{ {
if (rect.Contains(x, y)) if (rect.Contains(x, y))
{ {
return true; return true;
} }
} }
// check the rest of the lines // check the rest of the lines
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(Color.White, lineThickness); using Pen pen = new Pen(Color.White, lineThickness);
using GraphicsPath path = new GraphicsPath(); using GraphicsPath path = new GraphicsPath();
path.AddEllipse(rect); path.AddEllipse(rect);
return path.IsOutlineVisible(x, y, pen); return path.IsOutlineVisible(x, y, pen);
} }
return false; return false;
} }
} }
} }

View file

@ -1,192 +1,192 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Configuration; using Greenshot.Editor.Configuration;
using log4net; using log4net;
namespace Greenshot.Drawing.Fields namespace Greenshot.Editor.Drawing.Fields
{ {
/// <summary> /// <summary>
/// Basic IFieldHolder implementation, providing access to a set of fields /// Basic IFieldHolder implementation, providing access to a set of fields
/// </summary> /// </summary>
[Serializable] [Serializable]
public abstract class AbstractFieldHolder : IFieldHolder public abstract class AbstractFieldHolder : IFieldHolder
{ {
private static readonly ILog LOG = LogManager.GetLogger(typeof(AbstractFieldHolder)); private static readonly ILog LOG = LogManager.GetLogger(typeof(AbstractFieldHolder));
private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
[NonSerialized] private readonly IDictionary<IField, PropertyChangedEventHandler> _handlers = new Dictionary<IField, PropertyChangedEventHandler>(); [NonSerialized] private readonly IDictionary<IField, PropertyChangedEventHandler> _handlers = new Dictionary<IField, PropertyChangedEventHandler>();
/// <summary> /// <summary>
/// called when a field's value has changed /// called when a field's value has changed
/// </summary> /// </summary>
[NonSerialized] private FieldChangedEventHandler _fieldChanged; [NonSerialized] private FieldChangedEventHandler _fieldChanged;
public event FieldChangedEventHandler FieldChanged public event FieldChangedEventHandler FieldChanged
{ {
add { _fieldChanged += value; } add { _fieldChanged += value; }
remove { _fieldChanged -= value; } remove { _fieldChanged -= value; }
} }
// we keep two Collections of our fields, dictionary for quick access, list for serialization // we keep two Collections of our fields, dictionary for quick access, list for serialization
// this allows us to use default serialization // this allows us to use default serialization
[NonSerialized] private IDictionary<IFieldType, IField> _fieldsByType = new Dictionary<IFieldType, IField>(); [NonSerialized] private IDictionary<IFieldType, IField> _fieldsByType = new Dictionary<IFieldType, IField>();
private readonly IList<IField> fields = new List<IField>(); private readonly IList<IField> fields = new List<IField>();
[OnDeserialized] [OnDeserialized]
private void OnDeserialized(StreamingContext context) private void OnDeserialized(StreamingContext context)
{ {
_fieldsByType = new Dictionary<IFieldType, IField>(); _fieldsByType = new Dictionary<IFieldType, IField>();
// listen to changing properties // listen to changing properties
foreach (var field in fields) foreach (var field in fields)
{ {
field.PropertyChanged += delegate { _fieldChanged?.Invoke(this, new FieldChangedEventArgs(field)); }; field.PropertyChanged += delegate { _fieldChanged?.Invoke(this, new FieldChangedEventArgs(field)); };
_fieldsByType[field.FieldType] = field; _fieldsByType[field.FieldType] = field;
} }
} }
public void AddField(Type requestingType, IFieldType fieldType, object fieldValue) public void AddField(Type requestingType, IFieldType fieldType, object fieldValue)
{ {
AddField(EditorConfig.CreateField(requestingType, fieldType, fieldValue)); AddField(EditorConfig.CreateField(requestingType, fieldType, fieldValue));
} }
public virtual void AddField(IField field) public virtual void AddField(IField field)
{ {
fields.Add(field); fields.Add(field);
if (_fieldsByType == null) if (_fieldsByType == null)
{ {
return; return;
} }
if (_fieldsByType.ContainsKey(field.FieldType)) if (_fieldsByType.ContainsKey(field.FieldType))
{ {
if (LOG.IsDebugEnabled) if (LOG.IsDebugEnabled)
{ {
LOG.DebugFormat("A field with of type '{0}' already exists in this {1}, will overwrite.", field.FieldType, GetType()); LOG.DebugFormat("A field with of type '{0}' already exists in this {1}, will overwrite.", field.FieldType, GetType());
} }
} }
_fieldsByType[field.FieldType] = field; _fieldsByType[field.FieldType] = field;
_handlers[field] = (sender, args) => { _fieldChanged?.Invoke(this, new FieldChangedEventArgs(field)); }; _handlers[field] = (sender, args) => { _fieldChanged?.Invoke(this, new FieldChangedEventArgs(field)); };
field.PropertyChanged += _handlers[field]; field.PropertyChanged += _handlers[field];
} }
public void RemoveField(IField field) public void RemoveField(IField field)
{ {
fields.Remove(field); fields.Remove(field);
_fieldsByType.Remove(field.FieldType); _fieldsByType.Remove(field.FieldType);
field.PropertyChanged -= _handlers[field]; field.PropertyChanged -= _handlers[field];
_handlers.Remove(field); _handlers.Remove(field);
} }
public IList<IField> GetFields() public IList<IField> GetFields()
{ {
return fields; return fields;
} }
public IField GetField(IFieldType fieldType) public IField GetField(IFieldType fieldType)
{ {
try try
{ {
return _fieldsByType[fieldType]; return _fieldsByType[fieldType];
} }
catch (KeyNotFoundException e) catch (KeyNotFoundException e)
{ {
throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e); throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e);
} }
} }
public object GetFieldValue(IFieldType fieldType) public object GetFieldValue(IFieldType fieldType)
{ {
return GetField(fieldType)?.Value; return GetField(fieldType)?.Value;
} }
public string GetFieldValueAsString(IFieldType fieldType) public string GetFieldValueAsString(IFieldType fieldType)
{ {
return Convert.ToString(GetFieldValue(fieldType)); return Convert.ToString(GetFieldValue(fieldType));
} }
public int GetFieldValueAsInt(IFieldType fieldType) public int GetFieldValueAsInt(IFieldType fieldType)
{ {
return Convert.ToInt32(GetFieldValue(fieldType)); return Convert.ToInt32(GetFieldValue(fieldType));
} }
public decimal GetFieldValueAsDecimal(IFieldType fieldType) public decimal GetFieldValueAsDecimal(IFieldType fieldType)
{ {
return Convert.ToDecimal(GetFieldValue(fieldType)); return Convert.ToDecimal(GetFieldValue(fieldType));
} }
public double GetFieldValueAsDouble(IFieldType fieldType) public double GetFieldValueAsDouble(IFieldType fieldType)
{ {
return Convert.ToDouble(GetFieldValue(fieldType)); return Convert.ToDouble(GetFieldValue(fieldType));
} }
public float GetFieldValueAsFloat(IFieldType fieldType) public float GetFieldValueAsFloat(IFieldType fieldType)
{ {
return Convert.ToSingle(GetFieldValue(fieldType)); return Convert.ToSingle(GetFieldValue(fieldType));
} }
public bool GetFieldValueAsBool(IFieldType fieldType) public bool GetFieldValueAsBool(IFieldType fieldType)
{ {
return Convert.ToBoolean(GetFieldValue(fieldType)); return Convert.ToBoolean(GetFieldValue(fieldType));
} }
public Color GetFieldValueAsColor(IFieldType fieldType, Color defaultColor = default) public Color GetFieldValueAsColor(IFieldType fieldType, Color defaultColor = default)
{ {
return (Color) (GetFieldValue(fieldType) ?? defaultColor); return (Color) (GetFieldValue(fieldType) ?? defaultColor);
} }
public bool HasField(IFieldType fieldType) public bool HasField(IFieldType fieldType)
{ {
return _fieldsByType.ContainsKey(fieldType); return _fieldsByType.ContainsKey(fieldType);
} }
public bool HasFieldValue(IFieldType fieldType) public bool HasFieldValue(IFieldType fieldType)
{ {
return HasField(fieldType) && _fieldsByType[fieldType].HasValue; return HasField(fieldType) && _fieldsByType[fieldType].HasValue;
} }
public void SetFieldValue(IFieldType fieldType, object value) public void SetFieldValue(IFieldType fieldType, object value)
{ {
try try
{ {
_fieldsByType[fieldType].Value = value; _fieldsByType[fieldType].Value = value;
} }
catch (KeyNotFoundException e) catch (KeyNotFoundException e)
{ {
throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e); throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e);
} }
} }
protected void OnFieldChanged(object sender, FieldChangedEventArgs e) protected void OnFieldChanged(object sender, FieldChangedEventArgs e)
{ {
_fieldChanged?.Invoke(sender, e); _fieldChanged?.Invoke(sender, e);
} }
} }
} }

View file

@ -1,149 +1,149 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Fields namespace Greenshot.Editor.Drawing.Fields
{ {
/// <summary> /// <summary>
/// Basic IFieldHolderWithChildren implementation. Similar to IFieldHolder, /// Basic IFieldHolderWithChildren implementation. Similar to IFieldHolder,
/// but has a List of IFieldHolder for children. /// but has a List of IFieldHolder for children.
/// Field values are passed to and from children as well. /// Field values are passed to and from children as well.
/// </summary> /// </summary>
[Serializable] [Serializable]
public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder
{ {
[NonSerialized] private readonly FieldChangedEventHandler _fieldChangedEventHandler; [NonSerialized] private readonly FieldChangedEventHandler _fieldChangedEventHandler;
[NonSerialized] private EventHandler childrenChanged; [NonSerialized] private EventHandler childrenChanged;
public event EventHandler ChildrenChanged public event EventHandler ChildrenChanged
{ {
add { childrenChanged += value; } add { childrenChanged += value; }
remove { childrenChanged -= value; } remove { childrenChanged -= value; }
} }
public IList<IFieldHolder> Children = new List<IFieldHolder>(); public IList<IFieldHolder> Children = new List<IFieldHolder>();
public AbstractFieldHolderWithChildren() public AbstractFieldHolderWithChildren()
{ {
_fieldChangedEventHandler = OnFieldChanged; _fieldChangedEventHandler = OnFieldChanged;
} }
[OnDeserialized()] [OnDeserialized()]
private void OnDeserialized(StreamingContext context) private void OnDeserialized(StreamingContext context)
{ {
// listen to changing properties // listen to changing properties
foreach (IFieldHolder fieldHolder in Children) foreach (IFieldHolder fieldHolder in Children)
{ {
fieldHolder.FieldChanged += _fieldChangedEventHandler; fieldHolder.FieldChanged += _fieldChangedEventHandler;
} }
childrenChanged?.Invoke(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public void AddChild(IFieldHolder fieldHolder) public void AddChild(IFieldHolder fieldHolder)
{ {
Children.Add(fieldHolder); Children.Add(fieldHolder);
fieldHolder.FieldChanged += _fieldChangedEventHandler; fieldHolder.FieldChanged += _fieldChangedEventHandler;
childrenChanged?.Invoke(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public void RemoveChild(IFieldHolder fieldHolder) public void RemoveChild(IFieldHolder fieldHolder)
{ {
Children.Remove(fieldHolder); Children.Remove(fieldHolder);
fieldHolder.FieldChanged -= _fieldChangedEventHandler; fieldHolder.FieldChanged -= _fieldChangedEventHandler;
childrenChanged?.Invoke(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public new IList<IField> GetFields() public new IList<IField> GetFields()
{ {
var ret = new List<IField>(); var ret = new List<IField>();
ret.AddRange(base.GetFields()); ret.AddRange(base.GetFields());
foreach (IFieldHolder fh in Children) foreach (IFieldHolder fh in Children)
{ {
ret.AddRange(fh.GetFields()); ret.AddRange(fh.GetFields());
} }
return ret; return ret;
} }
public new IField GetField(IFieldType fieldType) public new IField GetField(IFieldType fieldType)
{ {
IField ret = null; IField ret = null;
if (base.HasField(fieldType)) if (base.HasField(fieldType))
{ {
ret = base.GetField(fieldType); ret = base.GetField(fieldType);
} }
else else
{ {
foreach (IFieldHolder fh in Children) foreach (IFieldHolder fh in Children)
{ {
if (fh.HasField(fieldType)) if (fh.HasField(fieldType))
{ {
ret = fh.GetField(fieldType); ret = fh.GetField(fieldType);
break; break;
} }
} }
} }
if (ret == null) if (ret == null)
{ {
throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType()); throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType());
} }
return ret; return ret;
} }
public new bool HasField(IFieldType fieldType) public new bool HasField(IFieldType fieldType)
{ {
bool ret = base.HasField(fieldType); bool ret = base.HasField(fieldType);
if (!ret) if (!ret)
{ {
foreach (IFieldHolder fh in Children) foreach (IFieldHolder fh in Children)
{ {
if (fh.HasField(fieldType)) if (fh.HasField(fieldType))
{ {
ret = true; ret = true;
break; break;
} }
} }
} }
return ret; return ret;
} }
public new bool HasFieldValue(IFieldType fieldType) public new bool HasFieldValue(IFieldType fieldType)
{ {
IField f = GetField(fieldType); IField f = GetField(fieldType);
return f != null && f.HasValue; return f != null && f.HasValue;
} }
public new void SetFieldValue(IFieldType fieldType, object value) public new void SetFieldValue(IFieldType fieldType, object value)
{ {
IField f = GetField(fieldType); IField f = GetField(fieldType);
if (f != null) f.Value = value; if (f != null) f.Value = value;
} }
} }
} }

View file

@ -1,54 +1,54 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Basic IBindingConverter implementation /// Basic IBindingConverter implementation
/// </summary> /// </summary>
public abstract class AbstractBindingConverter<T1, T2> : IBindingConverter public abstract class AbstractBindingConverter<T1, T2> : IBindingConverter
{ {
public object convert(object o) public object convert(object o)
{ {
if (o == null) if (o == null)
{ {
return null; return null;
} }
if (o is T1) if (o is T1)
{ {
return convert((T1) o); return convert((T1) o);
} }
if (o is T2) if (o is T2)
{ {
return convert((T2) o); return convert((T2) o);
} }
throw new ArgumentException("Cannot handle argument of type " + o.GetType()); throw new ArgumentException("Cannot handle argument of type " + o.GetType());
} }
protected abstract T2 convert(T1 o); protected abstract T2 convert(T1 o);
protected abstract T1 convert(T2 o); protected abstract T1 convert(T2 o);
} }
} }

View file

@ -1,184 +1,184 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Reflection; using System.Reflection;
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Bidirectional binding of properties of two INotifyPropertyChanged instances. /// Bidirectional binding of properties of two INotifyPropertyChanged instances.
/// This implementation synchronizes null values, too. If you do not want this /// This implementation synchronizes null values, too. If you do not want this
/// behavior (e.g. when binding to a /// behavior (e.g. when binding to a
/// </summary> /// </summary>
public class BidirectionalBinding public class BidirectionalBinding
{ {
private readonly INotifyPropertyChanged _controlObject; private readonly INotifyPropertyChanged _controlObject;
private readonly INotifyPropertyChanged _fieldObject; private readonly INotifyPropertyChanged _fieldObject;
private readonly string _controlPropertyName; private readonly string _controlPropertyName;
private readonly string _fieldPropertyName; private readonly string _fieldPropertyName;
private bool _updatingControl; private bool _updatingControl;
private bool _updatingField; private bool _updatingField;
private IBindingConverter _converter; private IBindingConverter _converter;
private readonly IBindingValidator _validator; private readonly IBindingValidator _validator;
/// <summary> /// <summary>
/// Whether or not null values are passed on to the other object. /// Whether or not null values are passed on to the other object.
/// </summary> /// </summary>
protected bool AllowSynchronizeNull = true; protected bool AllowSynchronizeNull = true;
/// <summary> /// <summary>
/// Bind properties of two objects bidirectionally /// Bind properties of two objects bidirectionally
/// </summary> /// </summary>
/// <param name="controlObject">Object containing 1st property to bind</param> /// <param name="controlObject">Object containing 1st property to bind</param>
/// <param name="controlPropertyName">Property of 1st object to bind</param> /// <param name="controlPropertyName">Property of 1st object to bind</param>
/// <param name="fieldObject">Object containing 2nd property to bind</param> /// <param name="fieldObject">Object containing 2nd property to bind</param>
/// <param name="fieldPropertyName">Property of 2nd object to bind</param> /// <param name="fieldPropertyName">Property of 2nd object to bind</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName) public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName)
{ {
_controlObject = controlObject; _controlObject = controlObject;
_fieldObject = fieldObject; _fieldObject = fieldObject;
_controlPropertyName = controlPropertyName; _controlPropertyName = controlPropertyName;
_fieldPropertyName = fieldPropertyName; _fieldPropertyName = fieldPropertyName;
_controlObject.PropertyChanged += ControlPropertyChanged; _controlObject.PropertyChanged += ControlPropertyChanged;
_fieldObject.PropertyChanged += FieldPropertyChanged; _fieldObject.PropertyChanged += FieldPropertyChanged;
} }
/// <summary> /// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter /// Bind properties of two objects bidirectionally, converting the values using a converter
/// </summary> /// </summary>
/// <param name="controlObject">Object containing 1st property to bind</param> /// <param name="controlObject">Object containing 1st property to bind</param>
/// <param name="controlPropertyName">Property of 1st object to bind</param> /// <param name="controlPropertyName">Property of 1st object to bind</param>
/// <param name="fieldObject">Object containing 2nd property to bind</param> /// <param name="fieldObject">Object containing 2nd property to bind</param>
/// <param name="fieldPropertyName">Property of 2nd object to bind</param> /// <param name="fieldPropertyName">Property of 2nd object to bind</param>
/// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param> /// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName,
IBindingConverter converter) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName) IBindingConverter converter) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName)
{ {
_converter = converter; _converter = converter;
} }
/// <summary> /// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter. /// Bind properties of two objects bidirectionally, converting the values using a converter.
/// Synchronization can be intercepted by adding a validator. /// Synchronization can be intercepted by adding a validator.
/// </summary> /// </summary>
/// <param name="controlObject">Object containing 1st property to bind</param> /// <param name="controlObject">Object containing 1st property to bind</param>
/// <param name="controlPropertyName">Property of 1st object to bind</param> /// <param name="controlPropertyName">Property of 1st object to bind</param>
/// <param name="fieldObject">Object containing 2nd property to bind</param> /// <param name="fieldObject">Object containing 2nd property to bind</param>
/// <param name="fieldPropertyName">Property of 2nd object to bind</param> /// <param name="fieldPropertyName">Property of 2nd object to bind</param>
/// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param> /// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName,
IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName) IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName)
{ {
_validator = validator; _validator = validator;
} }
/// <summary> /// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter. /// Bind properties of two objects bidirectionally, converting the values using a converter.
/// Synchronization can be intercepted by adding a validator. /// Synchronization can be intercepted by adding a validator.
/// </summary> /// </summary>
/// <param name="controlObject">Object containing 1st property to bind</param> /// <param name="controlObject">Object containing 1st property to bind</param>
/// <param name="controlPropertyName">Property of 1st object to bind</param> /// <param name="controlPropertyName">Property of 1st object to bind</param>
/// <param name="fieldObject">Object containing 2nd property to bind</param> /// <param name="fieldObject">Object containing 2nd property to bind</param>
/// <param name="fieldPropertyName">Property of 2nd object to bind</param> /// <param name="fieldPropertyName">Property of 2nd object to bind</param>
/// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param> /// <param name="converter">taking care of converting the synchronized value to the correct target format and back</param>
/// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param> /// <param name="validator">validator to intercept synchronization if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName, public BidirectionalBinding(INotifyPropertyChanged controlObject, string controlPropertyName, INotifyPropertyChanged fieldObject, string fieldPropertyName,
IBindingConverter converter, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName, converter) IBindingConverter converter, IBindingValidator validator) : this(controlObject, controlPropertyName, fieldObject, fieldPropertyName, converter)
{ {
_validator = validator; _validator = validator;
} }
public void ControlPropertyChanged(object sender, PropertyChangedEventArgs e) public void ControlPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (!_updatingControl && e.PropertyName.Equals(_controlPropertyName)) if (!_updatingControl && e.PropertyName.Equals(_controlPropertyName))
{ {
_updatingField = true; _updatingField = true;
Synchronize(_controlObject, _controlPropertyName, _fieldObject, _fieldPropertyName); Synchronize(_controlObject, _controlPropertyName, _fieldObject, _fieldPropertyName);
_updatingField = false; _updatingField = false;
} }
} }
public void FieldPropertyChanged(object sender, PropertyChangedEventArgs e) public void FieldPropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (!_updatingField && e.PropertyName.Equals(_fieldPropertyName)) if (!_updatingField && e.PropertyName.Equals(_fieldPropertyName))
{ {
_updatingControl = true; _updatingControl = true;
Synchronize(_fieldObject, _fieldPropertyName, _controlObject, _controlPropertyName); Synchronize(_fieldObject, _fieldPropertyName, _controlObject, _controlPropertyName);
_updatingControl = false; _updatingControl = false;
} }
} }
private void Synchronize(INotifyPropertyChanged sourceObject, string sourceProperty, INotifyPropertyChanged targetObject, string targetProperty) private void Synchronize(INotifyPropertyChanged sourceObject, string sourceProperty, INotifyPropertyChanged targetObject, string targetProperty)
{ {
PropertyInfo targetPropertyInfo = ResolvePropertyInfo(targetObject, targetProperty); PropertyInfo targetPropertyInfo = ResolvePropertyInfo(targetObject, targetProperty);
PropertyInfo sourcePropertyInfo = ResolvePropertyInfo(sourceObject, sourceProperty); PropertyInfo sourcePropertyInfo = ResolvePropertyInfo(sourceObject, sourceProperty);
if (sourcePropertyInfo != null && targetPropertyInfo != null && targetPropertyInfo.CanWrite) if (sourcePropertyInfo != null && targetPropertyInfo != null && targetPropertyInfo.CanWrite)
{ {
object bValue = sourcePropertyInfo.GetValue(sourceObject, null); object bValue = sourcePropertyInfo.GetValue(sourceObject, null);
if (_converter != null && bValue != null) if (_converter != null && bValue != null)
{ {
bValue = _converter.convert(bValue); bValue = _converter.convert(bValue);
} }
try try
{ {
if (_validator == null || _validator.validate(bValue)) if (_validator == null || _validator.validate(bValue))
{ {
targetPropertyInfo.SetValue(targetObject, bValue, null); targetPropertyInfo.SetValue(targetObject, bValue, null);
} }
} }
catch (Exception e) catch (Exception e)
{ {
throw new MemberAccessException( throw new MemberAccessException(
"Could not set property '" + targetProperty + "' to '" + bValue + "' [" + (bValue?.GetType().Name ?? string.Empty) + "] on " + targetObject + "Could not set property '" + targetProperty + "' to '" + bValue + "' [" + (bValue?.GetType().Name ?? string.Empty) + "] on " + targetObject +
". Probably other type than expected, IBindingCoverter to the rescue.", e); ". Probably other type than expected, IBindingCoverter to the rescue.", e);
} }
} }
} }
private static PropertyInfo ResolvePropertyInfo(object obj, string property) private static PropertyInfo ResolvePropertyInfo(object obj, string property)
{ {
PropertyInfo ret = null; PropertyInfo ret = null;
string[] properties = property.Split(".".ToCharArray()); string[] properties = property.Split(".".ToCharArray());
for (int i = 0; i < properties.Length; i++) for (int i = 0; i < properties.Length; i++)
{ {
string prop = properties[i]; string prop = properties[i];
ret = obj.GetType().GetProperty(prop); ret = obj.GetType().GetProperty(prop);
if (ret != null && ret.CanRead && i < prop.Length - 1) if (ret != null && ret.CanRead && i < prop.Length - 1)
{ {
obj = ret.GetValue(obj, null); obj = ret.GetValue(obj, null);
} }
} }
return ret; return ret;
} }
public IBindingConverter Converter public IBindingConverter Converter
{ {
get { return _converter; } get { return _converter; }
set { _converter = value; } set { _converter = value; }
} }
} }
} }

View file

@ -1,52 +1,52 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Converts decimal to double (%) and vice versa, e.g. 95f to 0.95d /// Converts decimal to double (%) and vice versa, e.g. 95f to 0.95d
/// </summary> /// </summary>
public class DecimalDoublePercentageConverter : AbstractBindingConverter<double, decimal> public class DecimalDoublePercentageConverter : AbstractBindingConverter<double, decimal>
{ {
private static DecimalDoublePercentageConverter _uniqueInstance; private static DecimalDoublePercentageConverter _uniqueInstance;
private DecimalDoublePercentageConverter() private DecimalDoublePercentageConverter()
{ {
} }
protected override decimal convert(double o) protected override decimal convert(double o)
{ {
return Convert.ToDecimal(o) * 100; return Convert.ToDecimal(o) * 100;
} }
protected override double convert(decimal o) protected override double convert(decimal o)
{ {
return Convert.ToDouble(o) / 100; return Convert.ToDouble(o) / 100;
} }
public static DecimalDoublePercentageConverter GetInstance() public static DecimalDoublePercentageConverter GetInstance()
{ {
return _uniqueInstance ??= new DecimalDoublePercentageConverter(); return _uniqueInstance ??= new DecimalDoublePercentageConverter();
} }
} }
} }

View file

@ -1,52 +1,52 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Converts decimal to float and vice versa. /// Converts decimal to float and vice versa.
/// </summary> /// </summary>
public class DecimalFloatConverter : AbstractBindingConverter<float, decimal> public class DecimalFloatConverter : AbstractBindingConverter<float, decimal>
{ {
private static DecimalFloatConverter _uniqueInstance; private static DecimalFloatConverter _uniqueInstance;
private DecimalFloatConverter() private DecimalFloatConverter()
{ {
} }
protected override decimal convert(float o) protected override decimal convert(float o)
{ {
return Convert.ToDecimal(o); return Convert.ToDecimal(o);
} }
protected override float convert(decimal o) protected override float convert(decimal o)
{ {
return Convert.ToSingle(o); return Convert.ToSingle(o);
} }
public static DecimalFloatConverter GetInstance() public static DecimalFloatConverter GetInstance()
{ {
return _uniqueInstance ??= new DecimalFloatConverter(); return _uniqueInstance ??= new DecimalFloatConverter();
} }
} }
} }

View file

@ -1,52 +1,52 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Converts decimal to int and vice versa. /// Converts decimal to int and vice versa.
/// </summary> /// </summary>
public class DecimalIntConverter : AbstractBindingConverter<int, decimal> public class DecimalIntConverter : AbstractBindingConverter<int, decimal>
{ {
private static DecimalIntConverter _uniqueInstance; private static DecimalIntConverter _uniqueInstance;
private DecimalIntConverter() private DecimalIntConverter()
{ {
} }
protected override decimal convert(int o) protected override decimal convert(int o)
{ {
return Convert.ToDecimal(o); return Convert.ToDecimal(o);
} }
protected override int convert(decimal o) protected override int convert(decimal o)
{ {
return Convert.ToInt32(o); return Convert.ToInt32(o);
} }
public static DecimalIntConverter GetInstance() public static DecimalIntConverter GetInstance()
{ {
return _uniqueInstance ??= new DecimalIntConverter(); return _uniqueInstance ??= new DecimalIntConverter();
} }
} }
} }

View file

@ -1,33 +1,33 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Interface for a bidirectional converter, for use with BidirectionalBinding. /// Interface for a bidirectional converter, for use with BidirectionalBinding.
/// convert(object) implementation must deal with both directions. /// convert(object) implementation must deal with both directions.
/// see DecimalIntConverter /// see DecimalIntConverter
/// </summary> /// </summary>
public interface IBindingConverter public interface IBindingConverter
{ {
object convert(object o); object convert(object o);
} }
} }

View file

@ -1,34 +1,34 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Interface for a bidirectional validator, for use with BidirectionalBinding. /// Interface for a bidirectional validator, for use with BidirectionalBinding.
/// Useful if you do not want to synchronize values which would be illegal on /// Useful if you do not want to synchronize values which would be illegal on
/// one of the bound objects (e.g. null value on some form components) /// one of the bound objects (e.g. null value on some form components)
/// see NotNullValidator /// see NotNullValidator
/// </summary> /// </summary>
public interface IBindingValidator public interface IBindingValidator
{ {
bool validate(object o); bool validate(object o);
} }
} }

View file

@ -1,45 +1,45 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
namespace Greenshot.Drawing.Fields.Binding namespace Greenshot.Editor.Drawing.Fields.Binding
{ {
/// <summary> /// <summary>
/// Validates a value not to be null. /// Validates a value not to be null.
/// </summary> /// </summary>
public class NotNullValidator : IBindingValidator public class NotNullValidator : IBindingValidator
{ {
private static NotNullValidator _uniqueInstance; private static NotNullValidator _uniqueInstance;
private NotNullValidator() private NotNullValidator()
{ {
} }
public bool validate(object o) public bool validate(object o)
{ {
return o != null; return o != null;
} }
public static NotNullValidator GetInstance() public static NotNullValidator GetInstance()
{ {
return _uniqueInstance ??= new NotNullValidator(); return _uniqueInstance ??= new NotNullValidator();
} }
} }
} }

View file

@ -1,128 +1,128 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Fields namespace Greenshot.Editor.Drawing.Fields
{ {
/// <summary> /// <summary>
/// Represents a single field of a drawable element, i.e. /// Represents a single field of a drawable element, i.e.
/// line thickness of a rectangle. /// line thickness of a rectangle.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class Field : IField public class Field : IField
{ {
[field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged;
private object _myValue; private object _myValue;
public object Value public object Value
{ {
get { return _myValue; } get { return _myValue; }
set set
{ {
if (!Equals(_myValue, value)) if (!Equals(_myValue, value))
{ {
_myValue = value; _myValue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
} }
} }
} }
public IFieldType FieldType { get; set; } public IFieldType FieldType { get; set; }
public string Scope { get; set; } public string Scope { get; set; }
/// <summary> /// <summary>
/// Constructs a new Field instance, usually you should be using FieldFactory /// Constructs a new Field instance, usually you should be using FieldFactory
/// to create Fields. /// to create Fields.
/// </summary> /// </summary>
/// <param name="fieldType">FieldType of the Field to be created</param> /// <param name="fieldType">FieldType of the Field to be created</param>
/// <param name="scope">The scope to which the value of this Field is relevant. /// <param name="scope">The scope to which the value of this Field is relevant.
/// Depending on the scope the Field's value may be shared for other elements /// Depending on the scope the Field's value may be shared for other elements
/// containing the same FieldType for defaulting to the last used value. /// containing the same FieldType for defaulting to the last used value.
/// When scope is set to a Type (e.g. typeof(RectangleContainer)), its value /// When scope is set to a Type (e.g. typeof(RectangleContainer)), its value
/// should not be reused for FieldHolders of another Type (e.g. typeof(EllipseContainer)) /// should not be reused for FieldHolders of another Type (e.g. typeof(EllipseContainer))
/// </param> /// </param>
public Field(IFieldType fieldType, Type scope) public Field(IFieldType fieldType, Type scope)
{ {
FieldType = fieldType; FieldType = fieldType;
Scope = scope.Name; Scope = scope.Name;
} }
public Field(IFieldType fieldType, string scope) public Field(IFieldType fieldType, string scope)
{ {
FieldType = fieldType; FieldType = fieldType;
Scope = scope; Scope = scope;
} }
public Field(IFieldType fieldType) public Field(IFieldType fieldType)
{ {
FieldType = fieldType; FieldType = fieldType;
} }
/// <summary> /// <summary>
/// Returns true if this field holds a value other than null. /// Returns true if this field holds a value other than null.
/// </summary> /// </summary>
public bool HasValue => Value != null; public bool HasValue => Value != null;
/// <summary> /// <summary>
/// Creates a flat clone of this Field. The fields value itself is not cloned. /// Creates a flat clone of this Field. The fields value itself is not cloned.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public Field Clone() public Field Clone()
{ {
return new Field(FieldType, Scope) return new Field(FieldType, Scope)
{ {
Value = Value Value = Value
}; };
} }
public override int GetHashCode() public override int GetHashCode()
{ {
int hashCode = 0; int hashCode = 0;
unchecked unchecked
{ {
hashCode += 1000000009 * FieldType.GetHashCode(); hashCode += 1000000009 * FieldType.GetHashCode();
if (Scope != null) if (Scope != null)
hashCode += 1000000021 * Scope.GetHashCode(); hashCode += 1000000021 * Scope.GetHashCode();
} }
return hashCode; return hashCode;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (!(obj is Field other)) if (!(obj is Field other))
{ {
return false; return false;
} }
return FieldType == other.FieldType && Equals(Scope, other.Scope); return FieldType == other.FieldType && Equals(Scope, other.Scope);
} }
public override string ToString() public override string ToString()
{ {
return string.Format("[Field FieldType={1} Value={0} Scope={2}]", _myValue, FieldType, Scope); return string.Format("[Field FieldType={1} Value={0} Scope={2}]", _myValue, FieldType, Scope);
} }
} }
} }

View file

@ -1,224 +1,224 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using Greenshot.Configuration; using System.Collections.Generic;
using System.Collections.Generic; using System.ComponentModel;
using System.ComponentModel; using System.Linq;
using System.Linq; using Greenshot.Base.IniFile;
using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Configuration;
namespace Greenshot.Drawing.Fields namespace Greenshot.Editor.Drawing.Fields
{ {
/// <summary> /// <summary>
/// Represents the current set of properties for the editor. /// Represents the current set of properties for the editor.
/// When one of EditorProperties' properties is updated, the change will be promoted /// When one of EditorProperties' properties is updated, the change will be promoted
/// to all bound elements. /// to all bound elements.
/// * If an element is selected: /// * If an element is selected:
/// This class represents the element's properties /// This class represents the element's properties
/// * I n>1 elements are selected: /// * I n>1 elements are selected:
/// This class represents the properties of all elements. /// This class represents the properties of all elements.
/// Properties that do not apply for ALL selected elements are null (or 0 respectively) /// Properties that do not apply for ALL selected elements are null (or 0 respectively)
/// If the property values of the selected elements differ, the value of the last bound element wins. /// If the property values of the selected elements differ, the value of the last bound element wins.
/// </summary> /// </summary>
[Serializable] [Serializable]
public sealed class FieldAggregator : AbstractFieldHolder public sealed class FieldAggregator : AbstractFieldHolder
{ {
private readonly IDrawableContainerList _boundContainers; private readonly IDrawableContainerList _boundContainers;
private bool _internalUpdateRunning; private bool _internalUpdateRunning;
private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
public FieldAggregator(ISurface parent) public FieldAggregator(ISurface parent)
{ {
foreach (var fieldType in FieldType.Values) foreach (var fieldType in FieldType.Values)
{ {
var field = new Field(fieldType, GetType()); var field = new Field(fieldType, GetType());
AddField(field); AddField(field);
} }
_boundContainers = new DrawableContainerList _boundContainers = new DrawableContainerList
{ {
Parent = parent Parent = parent
}; };
} }
public override void AddField(IField field) public override void AddField(IField field)
{ {
base.AddField(field); base.AddField(field);
field.PropertyChanged += OwnPropertyChanged; field.PropertyChanged += OwnPropertyChanged;
} }
public void BindElements(IDrawableContainerList dcs) public void BindElements(IDrawableContainerList dcs)
{ {
foreach (var dc in dcs) foreach (var dc in dcs)
{ {
BindElement(dc); BindElement(dc);
} }
} }
public void BindElement(IDrawableContainer dc) public void BindElement(IDrawableContainer dc)
{ {
if (!(dc is DrawableContainer container) || _boundContainers.Contains(container)) if (!(dc is DrawableContainer container) || _boundContainers.Contains(container))
{ {
return; return;
} }
_boundContainers.Add(container); _boundContainers.Add(container);
container.ChildrenChanged += delegate { UpdateFromBoundElements(); }; container.ChildrenChanged += delegate { UpdateFromBoundElements(); };
UpdateFromBoundElements(); UpdateFromBoundElements();
} }
public void BindAndUpdateElement(IDrawableContainer dc) public void BindAndUpdateElement(IDrawableContainer dc)
{ {
UpdateElement(dc); UpdateElement(dc);
BindElement(dc); BindElement(dc);
} }
public void UpdateElement(IDrawableContainer dc) public void UpdateElement(IDrawableContainer dc)
{ {
if (!(dc is DrawableContainer container)) if (!(dc is DrawableContainer container))
{ {
return; return;
} }
_internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (var field in GetFields()) foreach (var field in GetFields())
{ {
if (container.HasField(field.FieldType) && field.HasValue) if (container.HasField(field.FieldType) && field.HasValue)
{ {
//if(LOG.IsDebugEnabled) LOG.Debug(" "+field+ ": "+field.Value); //if(LOG.IsDebugEnabled) LOG.Debug(" "+field+ ": "+field.Value);
container.SetFieldValue(field.FieldType, field.Value); container.SetFieldValue(field.FieldType, field.Value);
} }
} }
_internalUpdateRunning = false; _internalUpdateRunning = false;
} }
public void UnbindElement(IDrawableContainer dc) public void UnbindElement(IDrawableContainer dc)
{ {
if (_boundContainers.Contains(dc)) if (_boundContainers.Contains(dc))
{ {
_boundContainers.Remove(dc); _boundContainers.Remove(dc);
UpdateFromBoundElements(); UpdateFromBoundElements();
} }
} }
public void Clear() public void Clear()
{ {
ClearFields(); ClearFields();
_boundContainers.Clear(); _boundContainers.Clear();
UpdateFromBoundElements(); UpdateFromBoundElements();
} }
/// <summary> /// <summary>
/// sets all field values to null, however does not remove fields /// sets all field values to null, however does not remove fields
/// </summary> /// </summary>
private void ClearFields() private void ClearFields()
{ {
_internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (var field in GetFields()) foreach (var field in GetFields())
{ {
field.Value = null; field.Value = null;
} }
_internalUpdateRunning = false; _internalUpdateRunning = false;
} }
/// <summary> /// <summary>
/// Updates this instance using the respective fields from the bound elements. /// Updates this instance using the respective fields from the bound elements.
/// Fields that do not apply to every bound element are set to null, or 0 respectively. /// Fields that do not apply to every bound element are set to null, or 0 respectively.
/// All other fields will be set to the field value of the least bound element. /// All other fields will be set to the field value of the least bound element.
/// </summary> /// </summary>
private void UpdateFromBoundElements() private void UpdateFromBoundElements()
{ {
ClearFields(); ClearFields();
_internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (var field in FindCommonFields()) foreach (var field in FindCommonFields())
{ {
SetFieldValue(field.FieldType, field.Value); SetFieldValue(field.FieldType, field.Value);
} }
_internalUpdateRunning = false; _internalUpdateRunning = false;
} }
private IList<IField> FindCommonFields() private IList<IField> FindCommonFields()
{ {
IList<IField> returnFields = null; IList<IField> returnFields = null;
if (_boundContainers.Count > 0) if (_boundContainers.Count > 0)
{ {
// take all fields from the least selected container... // take all fields from the least selected container...
if (_boundContainers[_boundContainers.Count - 1] is DrawableContainer leastSelectedContainer) if (_boundContainers[_boundContainers.Count - 1] is DrawableContainer leastSelectedContainer)
{ {
returnFields = leastSelectedContainer.GetFields(); returnFields = leastSelectedContainer.GetFields();
for (int i = 0; i < _boundContainers.Count - 1; i++) for (int i = 0; i < _boundContainers.Count - 1; i++)
{ {
if (!(_boundContainers[i] is DrawableContainer dc)) continue; if (!(_boundContainers[i] is DrawableContainer dc)) continue;
IList<IField> fieldsToRemove = new List<IField>(); IList<IField> fieldsToRemove = new List<IField>();
foreach (IField field in returnFields) foreach (IField field in returnFields)
{ {
// ... throw out those that do not apply to one of the other containers // ... throw out those that do not apply to one of the other containers
if (!dc.HasField(field.FieldType)) if (!dc.HasField(field.FieldType))
{ {
fieldsToRemove.Add(field); fieldsToRemove.Add(field);
} }
} }
foreach (var field in fieldsToRemove) foreach (var field in fieldsToRemove)
{ {
returnFields.Remove(field); returnFields.Remove(field);
} }
} }
} }
} }
return returnFields ?? new List<IField>(); return returnFields ?? new List<IField>();
} }
public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea)
{ {
IField field = (IField) sender; IField field = (IField) sender;
if (_internalUpdateRunning || field.Value == null) if (_internalUpdateRunning || field.Value == null)
{ {
return; return;
} }
foreach (var drawableContainer1 in _boundContainers.ToList()) foreach (var drawableContainer1 in _boundContainers.ToList())
{ {
var drawableContainer = (DrawableContainer) drawableContainer1; var drawableContainer = (DrawableContainer) drawableContainer1;
if (!drawableContainer.HasField(field.FieldType)) if (!drawableContainer.HasField(field.FieldType))
{ {
continue; continue;
} }
IField drawableContainerField = drawableContainer.GetField(field.FieldType); IField drawableContainerField = drawableContainer.GetField(field.FieldType);
// Notify before change, so we can e.g. invalidate the area // Notify before change, so we can e.g. invalidate the area
drawableContainer.BeforeFieldChange(drawableContainerField, field.Value); drawableContainer.BeforeFieldChange(drawableContainerField, field.Value);
drawableContainerField.Value = field.Value; drawableContainerField.Value = field.Value;
// update last used from DC field, so that scope is honored // update last used from DC field, so that scope is honored
EditorConfig.UpdateLastFieldValue(drawableContainerField); EditorConfig.UpdateLastFieldValue(drawableContainerField);
} }
} }
} }
} }

View file

@ -1,106 +1,106 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Fields namespace Greenshot.Editor.Drawing.Fields
{ {
/// <summary> /// <summary>
/// Defines all FieldTypes + their default value. /// Defines all FieldTypes + their default value.
/// (The additional value is why this is not an enum) /// (The additional value is why this is not an enum)
/// </summary> /// </summary>
[Serializable] [Serializable]
public class FieldType : IFieldType public class FieldType : IFieldType
{ {
public static readonly IFieldType ARROWHEADS = new FieldType("ARROWHEADS"); public static readonly IFieldType ARROWHEADS = new FieldType("ARROWHEADS");
public static readonly IFieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS"); public static readonly IFieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS");
public static readonly IFieldType BRIGHTNESS = new FieldType("BRIGHTNESS"); public static readonly IFieldType BRIGHTNESS = new FieldType("BRIGHTNESS");
public static readonly IFieldType FILL_COLOR = new FieldType("FILL_COLOR"); public static readonly IFieldType FILL_COLOR = new FieldType("FILL_COLOR");
public static readonly IFieldType FONT_BOLD = new FieldType("FONT_BOLD"); public static readonly IFieldType FONT_BOLD = new FieldType("FONT_BOLD");
public static readonly IFieldType FONT_FAMILY = new FieldType("FONT_FAMILY"); public static readonly IFieldType FONT_FAMILY = new FieldType("FONT_FAMILY");
public static readonly IFieldType FONT_ITALIC = new FieldType("FONT_ITALIC"); public static readonly IFieldType FONT_ITALIC = new FieldType("FONT_ITALIC");
public static readonly IFieldType FONT_SIZE = new FieldType("FONT_SIZE"); public static readonly IFieldType FONT_SIZE = new FieldType("FONT_SIZE");
public static readonly IFieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType("TEXT_HORIZONTAL_ALIGNMENT"); public static readonly IFieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType("TEXT_HORIZONTAL_ALIGNMENT");
public static readonly IFieldType TEXT_VERTICAL_ALIGNMENT = new FieldType("TEXT_VERTICAL_ALIGNMENT"); public static readonly IFieldType TEXT_VERTICAL_ALIGNMENT = new FieldType("TEXT_VERTICAL_ALIGNMENT");
public static readonly IFieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR"); public static readonly IFieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR");
public static readonly IFieldType LINE_COLOR = new FieldType("LINE_COLOR"); public static readonly IFieldType LINE_COLOR = new FieldType("LINE_COLOR");
public static readonly IFieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS"); public static readonly IFieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS");
public static readonly IFieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR"); public static readonly IFieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR");
public static readonly IFieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE"); public static readonly IFieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE");
public static readonly IFieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY"); public static readonly IFieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY");
public static readonly IFieldType SHADOW = new FieldType("SHADOW"); public static readonly IFieldType SHADOW = new FieldType("SHADOW");
public static readonly IFieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE"); public static readonly IFieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE");
public static readonly IFieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT"); public static readonly IFieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT");
public static readonly IFieldType FLAGS = new FieldType("FLAGS"); public static readonly IFieldType FLAGS = new FieldType("FLAGS");
public static IFieldType[] Values = public static IFieldType[] Values =
{ {
ARROWHEADS, BLUR_RADIUS, BRIGHTNESS, FILL_COLOR, FONT_BOLD, FONT_FAMILY, FONT_ITALIC, FONT_SIZE, TEXT_HORIZONTAL_ALIGNMENT, TEXT_VERTICAL_ALIGNMENT, HIGHLIGHT_COLOR, ARROWHEADS, BLUR_RADIUS, BRIGHTNESS, FILL_COLOR, FONT_BOLD, FONT_FAMILY, FONT_ITALIC, FONT_SIZE, TEXT_HORIZONTAL_ALIGNMENT, TEXT_VERTICAL_ALIGNMENT, HIGHLIGHT_COLOR,
LINE_COLOR, LINE_THICKNESS, MAGNIFICATION_FACTOR, PIXEL_SIZE, PREVIEW_QUALITY, SHADOW, PREPARED_FILTER_OBFUSCATE, PREPARED_FILTER_HIGHLIGHT, FLAGS LINE_COLOR, LINE_THICKNESS, MAGNIFICATION_FACTOR, PIXEL_SIZE, PREVIEW_QUALITY, SHADOW, PREPARED_FILTER_OBFUSCATE, PREPARED_FILTER_HIGHLIGHT, FLAGS
}; };
public string Name { get; set; } public string Name { get; set; }
private FieldType(string name) private FieldType(string name)
{ {
Name = name; Name = name;
} }
public override string ToString() public override string ToString()
{ {
return Name; return Name;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
int hashCode = 0; int hashCode = 0;
unchecked unchecked
{ {
if (Name != null) if (Name != null)
hashCode += 1000000009 * Name.GetHashCode(); hashCode += 1000000009 * Name.GetHashCode();
} }
return hashCode; return hashCode;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
FieldType other = obj as FieldType; FieldType other = obj as FieldType;
if (other == null) if (other == null)
{ {
return false; return false;
} }
return Equals(Name, other.Name); return Equals(Name, other.Name);
} }
public static bool operator ==(FieldType a, FieldType b) public static bool operator ==(FieldType a, FieldType b)
{ {
return Equals(a, b); return Equals(a, b);
} }
public static bool operator !=(FieldType a, FieldType b) public static bool operator !=(FieldType a, FieldType b)
{ {
return !Equals(a, b); return !Equals(a, b);
} }
} }
} }

View file

@ -1,115 +1,115 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using Greenshot.Drawing.Fields; using System.Drawing.Drawing2D;
using Greenshot.Helpers; using System.Runtime.Serialization;
using System.Drawing.Drawing2D; using Greenshot.Base.Interfaces.Drawing;
using System.Runtime.Serialization; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// empty container for filter-only elements /// empty container for filter-only elements
/// </summary> /// </summary>
[Serializable] [Serializable]
public abstract class FilterContainer : DrawableContainer public abstract class FilterContainer : DrawableContainer
{ {
public enum PreparedFilterMode public enum PreparedFilterMode
{ {
OBFUSCATE, OBFUSCATE,
HIGHLIGHT HIGHLIGHT
}; };
public enum PreparedFilter public enum PreparedFilter
{ {
BLUR, BLUR,
PIXELIZE, PIXELIZE,
TEXT_HIGHTLIGHT, TEXT_HIGHTLIGHT,
AREA_HIGHLIGHT, AREA_HIGHLIGHT,
GRAYSCALE, GRAYSCALE,
MAGNIFICATION MAGNIFICATION
}; };
public FilterContainer(Surface parent) : base(parent) public FilterContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 0); AddField(GetType(), FieldType.LINE_THICKNESS, 0);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.SHADOW, false); AddField(GetType(), FieldType.SHADOW, false);
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
if (lineVisible) if (lineVisible)
{ {
graphics.SmoothingMode = SmoothingMode.HighSpeed; graphics.SmoothingMode = SmoothingMode.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
//draw shadow first //draw shadow first
if (shadow) if (shadow)
{ {
int basealpha = 100; int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
int steps = 5; int steps = 5;
int currentStep = lineVisible ? 1 : 0; int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) while (currentStep <= steps)
{ {
using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness); using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + currentStep, Top + currentStep, Width, Height); Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + currentStep, Top + currentStep, Width, Height);
graphics.DrawRectangle(shadowPen, shadowRect); graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
graphics.DrawRectangle(pen, rect); graphics.DrawRectangle(pen, rect);
} }
} }
} }
} }
} }

View file

@ -1,83 +1,83 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
/// <summary> /// <summary>
/// Graphical filter which can be added to DrawableContainer. /// Graphical filter which can be added to DrawableContainer.
/// Subclasses should fulfill INotifyPropertyChanged contract, i.e. call /// Subclasses should fulfill INotifyPropertyChanged contract, i.e. call
/// OnPropertyChanged whenever a public property has been changed. /// OnPropertyChanged whenever a public property has been changed.
/// </summary> /// </summary>
[Serializable] [Serializable]
public abstract class AbstractFilter : AbstractFieldHolder, IFilter public abstract class AbstractFilter : AbstractFieldHolder, IFilter
{ {
[NonSerialized] private PropertyChangedEventHandler propertyChanged; [NonSerialized] private PropertyChangedEventHandler propertyChanged;
public event PropertyChangedEventHandler PropertyChanged public event PropertyChangedEventHandler PropertyChanged
{ {
add { propertyChanged += value; } add { propertyChanged += value; }
remove { propertyChanged -= value; } remove { propertyChanged -= value; }
} }
private bool invert; private bool invert;
public bool Invert public bool Invert
{ {
get { return invert; } get { return invert; }
set set
{ {
invert = value; invert = value;
OnPropertyChanged("Invert"); OnPropertyChanged("Invert");
} }
} }
protected DrawableContainer parent; protected DrawableContainer parent;
public DrawableContainer Parent public DrawableContainer Parent
{ {
get { return parent; } get { return parent; }
set { parent = value; } set { parent = value; }
} }
public AbstractFilter(DrawableContainer parent) public AbstractFilter(DrawableContainer parent)
{ {
this.parent = parent; this.parent = parent;
} }
public DrawableContainer GetParent() public DrawableContainer GetParent()
{ {
return parent; return parent;
} }
public abstract void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode); public abstract void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode);
protected void OnPropertyChanged(string propertyName) protected void OnPropertyChanged(string propertyName)
{ {
propertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); propertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
} }
} }

View file

@ -1,83 +1,83 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using Greenshot.Drawing.Fields; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using Greenshot.Base.Core;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Base.UnmanagedHelpers; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
[Serializable] [Serializable]
public class BlurFilter : AbstractFilter public class BlurFilter : AbstractFilter
{ {
public double previewQuality; public double previewQuality;
public double PreviewQuality public double PreviewQuality
{ {
get { return previewQuality; } get { return previewQuality; }
set set
{ {
previewQuality = value; previewQuality = value;
OnPropertyChanged("PreviewQuality"); OnPropertyChanged("PreviewQuality");
} }
} }
public BlurFilter(DrawableContainer parent) : base(parent) public BlurFilter(DrawableContainer parent) : base(parent)
{ {
AddField(GetType(), FieldType.BLUR_RADIUS, 3); AddField(GetType(), FieldType.BLUR_RADIUS, 3);
AddField(GetType(), FieldType.PREVIEW_QUALITY, 1.0d); AddField(GetType(), FieldType.PREVIEW_QUALITY, 1.0d);
} }
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS); int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (applyRect.Width == 0 || applyRect.Height == 0) if (applyRect.Width == 0 || applyRect.Height == 0)
{ {
return; return;
} }
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
if (Invert) if (Invert)
{ {
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
if (GDIplus.IsBlurPossible(blurRadius)) if (GDIplus.IsBlurPossible(blurRadius))
{ {
GDIplus.DrawWithBlur(graphics, applyBitmap, applyRect, null, null, blurRadius, false); GDIplus.DrawWithBlur(graphics, applyBitmap, applyRect, null, null, blurRadius, false);
} }
else else
{ {
using IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect); using IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect);
ImageHelper.ApplyBoxBlur(fastBitmap, blurRadius); ImageHelper.ApplyBoxBlur(fastBitmap, blurRadius);
fastBitmap.DrawTo(graphics, applyRect); fastBitmap.DrawTo(graphics, applyRect);
} }
graphics.Restore(state); graphics.Restore(state);
} }
} }
} }

View file

@ -1,73 +1,73 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using Greenshot.Drawing.Fields; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Drawing.Drawing2D; using Greenshot.Base.Core;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
[Serializable()] [Serializable()]
public class BrightnessFilter : AbstractFilter public class BrightnessFilter : AbstractFilter
{ {
public BrightnessFilter(DrawableContainer parent) : base(parent) public BrightnessFilter(DrawableContainer parent) : base(parent)
{ {
AddField(GetType(), FieldType.BRIGHTNESS, 0.9d); AddField(GetType(), FieldType.BRIGHTNESS, 0.9d);
} }
/// <summary> /// <summary>
/// Implements the Apply code for the Brightness Filet /// Implements the Apply code for the Brightness Filet
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="applyBitmap"></param> /// <param name="applyBitmap"></param>
/// <param name="rect"></param> /// <param name="rect"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (applyRect.Width == 0 || applyRect.Height == 0) if (applyRect.Width == 0 || applyRect.Height == 0)
{ {
// nothing to do // nothing to do
return; return;
} }
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
if (Invert) if (Invert)
{ {
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
float brightness = GetFieldValueAsFloat(FieldType.BRIGHTNESS); float brightness = GetFieldValueAsFloat(FieldType.BRIGHTNESS);
using (ImageAttributes ia = ImageHelper.CreateAdjustAttributes(brightness, 1f, 1f)) using (ImageAttributes ia = ImageHelper.CreateAdjustAttributes(brightness, 1f, 1f))
{ {
graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia);
} }
graphics.Restore(state); graphics.Restore(state);
} }
} }
} }

View file

@ -1,90 +1,90 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
/// <summary> /// <summary>
/// Description of GrayscaleFilter. /// Description of GrayscaleFilter.
/// </summary> /// </summary>
[Serializable()] [Serializable()]
public class GrayscaleFilter : AbstractFilter public class GrayscaleFilter : AbstractFilter
{ {
public GrayscaleFilter(DrawableContainer parent) : base(parent) public GrayscaleFilter(DrawableContainer parent) : base(parent)
{ {
} }
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (applyRect.Width == 0 || applyRect.Height == 0) if (applyRect.Width == 0 || applyRect.Height == 0)
{ {
// nothing to do // nothing to do
return; return;
} }
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
if (Invert) if (Invert)
{ {
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
ColorMatrix grayscaleMatrix = new ColorMatrix(new[] ColorMatrix grayscaleMatrix = new ColorMatrix(new[]
{ {
new[] new[]
{ {
.3f, .3f, .3f, 0, 0 .3f, .3f, .3f, 0, 0
}, },
new[] new[]
{ {
.59f, .59f, .59f, 0, 0 .59f, .59f, .59f, 0, 0
}, },
new[] new[]
{ {
.11f, .11f, .11f, 0, 0 .11f, .11f, .11f, 0, 0
}, },
new float[] new float[]
{ {
0, 0, 0, 1, 0 0, 0, 0, 1, 0
}, },
new float[] new float[]
{ {
0, 0, 0, 0, 1 0, 0, 0, 0, 1
} }
}); });
using (ImageAttributes ia = new ImageAttributes()) using (ImageAttributes ia = new ImageAttributes())
{ {
ia.SetColorMatrix(grayscaleMatrix); ia.SetColorMatrix(grayscaleMatrix);
graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia);
} }
graphics.Restore(state); graphics.Restore(state);
} }
} }
} }

View file

@ -1,82 +1,82 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using Greenshot.Drawing.Fields; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using Greenshot.Base.Core;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
[Serializable()] [Serializable()]
public class HighlightFilter : AbstractFilter public class HighlightFilter : AbstractFilter
{ {
public HighlightFilter(DrawableContainer parent) : base(parent) public HighlightFilter(DrawableContainer parent) : base(parent)
{ {
AddField(GetType(), FieldType.FILL_COLOR, Color.Yellow); AddField(GetType(), FieldType.FILL_COLOR, Color.Yellow);
} }
/// <summary> /// <summary>
/// Implements the Apply code for the Brightness Filet /// Implements the Apply code for the Brightness Filet
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="applyBitmap"></param> /// <param name="applyBitmap"></param>
/// <param name="rect"></param> /// <param name="rect"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (applyRect.Width == 0 || applyRect.Height == 0) if (applyRect.Width == 0 || applyRect.Height == 0)
{ {
// nothing to do // nothing to do
return; return;
} }
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
if (Invert) if (Invert)
{ {
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect)) using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(applyBitmap, applyRect))
{ {
Color highlightColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color highlightColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
for (int y = fastBitmap.Top; y < fastBitmap.Bottom; y++) for (int y = fastBitmap.Top; y < fastBitmap.Bottom; y++)
{ {
for (int x = fastBitmap.Left; x < fastBitmap.Right; x++) for (int x = fastBitmap.Left; x < fastBitmap.Right; x++)
{ {
Color color = fastBitmap.GetColorAt(x, y); Color color = fastBitmap.GetColorAt(x, y);
color = Color.FromArgb(color.A, Math.Min(highlightColor.R, color.R), Math.Min(highlightColor.G, color.G), Math.Min(highlightColor.B, color.B)); color = Color.FromArgb(color.A, Math.Min(highlightColor.R, color.R), Math.Min(highlightColor.G, color.G), Math.Min(highlightColor.B, color.B));
fastBitmap.SetColorAt(x, y, color); fastBitmap.SetColorAt(x, y, color);
} }
} }
fastBitmap.DrawTo(graphics, applyRect.Location); fastBitmap.DrawTo(graphics, applyRect.Location);
} }
graphics.Restore(state); graphics.Restore(state);
} }
} }
} }

View file

@ -1,35 +1,35 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
public interface IFilter : INotifyPropertyChanged, IFieldHolder public interface IFilter : INotifyPropertyChanged, IFieldHolder
{ {
DrawableContainer Parent { get; set; } DrawableContainer Parent { get; set; }
void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode); void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode);
DrawableContainer GetParent(); DrawableContainer GetParent();
bool Invert { get; set; } bool Invert { get; set; }
} }
} }

View file

@ -1,70 +1,70 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using Greenshot.Drawing.Fields; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using Greenshot.Base.Core;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing.Fields;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
[Serializable] [Serializable]
public class MagnifierFilter : AbstractFilter public class MagnifierFilter : AbstractFilter
{ {
public MagnifierFilter(DrawableContainer parent) : base(parent) public MagnifierFilter(DrawableContainer parent) : base(parent)
{ {
AddField(GetType(), FieldType.MAGNIFICATION_FACTOR, 2); AddField(GetType(), FieldType.MAGNIFICATION_FACTOR, 2);
} }
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (applyRect.Width == 0 || applyRect.Height == 0) if (applyRect.Width == 0 || applyRect.Height == 0)
{ {
// nothing to do // nothing to do
return; return;
} }
int magnificationFactor = GetFieldValueAsInt(FieldType.MAGNIFICATION_FACTOR); int magnificationFactor = GetFieldValueAsInt(FieldType.MAGNIFICATION_FACTOR);
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
if (Invert) if (Invert)
{ {
graphics.SetClip(applyRect); graphics.SetClip(applyRect);
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
graphics.SmoothingMode = SmoothingMode.None; graphics.SmoothingMode = SmoothingMode.None;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor; graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
int halfWidth = rect.Width / 2; int halfWidth = rect.Width / 2;
int halfHeight = rect.Height / 2; int halfHeight = rect.Height / 2;
int newWidth = rect.Width / magnificationFactor; int newWidth = rect.Width / magnificationFactor;
int newHeight = rect.Height / magnificationFactor; int newHeight = rect.Height / magnificationFactor;
Rectangle source = new Rectangle(rect.X + halfWidth - newWidth / 2, rect.Y + halfHeight - newHeight / 2, newWidth, newHeight); Rectangle source = new Rectangle(rect.X + halfWidth - newWidth / 2, rect.Y + halfHeight - newHeight / 2, newWidth, newHeight);
graphics.DrawImage(applyBitmap, rect, source, GraphicsUnit.Pixel); graphics.DrawImage(applyBitmap, rect, source, GraphicsUnit.Pixel);
graphics.Restore(state); graphics.Restore(state);
} }
} }
} }

View file

@ -1,105 +1,105 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Helpers; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing.Filters namespace Greenshot.Editor.Drawing.Filters
{ {
[Serializable()] [Serializable()]
public class PixelizationFilter : AbstractFilter public class PixelizationFilter : AbstractFilter
{ {
public PixelizationFilter(DrawableContainer parent) : base(parent) public PixelizationFilter(DrawableContainer parent) : base(parent)
{ {
AddField(GetType(), FieldType.PIXEL_SIZE, 5); AddField(GetType(), FieldType.PIXEL_SIZE, 5);
} }
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode)
{ {
int pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE); int pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE);
ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert);
if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0) if (pixelSize <= 1 || rect.Width == 0 || rect.Height == 0)
{ {
// Nothing to do // Nothing to do
return; return;
} }
if (rect.Width < pixelSize) if (rect.Width < pixelSize)
{ {
pixelSize = rect.Width; pixelSize = rect.Width;
} }
if (rect.Height < pixelSize) if (rect.Height < pixelSize)
{ {
pixelSize = rect.Height; pixelSize = rect.Height;
} }
using IFastBitmap dest = FastBitmap.CreateCloneOf(applyBitmap, rect); using IFastBitmap dest = FastBitmap.CreateCloneOf(applyBitmap, rect);
using (IFastBitmap src = FastBitmap.Create(applyBitmap, rect)) using (IFastBitmap src = FastBitmap.Create(applyBitmap, rect))
{ {
List<Color> colors = new List<Color>(); List<Color> colors = new List<Color>();
int halbPixelSize = pixelSize / 2; int halbPixelSize = pixelSize / 2;
for (int y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y += pixelSize) for (int y = src.Top - halbPixelSize; y < src.Bottom + halbPixelSize; y += pixelSize)
{ {
for (int x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x += pixelSize) for (int x = src.Left - halbPixelSize; x <= src.Right + halbPixelSize; x += pixelSize)
{ {
colors.Clear(); colors.Clear();
for (int yy = y; yy < y + pixelSize; yy++) for (int yy = y; yy < y + pixelSize; yy++)
{ {
if (yy >= src.Top && yy < src.Bottom) if (yy >= src.Top && yy < src.Bottom)
{ {
for (int xx = x; xx < x + pixelSize; xx++) for (int xx = x; xx < x + pixelSize; xx++)
{ {
if (xx >= src.Left && xx < src.Right) if (xx >= src.Left && xx < src.Right)
{ {
colors.Add(src.GetColorAt(xx, yy)); colors.Add(src.GetColorAt(xx, yy));
} }
} }
} }
} }
Color currentAvgColor = Colors.Mix(colors); Color currentAvgColor = Colors.Mix(colors);
for (int yy = y; yy <= y + pixelSize; yy++) for (int yy = y; yy <= y + pixelSize; yy++)
{ {
if (yy >= src.Top && yy < src.Bottom) if (yy >= src.Top && yy < src.Bottom)
{ {
for (int xx = x; xx <= x + pixelSize; xx++) for (int xx = x; xx <= x + pixelSize; xx++)
{ {
if (xx >= src.Left && xx < src.Right) if (xx >= src.Left && xx < src.Right)
{ {
dest.SetColorAt(xx, yy, currentAvgColor); dest.SetColorAt(xx, yy, currentAvgColor);
} }
} }
} }
} }
} }
} }
} }
dest.DrawTo(graphics, rect.Location); dest.DrawTo(graphics, rect.Location);
} }
} }
} }

View file

@ -1,323 +1,323 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Drawing.Fields; using System;
using Greenshot.Helpers; using System.Collections.Generic;
using System; using System.Drawing;
using System.Collections.Generic; using System.Drawing.Drawing2D;
using System.Drawing; using System.Runtime.Serialization;
using System.Drawing.Drawing2D; using Greenshot.Base.Interfaces.Drawing;
using System.Runtime.Serialization; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of PathContainer. /// Description of PathContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class FreehandContainer : DrawableContainer public class FreehandContainer : DrawableContainer
{ {
private static readonly float[] PointOffset = private static readonly float[] PointOffset =
{ {
0.5f, 0.25f, 0.75f 0.5f, 0.25f, 0.75f
}; };
[NonSerialized] private GraphicsPath freehandPath = new GraphicsPath(); [NonSerialized] private GraphicsPath freehandPath = new GraphicsPath();
private Rectangle myBounds = Rectangle.Empty; private Rectangle myBounds = Rectangle.Empty;
private Point lastMouse = Point.Empty; private Point lastMouse = Point.Empty;
private readonly List<Point> capturePoints = new List<Point>(); private readonly List<Point> capturePoints = new List<Point>();
private bool isRecalculated; private bool isRecalculated;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public FreehandContainer(Surface parent) : base(parent) public FreehandContainer(Surface parent) : base(parent)
{ {
Width = parent.Image.Width; Width = parent.Image.Width;
Height = parent.Image.Height; Height = parent.Image.Height;
Top = 0; Top = 0;
Left = 0; Left = 0;
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 3); AddField(GetType(), FieldType.LINE_THICKNESS, 3);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
} }
public override void Transform(Matrix matrix) public override void Transform(Matrix matrix)
{ {
Point[] points = capturePoints.ToArray(); Point[] points = capturePoints.ToArray();
matrix.TransformPoints(points); matrix.TransformPoints(points);
capturePoints.Clear(); capturePoints.Clear();
capturePoints.AddRange(points); capturePoints.AddRange(points);
RecalculatePath(); RecalculatePath();
} }
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
RecalculatePath(); RecalculatePath();
} }
/// <summary> /// <summary>
/// This Dispose is called from the Dispose and the Destructor. /// This Dispose is called from the Dispose and the Destructor.
/// </summary> /// </summary>
/// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param> /// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
base.Dispose(disposing); base.Dispose(disposing);
if (disposing) if (disposing)
{ {
freehandPath?.Dispose(); freehandPath?.Dispose();
} }
freehandPath = null; freehandPath = null;
} }
/// <summary> /// <summary>
/// Called from Surface (the parent) when the drawing begins (mouse-down) /// Called from Surface (the parent) when the drawing begins (mouse-down)
/// </summary> /// </summary>
/// <returns>true if the surface doesn't need to handle the event</returns> /// <returns>true if the surface doesn't need to handle the event</returns>
public override bool HandleMouseDown(int mouseX, int mouseY) public override bool HandleMouseDown(int mouseX, int mouseY)
{ {
lastMouse = new Point(mouseX, mouseY); lastMouse = new Point(mouseX, mouseY);
capturePoints.Add(lastMouse); capturePoints.Add(lastMouse);
return true; return true;
} }
/// <summary> /// <summary>
/// Called from Surface (the parent) if a mouse move is made while drawing /// Called from Surface (the parent) if a mouse move is made while drawing
/// </summary> /// </summary>
/// <returns>true if the surface doesn't need to handle the event</returns> /// <returns>true if the surface doesn't need to handle the event</returns>
public override bool HandleMouseMove(int mouseX, int mouseY) public override bool HandleMouseMove(int mouseX, int mouseY)
{ {
Point previousPoint = capturePoints[capturePoints.Count - 1]; Point previousPoint = capturePoints[capturePoints.Count - 1];
if (GeometryHelper.Distance2D(previousPoint.X, previousPoint.Y, mouseX, mouseY) >= 2 * EditorConfig.FreehandSensitivity) if (GeometryHelper.Distance2D(previousPoint.X, previousPoint.Y, mouseX, mouseY) >= 2 * EditorConfig.FreehandSensitivity)
{ {
capturePoints.Add(new Point(mouseX, mouseY)); capturePoints.Add(new Point(mouseX, mouseY));
} }
if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) < EditorConfig.FreehandSensitivity) if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) < EditorConfig.FreehandSensitivity)
{ {
return true; return true;
} }
//path.AddCurve(new Point[]{lastMouse, new Point(mouseX, mouseY)}); //path.AddCurve(new Point[]{lastMouse, new Point(mouseX, mouseY)});
lastMouse = new Point(mouseX, mouseY); lastMouse = new Point(mouseX, mouseY);
freehandPath.AddLine(lastMouse, new Point(mouseX, mouseY)); freehandPath.AddLine(lastMouse, new Point(mouseX, mouseY));
// Only re-calculate the bounds & redraw when we added something to the path // Only re-calculate the bounds & redraw when we added something to the path
myBounds = Rectangle.Round(freehandPath.GetBounds()); myBounds = Rectangle.Round(freehandPath.GetBounds());
Invalidate(); Invalidate();
return true; return true;
} }
/// <summary> /// <summary>
/// Called when the surface finishes drawing the element /// Called when the surface finishes drawing the element
/// </summary> /// </summary>
public override void HandleMouseUp(int mouseX, int mouseY) public override void HandleMouseUp(int mouseX, int mouseY)
{ {
// Make sure we don't loose the ending point // Make sure we don't loose the ending point
if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) >= EditorConfig.FreehandSensitivity) if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) >= EditorConfig.FreehandSensitivity)
{ {
capturePoints.Add(new Point(mouseX, mouseY)); capturePoints.Add(new Point(mouseX, mouseY));
} }
RecalculatePath(); RecalculatePath();
} }
/// <summary> /// <summary>
/// Here we recalculate the freehand path by smoothing out the lines with Beziers. /// Here we recalculate the freehand path by smoothing out the lines with Beziers.
/// </summary> /// </summary>
private void RecalculatePath() private void RecalculatePath()
{ {
// Store the previous path, to dispose it later when we are finished // Store the previous path, to dispose it later when we are finished
var previousFreehandPath = freehandPath; var previousFreehandPath = freehandPath;
var newFreehandPath = new GraphicsPath(); var newFreehandPath = new GraphicsPath();
// Here we can put some cleanup... like losing all the uninteresting points. // Here we can put some cleanup... like losing all the uninteresting points.
if (capturePoints.Count >= 3) if (capturePoints.Count >= 3)
{ {
int index = 0; int index = 0;
while ((capturePoints.Count - 1) % 3 != 0) while ((capturePoints.Count - 1) % 3 != 0)
{ {
// duplicate points, first at 50% than 25% than 75% // duplicate points, first at 50% than 25% than 75%
capturePoints.Insert((int) (capturePoints.Count * PointOffset[index]), capturePoints[(int) (capturePoints.Count * PointOffset[index++])]); capturePoints.Insert((int) (capturePoints.Count * PointOffset[index]), capturePoints[(int) (capturePoints.Count * PointOffset[index++])]);
} }
newFreehandPath.AddBeziers(capturePoints.ToArray()); newFreehandPath.AddBeziers(capturePoints.ToArray());
} }
else if (capturePoints.Count == 2) else if (capturePoints.Count == 2)
{ {
newFreehandPath.AddLine(capturePoints[0], capturePoints[1]); newFreehandPath.AddLine(capturePoints[0], capturePoints[1]);
} }
// Recalculate the bounds // Recalculate the bounds
myBounds = Rectangle.Round(newFreehandPath.GetBounds()); myBounds = Rectangle.Round(newFreehandPath.GetBounds());
// assign // assign
isRecalculated = true; isRecalculated = true;
freehandPath = newFreehandPath; freehandPath = newFreehandPath;
// dispose previous // dispose previous
previousFreehandPath?.Dispose(); previousFreehandPath?.Dispose();
} }
/// <summary> /// <summary>
/// Do the drawing of the freehand "stroke" /// Do the drawing of the freehand "stroke"
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
public override void Draw(Graphics graphics, RenderMode renderMode) public override void Draw(Graphics graphics, RenderMode renderMode)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
using var pen = new Pen(lineColor) using var pen = new Pen(lineColor)
{ {
Width = lineThickness Width = lineThickness
}; };
if (!(pen.Width > 0)) if (!(pen.Width > 0))
{ {
return; return;
} }
// Make sure the lines are nicely rounded // Make sure the lines are nicely rounded
pen.EndCap = LineCap.Round; pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round; pen.StartCap = LineCap.Round;
pen.LineJoin = LineJoin.Round; pen.LineJoin = LineJoin.Round;
// Move to where we need to draw // Move to where we need to draw
graphics.TranslateTransform(Left, Top); graphics.TranslateTransform(Left, Top);
var currentFreehandPath = freehandPath; var currentFreehandPath = freehandPath;
if (currentFreehandPath != null) if (currentFreehandPath != null)
{ {
if (isRecalculated && Selected && renderMode == RenderMode.EDIT) if (isRecalculated && Selected && renderMode == RenderMode.EDIT)
{ {
isRecalculated = false; isRecalculated = false;
DrawSelectionBorder(graphics, pen, currentFreehandPath); DrawSelectionBorder(graphics, pen, currentFreehandPath);
} }
graphics.DrawPath(pen, currentFreehandPath); graphics.DrawPath(pen, currentFreehandPath);
} }
// Move back, otherwise everything is shifted // Move back, otherwise everything is shifted
graphics.TranslateTransform(-Left, -Top); graphics.TranslateTransform(-Left, -Top);
} }
/// <summary> /// <summary>
/// Draw a selectionborder around the freehand path /// Draw a selectionborder around the freehand path
/// </summary> /// </summary>
/// <param name="graphics">Graphics</param> /// <param name="graphics">Graphics</param>
/// <param name="linePen">Pen</param> /// <param name="linePen">Pen</param>
/// <param name="path">GraphicsPath</param> /// <param name="path">GraphicsPath</param>
protected static void DrawSelectionBorder(Graphics graphics, Pen linePen, GraphicsPath path) protected static void DrawSelectionBorder(Graphics graphics, Pen linePen, GraphicsPath path)
{ {
using var selectionPen = (Pen) linePen.Clone(); using var selectionPen = (Pen) linePen.Clone();
using var selectionPath = (GraphicsPath) path.Clone(); using var selectionPath = (GraphicsPath) path.Clone();
selectionPen.Width += 5; selectionPen.Width += 5;
selectionPen.Color = Color.FromArgb(120, Color.LightSeaGreen); selectionPen.Color = Color.FromArgb(120, Color.LightSeaGreen);
graphics.DrawPath(selectionPen, selectionPath); graphics.DrawPath(selectionPen, selectionPath);
selectionPath.Widen(selectionPen); selectionPath.Widen(selectionPen);
selectionPen.DashPattern = new float[] selectionPen.DashPattern = new float[]
{ {
2, 2 2, 2
}; };
selectionPen.Color = Color.LightSeaGreen; selectionPen.Color = Color.LightSeaGreen;
selectionPen.Width = 1; selectionPen.Width = 1;
graphics.DrawPath(selectionPen, selectionPath); graphics.DrawPath(selectionPen, selectionPath);
} }
/// <summary> /// <summary>
/// Get the bounds in which we have something drawn, plus safety margin, these are not the normal bounds... /// Get the bounds in which we have something drawn, plus safety margin, these are not the normal bounds...
/// </summary> /// </summary>
public override Rectangle DrawingBounds public override Rectangle DrawingBounds
{ {
get get
{ {
if (!myBounds.IsEmpty) if (!myBounds.IsEmpty)
{ {
int lineThickness = Math.Max(10, GetFieldValueAsInt(FieldType.LINE_THICKNESS)); int lineThickness = Math.Max(10, GetFieldValueAsInt(FieldType.LINE_THICKNESS));
int safetymargin = 10; int safetymargin = 10;
return new Rectangle(myBounds.Left + Left - (safetymargin + lineThickness), myBounds.Top + Top - (safetymargin + lineThickness), return new Rectangle(myBounds.Left + Left - (safetymargin + lineThickness), myBounds.Top + Top - (safetymargin + lineThickness),
myBounds.Width + 2 * (lineThickness + safetymargin), myBounds.Height + 2 * (lineThickness + safetymargin)); myBounds.Width + 2 * (lineThickness + safetymargin), myBounds.Height + 2 * (lineThickness + safetymargin));
} }
if (_parent?.Image is Image image) if (_parent?.Image is Image image)
{ {
return new Rectangle(0, 0, image.Width, image.Height); return new Rectangle(0, 0, image.Width, image.Height);
} }
else else
{ {
return Rectangle.Empty; return Rectangle.Empty;
} }
} }
} }
/// <summary> /// <summary>
/// FreehandContainer are regarded equal if they are of the same type and their paths are equal. /// FreehandContainer are regarded equal if they are of the same type and their paths are equal.
/// </summary> /// </summary>
/// <param name="obj">object</param> /// <param name="obj">object</param>
/// <returns>bool</returns> /// <returns>bool</returns>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
bool ret = false; bool ret = false;
if (obj == null || GetType() != obj.GetType()) if (obj == null || GetType() != obj.GetType())
{ {
return false; return false;
} }
if (obj is FreehandContainer other && Equals(freehandPath, other.freehandPath)) if (obj is FreehandContainer other && Equals(freehandPath, other.freehandPath))
{ {
ret = true; ret = true;
} }
return ret; return ret;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return freehandPath?.GetHashCode() ?? 0; return freehandPath?.GetHashCode() ?? 0;
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
bool returnValue = base.ClickableAt(x, y); bool returnValue = base.ClickableAt(x, y);
if (returnValue) if (returnValue)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
using var pen = new Pen(Color.White) using var pen = new Pen(Color.White)
{ {
Width = lineThickness + 10 Width = lineThickness + 10
}; };
returnValue = freehandPath.IsOutlineVisible(x - Left, y - Top, pen); returnValue = freehandPath.IsOutlineVisible(x - Left, y - Top, pen);
} }
return returnValue; return returnValue;
} }
} }
} }

View file

@ -1,112 +1,112 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Drawing.Filters; using Greenshot.Editor.Drawing.Filters;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of ObfuscateContainer. /// Description of ObfuscateContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class HighlightContainer : FilterContainer public class HighlightContainer : FilterContainer
{ {
public HighlightContainer(Surface parent) : base(parent) public HighlightContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
/// <summary> /// <summary>
/// Use settings from base, extend with our own field /// Use settings from base, extend with our own field
/// </summary> /// </summary>
protected override void InitializeFields() protected override void InitializeFields()
{ {
base.InitializeFields(); base.InitializeFields();
AddField(GetType(), FieldType.PREPARED_FILTER_HIGHLIGHT, PreparedFilter.TEXT_HIGHTLIGHT); AddField(GetType(), FieldType.PREPARED_FILTER_HIGHLIGHT, PreparedFilter.TEXT_HIGHTLIGHT);
} }
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
Init(); Init();
} }
private void Init() private void Init()
{ {
FieldChanged += HighlightContainer_OnFieldChanged; FieldChanged += HighlightContainer_OnFieldChanged;
ConfigurePreparedFilters(); ConfigurePreparedFilters();
} }
protected void HighlightContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) protected void HighlightContainer_OnFieldChanged(object sender, FieldChangedEventArgs e)
{ {
if (!sender.Equals(this)) if (!sender.Equals(this))
{ {
return; return;
} }
if (Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_HIGHLIGHT)) if (Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_HIGHLIGHT))
{ {
ConfigurePreparedFilters(); ConfigurePreparedFilters();
} }
} }
private void ConfigurePreparedFilters() private void ConfigurePreparedFilters()
{ {
PreparedFilter preset = (PreparedFilter) GetFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT); PreparedFilter preset = (PreparedFilter) GetFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT);
while (Filters.Count > 0) while (Filters.Count > 0)
{ {
Remove(Filters[0]); Remove(Filters[0]);
} }
switch (preset) switch (preset)
{ {
case PreparedFilter.TEXT_HIGHTLIGHT: case PreparedFilter.TEXT_HIGHTLIGHT:
Add(new HighlightFilter(this)); Add(new HighlightFilter(this));
break; break;
case PreparedFilter.AREA_HIGHLIGHT: case PreparedFilter.AREA_HIGHLIGHT:
var brightnessFilter = new BrightnessFilter(this) var brightnessFilter = new BrightnessFilter(this)
{ {
Invert = true Invert = true
}; };
Add(brightnessFilter); Add(brightnessFilter);
var blurFilter = new BlurFilter(this) var blurFilter = new BlurFilter(this)
{ {
Invert = true Invert = true
}; };
Add(blurFilter); Add(blurFilter);
break; break;
case PreparedFilter.GRAYSCALE: case PreparedFilter.GRAYSCALE:
AbstractFilter f = new GrayscaleFilter(this) AbstractFilter f = new GrayscaleFilter(this)
{ {
Invert = true Invert = true
}; };
Add(f); Add(f);
break; break;
case PreparedFilter.MAGNIFICATION: case PreparedFilter.MAGNIFICATION:
Add(new MagnifierFilter(this)); Add(new MagnifierFilter(this));
break; break;
} }
} }
} }
} }

View file

@ -1,120 +1,120 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.IO; using System.Drawing.Drawing2D;
using System.Drawing.Drawing2D; using System.IO;
using log4net; using System.Runtime.Serialization;
using System.Runtime.Serialization; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Drawing; using log4net;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of IconContainer. /// Description of IconContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class IconContainer : DrawableContainer, IIconContainer public class IconContainer : DrawableContainer, IIconContainer
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(IconContainer)); private static readonly ILog Log = LogManager.GetLogger(typeof(IconContainer));
protected Icon icon; protected Icon icon;
public IconContainer(Surface parent) : base(parent) public IconContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
public IconContainer(Surface parent, string filename) : base(parent) public IconContainer(Surface parent, string filename) : base(parent)
{ {
Load(filename); Load(filename);
} }
public Icon Icon public Icon Icon
{ {
set set
{ {
icon?.Dispose(); icon?.Dispose();
icon = (Icon) value.Clone(); icon = (Icon) value.Clone();
Width = value.Width; Width = value.Width;
Height = value.Height; Height = value.Height;
} }
get => icon; get => icon;
} }
/** /**
* This Dispose is called from the Dispose and the Destructor. * This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too! * When disposing==true all non-managed resources should be freed too!
*/ */
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
icon?.Dispose(); icon?.Dispose();
} }
icon = null; icon = null;
base.Dispose(disposing); base.Dispose(disposing);
} }
public void Load(string filename) public void Load(string filename)
{ {
if (!File.Exists(filename)) if (!File.Exists(filename))
{ {
return; return;
} }
using Icon fileIcon = new Icon(filename); using Icon fileIcon = new Icon(filename);
Icon = fileIcon; Icon = fileIcon;
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width); Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
if (icon == null) if (icon == null)
{ {
return; return;
} }
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor; graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.CompositingQuality = CompositingQuality.Default; graphics.CompositingQuality = CompositingQuality.Default;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.DrawIcon(icon, Bounds); graphics.DrawIcon(icon, Bounds);
} }
public override bool HasDefaultSize => true; public override bool HasDefaultSize => true;
public override Size DefaultSize => icon?.Size ?? new Size(16, 16); public override Size DefaultSize => icon?.Size ?? new Size(16, 16);
} }
} }

View file

@ -1,267 +1,267 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.IO; using System.Drawing.Drawing2D;
using Greenshot.Drawing.Fields; using System.IO;
using System.Drawing.Drawing2D; using System.Runtime.Serialization;
using log4net; using Greenshot.Base.Core;
using System.Runtime.Serialization; using Greenshot.Base.Effects;
using Greenshot.Base.Core; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Effects; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using log4net;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of BitmapContainer. /// Description of BitmapContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class ImageContainer : DrawableContainer, IImageContainer public class ImageContainer : DrawableContainer, IImageContainer
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageContainer)); private static readonly ILog Log = LogManager.GetLogger(typeof(ImageContainer));
private Image image; private Image image;
/// <summary> /// <summary>
/// This is the shadow version of the bitmap, rendered once to save performance /// This is the shadow version of the bitmap, rendered once to save performance
/// Do not serialize, as the shadow is recreated from the original bitmap if it's not available /// Do not serialize, as the shadow is recreated from the original bitmap if it's not available
/// </summary> /// </summary>
[NonSerialized] private Image _shadowBitmap; [NonSerialized] private Image _shadowBitmap;
/// <summary> /// <summary>
/// This is the offset for the shadow version of the bitmap /// This is the offset for the shadow version of the bitmap
/// Do not serialize, as the offset is recreated /// Do not serialize, as the offset is recreated
/// </summary> /// </summary>
[NonSerialized] private Point _shadowOffset = new Point(-1, -1); [NonSerialized] private Point _shadowOffset = new Point(-1, -1);
public ImageContainer(Surface parent, string filename) : this(parent) public ImageContainer(Surface parent, string filename) : this(parent)
{ {
Load(filename); Load(filename);
} }
public ImageContainer(Surface parent) : base(parent) public ImageContainer(Surface parent) : base(parent)
{ {
FieldChanged += BitmapContainer_OnFieldChanged; FieldChanged += BitmapContainer_OnFieldChanged;
Init(); Init();
} }
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.SHADOW, false); AddField(GetType(), FieldType.SHADOW, false);
} }
protected void BitmapContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) protected void BitmapContainer_OnFieldChanged(object sender, FieldChangedEventArgs e)
{ {
if (!sender.Equals(this)) if (!sender.Equals(this))
{ {
return; return;
} }
if (FieldType.SHADOW.Equals(e.Field.FieldType)) if (FieldType.SHADOW.Equals(e.Field.FieldType))
{ {
ChangeShadowField(); ChangeShadowField();
} }
} }
public void ChangeShadowField() public void ChangeShadowField()
{ {
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
if (shadow) if (shadow)
{ {
CheckShadow(true); CheckShadow(true);
Width = _shadowBitmap.Width; Width = _shadowBitmap.Width;
Height = _shadowBitmap.Height; Height = _shadowBitmap.Height;
Left -= _shadowOffset.X; Left -= _shadowOffset.X;
Top -= _shadowOffset.Y; Top -= _shadowOffset.Y;
} }
else else
{ {
Width = image.Width; Width = image.Width;
Height = image.Height; Height = image.Height;
if (_shadowBitmap != null) if (_shadowBitmap != null)
{ {
Left += _shadowOffset.X; Left += _shadowOffset.X;
Top += _shadowOffset.Y; Top += _shadowOffset.Y;
} }
} }
} }
public Image Image public Image Image
{ {
set set
{ {
// Remove all current bitmaps // Remove all current bitmaps
DisposeImage(); DisposeImage();
DisposeShadow(); DisposeShadow();
image = ImageHelper.Clone(value); image = ImageHelper.Clone(value);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
CheckShadow(shadow); CheckShadow(shadow);
if (!shadow) if (!shadow)
{ {
Width = image.Width; Width = image.Width;
Height = image.Height; Height = image.Height;
} }
else else
{ {
Width = _shadowBitmap.Width; Width = _shadowBitmap.Width;
Height = _shadowBitmap.Height; Height = _shadowBitmap.Height;
Left -= _shadowOffset.X; Left -= _shadowOffset.X;
Top -= _shadowOffset.Y; Top -= _shadowOffset.Y;
} }
} }
get { return image; } get { return image; }
} }
/// <summary> /// <summary>
/// The bulk of the clean-up code is implemented in Dispose(bool) /// The bulk of the clean-up code is implemented in Dispose(bool)
/// This Dispose is called from the Dispose and the Destructor. /// This Dispose is called from the Dispose and the Destructor.
/// When disposing==true all non-managed resources should be freed too! /// When disposing==true all non-managed resources should be freed too!
/// </summary> /// </summary>
/// <param name="disposing"></param> /// <param name="disposing"></param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
DisposeImage(); DisposeImage();
DisposeShadow(); DisposeShadow();
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
private void DisposeImage() private void DisposeImage()
{ {
image?.Dispose(); image?.Dispose();
image = null; image = null;
} }
private void DisposeShadow() private void DisposeShadow()
{ {
_shadowBitmap?.Dispose(); _shadowBitmap?.Dispose();
_shadowBitmap = null; _shadowBitmap = null;
} }
/// <summary> /// <summary>
/// Make sure the content is also transformed. /// Make sure the content is also transformed.
/// </summary> /// </summary>
/// <param name="matrix"></param> /// <param name="matrix"></param>
public override void Transform(Matrix matrix) public override void Transform(Matrix matrix)
{ {
int rotateAngle = CalculateAngle(matrix); int rotateAngle = CalculateAngle(matrix);
// we currently assume only one transformation has been made. // we currently assume only one transformation has been made.
if (rotateAngle != 0) if (rotateAngle != 0)
{ {
Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle); Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle);
DisposeShadow(); DisposeShadow();
using var tmpMatrix = new Matrix(); using var tmpMatrix = new Matrix();
using (image) using (image)
{ {
image = ImageHelper.ApplyEffect(image, new RotateEffect(rotateAngle), tmpMatrix); image = ImageHelper.ApplyEffect(image, new RotateEffect(rotateAngle), tmpMatrix);
} }
} }
base.Transform(matrix); base.Transform(matrix);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="filename"></param> /// <param name="filename"></param>
public void Load(string filename) public void Load(string filename)
{ {
if (!File.Exists(filename)) if (!File.Exists(filename))
{ {
return; return;
} }
// Always make sure ImageHelper.LoadBitmap results are disposed some time, // Always make sure ImageHelper.LoadBitmap results are disposed some time,
// as we close the bitmap internally, we need to do it afterwards // as we close the bitmap internally, we need to do it afterwards
using (var tmpImage = ImageHelper.LoadImage(filename)) using (var tmpImage = ImageHelper.LoadImage(filename))
{ {
Image = tmpImage; Image = tmpImage;
} }
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width); Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
} }
/// <summary> /// <summary>
/// This checks if a shadow is already generated /// This checks if a shadow is already generated
/// </summary> /// </summary>
/// <param name="shadow"></param> /// <param name="shadow"></param>
private void CheckShadow(bool shadow) private void CheckShadow(bool shadow)
{ {
if (!shadow || _shadowBitmap != null) if (!shadow || _shadowBitmap != null)
{ {
return; return;
} }
using var matrix = new Matrix(); using var matrix = new Matrix();
_shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix); _shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix);
} }
/// <summary> /// <summary>
/// Draw the actual container to the graphics object /// Draw the actual container to the graphics object
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="rm"></param> /// <param name="rm"></param>
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
if (image == null) if (image == null)
{ {
return; return;
} }
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
if (shadow) if (shadow)
{ {
CheckShadow(true); CheckShadow(true);
graphics.DrawImage(_shadowBitmap, Bounds); graphics.DrawImage(_shadowBitmap, Bounds);
} }
else else
{ {
graphics.DrawImage(image, Bounds); graphics.DrawImage(image, Bounds);
} }
} }
public override bool HasDefaultSize => true; public override bool HasDefaultSize => true;
public override Size DefaultSize => image?.Size ?? new Size(32, 32); public override Size DefaultSize => image?.Size ?? new Size(32, 32);
} }
} }

View file

@ -1,123 +1,123 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Adorners;
using Greenshot.Helpers; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Drawing.Adorners; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of LineContainer. /// Description of LineContainer.
/// </summary> /// </summary>
[Serializable()] [Serializable()]
public class LineContainer : DrawableContainer public class LineContainer : DrawableContainer
{ {
public LineContainer(Surface parent) : base(parent) public LineContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 2); AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.SHADOW, true); AddField(GetType(), FieldType.SHADOW, true);
} }
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
Init(); Init();
} }
protected void Init() protected void Init()
{ {
Adorners.Add(new MoveAdorner(this, Positions.TopLeft)); Adorners.Add(new MoveAdorner(this, Positions.TopLeft));
Adorners.Add(new MoveAdorner(this, Positions.BottomRight)); Adorners.Add(new MoveAdorner(this, Positions.BottomRight));
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
if (lineThickness > 0) if (lineThickness > 0)
{ {
if (shadow) if (shadow)
{ {
//draw shadow first //draw shadow first
int basealpha = 100; int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
int steps = 5; int steps = 5;
int currentStep = 1; int currentStep = 1;
while (currentStep <= steps) while (currentStep <= steps)
{ {
using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness); using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
graphics.DrawLine(shadowCapPen, graphics.DrawLine(shadowCapPen,
Left + currentStep, Left + currentStep,
Top + currentStep, Top + currentStep,
Left + currentStep + Width, Left + currentStep + Width,
Top + currentStep + Height); Top + currentStep + Height);
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height); graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
} }
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 5; int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 5;
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(Color.White) using Pen pen = new Pen(Color.White)
{ {
Width = lineThickness Width = lineThickness
}; };
using GraphicsPath path = new GraphicsPath(); using GraphicsPath path = new GraphicsPath();
path.AddLine(Left, Top, Left + Width, Top + Height); path.AddLine(Left, Top, Left + Width, Top + Height);
return path.IsOutlineVisible(x, y, pen); return path.IsOutlineVisible(x, y, pen);
} }
return false; return false;
} }
protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor()
{ {
return ScaleHelper.LineAngleRoundBehavior.Instance; return ScaleHelper.LineAngleRoundBehavior.Instance;
} }
} }
} }

View file

@ -1,89 +1,89 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Drawing.Filters; using Greenshot.Editor.Drawing.Filters;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of ObfuscateContainer. /// Description of ObfuscateContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class ObfuscateContainer : FilterContainer public class ObfuscateContainer : FilterContainer
{ {
public ObfuscateContainer(Surface parent) : base(parent) public ObfuscateContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
base.InitializeFields(); base.InitializeFields();
AddField(GetType(), FieldType.PREPARED_FILTER_OBFUSCATE, PreparedFilter.PIXELIZE); AddField(GetType(), FieldType.PREPARED_FILTER_OBFUSCATE, PreparedFilter.PIXELIZE);
} }
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
Init(); Init();
} }
private void Init() private void Init()
{ {
FieldChanged += ObfuscateContainer_OnFieldChanged; FieldChanged += ObfuscateContainer_OnFieldChanged;
ConfigurePreparedFilters(); ConfigurePreparedFilters();
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e)
{ {
if (sender.Equals(this)) if (sender.Equals(this))
{ {
if (Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_OBFUSCATE)) if (Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_OBFUSCATE))
{ {
ConfigurePreparedFilters(); ConfigurePreparedFilters();
} }
} }
} }
private void ConfigurePreparedFilters() private void ConfigurePreparedFilters()
{ {
PreparedFilter preset = (PreparedFilter) GetFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE); PreparedFilter preset = (PreparedFilter) GetFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE);
while (Filters.Count > 0) while (Filters.Count > 0)
{ {
Remove(Filters[0]); Remove(Filters[0]);
} }
switch (preset) switch (preset)
{ {
case PreparedFilter.BLUR: case PreparedFilter.BLUR:
Add(new BlurFilter(this)); Add(new BlurFilter(this));
break; break;
case PreparedFilter.PIXELIZE: case PreparedFilter.PIXELIZE:
Add(new PixelizationFilter(this)); Add(new PixelizationFilter(this));
break; break;
} }
} }
} }
} }

View file

@ -1,38 +1,38 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Position /// Position
/// </summary> /// </summary>
public enum Positions : int public enum Positions : int
{ {
TopLeft = 0, TopLeft = 0,
TopCenter = 1, TopCenter = 1,
TopRight = 2, TopRight = 2,
MiddleRight = 3, MiddleRight = 3,
BottomRight = 4, BottomRight = 4,
BottomCenter = 5, BottomCenter = 5,
BottomLeft = 6, BottomLeft = 6,
MiddleLeft = 7 MiddleLeft = 7
} }
} }

View file

@ -1,167 +1,167 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using Greenshot.Drawing.Fields; using System.Runtime.Serialization;
using Greenshot.Helpers; using Greenshot.Base.Interfaces.Drawing;
using System.Runtime.Serialization; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Represents a rectangular shape on the Surface /// Represents a rectangular shape on the Surface
/// </summary> /// </summary>
[Serializable] [Serializable]
public class RectangleContainer : DrawableContainer public class RectangleContainer : DrawableContainer
{ {
public RectangleContainer(Surface parent) : base(parent) public RectangleContainer(Surface parent) : base(parent)
{ {
Init(); Init();
} }
/// <summary> /// <summary>
/// Do some logic to make sure all field are initiated correctly /// Do some logic to make sure all field are initiated correctly
/// </summary> /// </summary>
/// <param name="streamingContext">StreamingContext</param> /// <param name="streamingContext">StreamingContext</param>
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 2); AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red); AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent); AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, true); AddField(GetType(), FieldType.SHADOW, true);
} }
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR, Color.Red); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR, Color.Red);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR, Color.Transparent); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR, Color.Transparent);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
DrawRectangle(rect, graphics, rm, lineThickness, lineColor, fillColor, shadow); DrawRectangle(rect, graphics, rm, lineThickness, lineColor, fillColor, shadow);
} }
/// <summary> /// <summary>
/// This method can also be used from other containers, if the right values are passed! /// This method can also be used from other containers, if the right values are passed!
/// </summary> /// </summary>
/// <param name="rect"></param> /// <param name="rect"></param>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="rm"></param> /// <param name="rm"></param>
/// <param name="lineThickness"></param> /// <param name="lineThickness"></param>
/// <param name="lineColor"></param> /// <param name="lineColor"></param>
/// <param name="fillColor"></param> /// <param name="fillColor"></param>
/// <param name="shadow"></param> /// <param name="shadow"></param>
public static void DrawRectangle(Rectangle rect, Graphics graphics, RenderMode rm, int lineThickness, Color lineColor, Color fillColor, bool shadow) public static void DrawRectangle(Rectangle rect, Graphics graphics, RenderMode rm, int lineThickness, Color lineColor, Color fillColor, bool shadow)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) if (shadow && (lineVisible || Colors.IsVisible(fillColor)))
{ {
//draw shadow first //draw shadow first
int basealpha = 100; int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
int steps = 5; int steps = 5;
int currentStep = lineVisible ? 1 : 0; int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) while (currentStep <= steps)
{ {
using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)) using Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))
{ {
Width = lineVisible ? lineThickness : 1 Width = lineVisible ? lineThickness : 1
}; };
Rectangle shadowRect = GuiRectangle.GetGuiRectangle( Rectangle shadowRect = GuiRectangle.GetGuiRectangle(
rect.Left + currentStep, rect.Left + currentStep,
rect.Top + currentStep, rect.Top + currentStep,
rect.Width, rect.Width,
rect.Height); rect.Height);
graphics.DrawRectangle(shadowPen, shadowRect); graphics.DrawRectangle(shadowPen, shadowRect);
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
if (Colors.IsVisible(fillColor)) if (Colors.IsVisible(fillColor))
{ {
using Brush brush = new SolidBrush(fillColor); using Brush brush = new SolidBrush(fillColor);
graphics.FillRectangle(brush, rect); graphics.FillRectangle(brush, rect);
} }
graphics.SmoothingMode = SmoothingMode.HighSpeed; graphics.SmoothingMode = SmoothingMode.HighSpeed;
if (lineVisible) if (lineVisible)
{ {
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
graphics.DrawRectangle(pen, rect); graphics.DrawRectangle(pen, rect);
} }
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10; int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
return RectangleClickableAt(rect, lineThickness, fillColor, x, y); return RectangleClickableAt(rect, lineThickness, fillColor, x, y);
} }
public static bool RectangleClickableAt(Rectangle rect, int lineThickness, Color fillColor, int x, int y) public static bool RectangleClickableAt(Rectangle rect, int lineThickness, Color fillColor, int x, int y)
{ {
// If we clicked inside the rectangle and it's visible we are clickable at. // If we clicked inside the rectangle and it's visible we are clickable at.
if (!Color.Transparent.Equals(fillColor)) if (!Color.Transparent.Equals(fillColor))
{ {
if (rect.Contains(x, y)) if (rect.Contains(x, y))
{ {
return true; return true;
} }
} }
// check the rest of the lines // check the rest of the lines
if (lineThickness > 0) if (lineThickness > 0)
{ {
using Pen pen = new Pen(Color.White, lineThickness); using Pen pen = new Pen(Color.White, lineThickness);
using GraphicsPath path = new GraphicsPath(); using GraphicsPath path = new GraphicsPath();
path.AddRectangle(rect); path.AddRectangle(rect);
return path.IsOutlineVisible(x, y, pen); return path.IsOutlineVisible(x, y, pen);
} }
return false; return false;
} }
} }
} }

View file

@ -1,399 +1,399 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Drawing.Fields; using System;
using Greenshot.Helpers; using System.Drawing;
using System; using System.Drawing.Drawing2D;
using System.Drawing; using System.Drawing.Text;
using System.Drawing.Drawing2D; using System.Runtime.Serialization;
using System.Drawing.Text; using Greenshot.Base.Interfaces.Drawing;
using System.Runtime.Serialization; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// Description of SpeechbubbleContainer. /// Description of SpeechbubbleContainer.
/// </summary> /// </summary>
[Serializable] [Serializable]
public class SpeechbubbleContainer : TextContainer public class SpeechbubbleContainer : TextContainer
{ {
private Point _initialGripperPoint; private Point _initialGripperPoint;
// Only used for serializing the TargetGripper location // Only used for serializing the TargetGripper location
private Point _storedTargetGripperLocation; private Point _storedTargetGripperLocation;
/// <summary> /// <summary>
/// Store the current location of the target gripper /// Store the current location of the target gripper
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
[OnSerializing] [OnSerializing]
private void SetValuesOnSerializing(StreamingContext context) private void SetValuesOnSerializing(StreamingContext context)
{ {
if (TargetAdorner != null) if (TargetAdorner != null)
{ {
_storedTargetGripperLocation = TargetAdorner.Location; _storedTargetGripperLocation = TargetAdorner.Location;
} }
} }
/// <summary> /// <summary>
/// Restore the target gripper /// Restore the target gripper
/// </summary> /// </summary>
/// <param name="streamingContext">StreamingContext</param> /// <param name="streamingContext">StreamingContext</param>
protected override void OnDeserialized(StreamingContext streamingContext) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext); base.OnDeserialized(streamingContext);
InitAdorner(Color.Green, _storedTargetGripperLocation); InitAdorner(Color.Green, _storedTargetGripperLocation);
} }
public SpeechbubbleContainer(Surface parent) public SpeechbubbleContainer(Surface parent)
: base(parent) : base(parent)
{ {
} }
/// <summary> /// <summary>
/// We set our own field values /// We set our own field values
/// </summary> /// </summary>
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.LINE_THICKNESS, 2); AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Blue); AddField(GetType(), FieldType.LINE_COLOR, Color.Blue);
AddField(GetType(), FieldType.SHADOW, false); AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.FONT_ITALIC, false); AddField(GetType(), FieldType.FONT_ITALIC, false);
AddField(GetType(), FieldType.FONT_BOLD, true); AddField(GetType(), FieldType.FONT_BOLD, true);
AddField(GetType(), FieldType.FILL_COLOR, Color.White); AddField(GetType(), FieldType.FILL_COLOR, Color.White);
AddField(GetType(), FieldType.FONT_FAMILY, FontFamily.GenericSansSerif.Name); AddField(GetType(), FieldType.FONT_FAMILY, FontFamily.GenericSansSerif.Name);
AddField(GetType(), FieldType.FONT_SIZE, 20f); AddField(GetType(), FieldType.FONT_SIZE, 20f);
AddField(GetType(), FieldType.TEXT_HORIZONTAL_ALIGNMENT, StringAlignment.Center); AddField(GetType(), FieldType.TEXT_HORIZONTAL_ALIGNMENT, StringAlignment.Center);
AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, StringAlignment.Center); AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, StringAlignment.Center);
} }
/// <summary> /// <summary>
/// Called from Surface (the _parent) when the drawing begins (mouse-down) /// Called from Surface (the _parent) when the drawing begins (mouse-down)
/// </summary> /// </summary>
/// <returns>true if the surface doesn't need to handle the event</returns> /// <returns>true if the surface doesn't need to handle the event</returns>
public override bool HandleMouseDown(int mouseX, int mouseY) public override bool HandleMouseDown(int mouseX, int mouseY)
{ {
if (TargetAdorner == null) if (TargetAdorner == null)
{ {
_initialGripperPoint = new Point(mouseX, mouseY); _initialGripperPoint = new Point(mouseX, mouseY);
InitAdorner(Color.Green, new Point(mouseX, mouseY)); InitAdorner(Color.Green, new Point(mouseX, mouseY));
} }
return base.HandleMouseDown(mouseX, mouseY); return base.HandleMouseDown(mouseX, mouseY);
} }
/// <summary> /// <summary>
/// Overriding the HandleMouseMove will help us to make sure the tail is always visible. /// Overriding the HandleMouseMove will help us to make sure the tail is always visible.
/// Should fix BUG-1682 /// Should fix BUG-1682
/// </summary> /// </summary>
/// <param name="x"></param> /// <param name="x"></param>
/// <param name="y"></param> /// <param name="y"></param>
/// <returns>base.HandleMouseMove</returns> /// <returns>base.HandleMouseMove</returns>
public override bool HandleMouseMove(int x, int y) public override bool HandleMouseMove(int x, int y)
{ {
bool returnValue = base.HandleMouseMove(x, y); bool returnValue = base.HandleMouseMove(x, y);
bool leftAligned = _boundsAfterResize.Right - _boundsAfterResize.Left >= 0; bool leftAligned = _boundsAfterResize.Right - _boundsAfterResize.Left >= 0;
bool topAligned = _boundsAfterResize.Bottom - _boundsAfterResize.Top >= 0; bool topAligned = _boundsAfterResize.Bottom - _boundsAfterResize.Top >= 0;
int xOffset = leftAligned ? -20 : 20; int xOffset = leftAligned ? -20 : 20;
int yOffset = topAligned ? -20 : 20; int yOffset = topAligned ? -20 : 20;
Point newGripperLocation = _initialGripperPoint; Point newGripperLocation = _initialGripperPoint;
newGripperLocation.Offset(xOffset, yOffset); newGripperLocation.Offset(xOffset, yOffset);
if (TargetAdorner.Location != newGripperLocation) if (TargetAdorner.Location != newGripperLocation)
{ {
Invalidate(); Invalidate();
TargetAdorner.Location = newGripperLocation; TargetAdorner.Location = newGripperLocation;
Invalidate(); Invalidate();
} }
return returnValue; return returnValue;
} }
/// <summary> /// <summary>
/// The DrawingBound should be so close as possible to the shape, so we don't invalidate to much. /// The DrawingBound should be so close as possible to the shape, so we don't invalidate to much.
/// </summary> /// </summary>
public override Rectangle DrawingBounds public override Rectangle DrawingBounds
{ {
get get
{ {
if (Status != EditStatus.UNDRAWN) if (Status != EditStatus.UNDRAWN)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
int inflateValue = lineThickness + 2 + (shadow ? 6 : 0); int inflateValue = lineThickness + 2 + (shadow ? 6 : 0);
using GraphicsPath tailPath = CreateTail(); using GraphicsPath tailPath = CreateTail();
return Rectangle.Inflate(Rectangle.Union(Rectangle.Round(tailPath.GetBounds(new Matrix(), pen)), GuiRectangle.GetGuiRectangle(Left, Top, Width, Height)), return Rectangle.Inflate(Rectangle.Union(Rectangle.Round(tailPath.GetBounds(new Matrix(), pen)), GuiRectangle.GetGuiRectangle(Left, Top, Width, Height)),
inflateValue, inflateValue); inflateValue, inflateValue);
} }
return Rectangle.Empty; return Rectangle.Empty;
} }
} }
/// <summary> /// <summary>
/// Helper method to create the bubble GraphicsPath, so we can also calculate the bounds /// Helper method to create the bubble GraphicsPath, so we can also calculate the bounds
/// </summary> /// </summary>
/// <param name="lineThickness"></param> /// <param name="lineThickness"></param>
/// <returns></returns> /// <returns></returns>
private GraphicsPath CreateBubble(int lineThickness) private GraphicsPath CreateBubble(int lineThickness)
{ {
GraphicsPath bubble = new GraphicsPath(); GraphicsPath bubble = new GraphicsPath();
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
Rectangle bubbleRect = GuiRectangle.GetGuiRectangle(0, 0, rect.Width, rect.Height); Rectangle bubbleRect = GuiRectangle.GetGuiRectangle(0, 0, rect.Width, rect.Height);
// adapt corner radius to small rectangle dimensions // adapt corner radius to small rectangle dimensions
int smallerSideLength = Math.Min(bubbleRect.Width, bubbleRect.Height); int smallerSideLength = Math.Min(bubbleRect.Width, bubbleRect.Height);
int cornerRadius = Math.Min(30, smallerSideLength / 2 - lineThickness); int cornerRadius = Math.Min(30, smallerSideLength / 2 - lineThickness);
if (cornerRadius > 0) if (cornerRadius > 0)
{ {
bubble.AddArc(bubbleRect.X, bubbleRect.Y, cornerRadius, cornerRadius, 180, 90); bubble.AddArc(bubbleRect.X, bubbleRect.Y, cornerRadius, cornerRadius, 180, 90);
bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y, cornerRadius, cornerRadius, 270, 90); bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y, cornerRadius, cornerRadius, 270, 90);
bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90); bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90);
bubble.AddArc(bubbleRect.X, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90); bubble.AddArc(bubbleRect.X, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90);
} }
else else
{ {
bubble.AddRectangle(bubbleRect); bubble.AddRectangle(bubbleRect);
} }
bubble.CloseAllFigures(); bubble.CloseAllFigures();
using (Matrix bubbleMatrix = new Matrix()) using (Matrix bubbleMatrix = new Matrix())
{ {
bubbleMatrix.Translate(rect.Left, rect.Top); bubbleMatrix.Translate(rect.Left, rect.Top);
bubble.Transform(bubbleMatrix); bubble.Transform(bubbleMatrix);
} }
return bubble; return bubble;
} }
/// <summary> /// <summary>
/// Helper method to create the tail of the bubble, so we can also calculate the bounds /// Helper method to create the tail of the bubble, so we can also calculate the bounds
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private GraphicsPath CreateTail() private GraphicsPath CreateTail()
{ {
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetAdorner.Location.X, TargetAdorner.Location.Y); int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetAdorner.Location.X, TargetAdorner.Location.Y);
int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20; int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
// This should fix a problem with the tail being to wide // This should fix a problem with the tail being to wide
tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth); tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth);
tailWidth = Math.Min(Math.Abs(rect.Height) / 2, tailWidth); tailWidth = Math.Min(Math.Abs(rect.Height) / 2, tailWidth);
GraphicsPath tail = new GraphicsPath(); GraphicsPath tail = new GraphicsPath();
tail.AddLine(-tailWidth, 0, tailWidth, 0); tail.AddLine(-tailWidth, 0, tailWidth, 0);
tail.AddLine(tailWidth, 0, 0, -tailLength); tail.AddLine(tailWidth, 0, 0, -tailLength);
tail.CloseFigure(); tail.CloseFigure();
int tailAngle = 90 + (int) GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetAdorner.Location.X, TargetAdorner.Location.Y); int tailAngle = 90 + (int) GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetAdorner.Location.X, TargetAdorner.Location.Y);
using (Matrix tailMatrix = new Matrix()) using (Matrix tailMatrix = new Matrix())
{ {
tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);
tailMatrix.Rotate(tailAngle); tailMatrix.Rotate(tailAngle);
tail.Transform(tailMatrix); tail.Transform(tailMatrix);
} }
return tail; return tail;
} }
/// <summary> /// <summary>
/// This is to draw the actual container /// This is to draw the actual container
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="renderMode"></param> /// <param name="renderMode"></param>
public override void Draw(Graphics graphics, RenderMode renderMode) public override void Draw(Graphics graphics, RenderMode renderMode)
{ {
if (TargetAdorner == null) if (TargetAdorner == null)
{ {
return; return;
} }
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW); bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor); bool lineVisible = lineThickness > 0 && Colors.IsVisible(lineColor);
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
if (Selected && renderMode == RenderMode.EDIT) if (Selected && renderMode == RenderMode.EDIT)
{ {
DrawSelectionBorder(graphics, rect); DrawSelectionBorder(graphics, rect);
} }
GraphicsPath bubble = CreateBubble(lineThickness); GraphicsPath bubble = CreateBubble(lineThickness);
GraphicsPath tail = CreateTail(); GraphicsPath tail = CreateTail();
//draw shadow first //draw shadow first
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) if (shadow && (lineVisible || Colors.IsVisible(fillColor)))
{ {
const int basealpha = 100; const int basealpha = 100;
int alpha = basealpha; int alpha = basealpha;
const int steps = 5; const int steps = 5;
int currentStep = lineVisible ? 1 : 0; int currentStep = lineVisible ? 1 : 0;
using Matrix shadowMatrix = new Matrix(); using Matrix shadowMatrix = new Matrix();
using GraphicsPath bubbleClone = (GraphicsPath) bubble.Clone(); using GraphicsPath bubbleClone = (GraphicsPath) bubble.Clone();
using GraphicsPath tailClone = (GraphicsPath) tail.Clone(); using GraphicsPath tailClone = (GraphicsPath) tail.Clone();
shadowMatrix.Translate(1, 1); shadowMatrix.Translate(1, 1);
while (currentStep <= steps) while (currentStep <= steps)
{ {
using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100)))
{ {
shadowPen.Width = lineVisible ? lineThickness : 1; shadowPen.Width = lineVisible ? lineThickness : 1;
tailClone.Transform(shadowMatrix); tailClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, tailClone); graphics.DrawPath(shadowPen, tailClone);
bubbleClone.Transform(shadowMatrix); bubbleClone.Transform(shadowMatrix);
graphics.DrawPath(shadowPen, bubbleClone); graphics.DrawPath(shadowPen, bubbleClone);
} }
currentStep++; currentStep++;
alpha -= basealpha / steps; alpha -= basealpha / steps;
} }
} }
GraphicsState state = graphics.Save(); GraphicsState state = graphics.Save();
// draw the tail border where the bubble is not visible // draw the tail border where the bubble is not visible
using (Region clipRegion = new Region(bubble)) using (Region clipRegion = new Region(bubble))
{ {
graphics.SetClip(clipRegion, CombineMode.Exclude); graphics.SetClip(clipRegion, CombineMode.Exclude);
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
graphics.DrawPath(pen, tail); graphics.DrawPath(pen, tail);
} }
graphics.Restore(state); graphics.Restore(state);
if (Colors.IsVisible(fillColor)) if (Colors.IsVisible(fillColor))
{ {
//draw the bubbleshape //draw the bubbleshape
state = graphics.Save(); state = graphics.Save();
using (Brush brush = new SolidBrush(fillColor)) using (Brush brush = new SolidBrush(fillColor))
{ {
graphics.FillPath(brush, bubble); graphics.FillPath(brush, bubble);
} }
graphics.Restore(state); graphics.Restore(state);
} }
if (lineVisible) if (lineVisible)
{ {
//draw the bubble border //draw the bubble border
state = graphics.Save(); state = graphics.Save();
// Draw bubble where the Tail is not visible. // Draw bubble where the Tail is not visible.
using (Region clipRegion = new Region(tail)) using (Region clipRegion = new Region(tail))
{ {
graphics.SetClip(clipRegion, CombineMode.Exclude); graphics.SetClip(clipRegion, CombineMode.Exclude);
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
//pen.EndCap = pen.StartCap = LineCap.Round; //pen.EndCap = pen.StartCap = LineCap.Round;
graphics.DrawPath(pen, bubble); graphics.DrawPath(pen, bubble);
} }
graphics.Restore(state); graphics.Restore(state);
} }
if (Colors.IsVisible(fillColor)) if (Colors.IsVisible(fillColor))
{ {
// Draw the tail border // Draw the tail border
state = graphics.Save(); state = graphics.Save();
using (Brush brush = new SolidBrush(fillColor)) using (Brush brush = new SolidBrush(fillColor))
{ {
graphics.FillPath(brush, tail); graphics.FillPath(brush, tail);
} }
graphics.Restore(state); graphics.Restore(state);
} }
// cleanup the paths // cleanup the paths
bubble.Dispose(); bubble.Dispose();
tail.Dispose(); tail.Dispose();
// Draw the text // Draw the text
DrawText(graphics, rect, lineThickness, lineColor, shadow, StringFormat, Text, Font); DrawText(graphics, rect, lineThickness, lineColor, shadow, StringFormat, Text, Font);
} }
public override bool Contains(int x, int y) public override bool Contains(int x, int y)
{ {
if (base.Contains(x, y)) if (base.Contains(x, y))
{ {
return true; return true;
} }
Point clickedPoint = new Point(x, y); Point clickedPoint = new Point(x, y);
if (Status != EditStatus.UNDRAWN) if (Status != EditStatus.UNDRAWN)
{ {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
using Pen pen = new Pen(lineColor, lineThickness); using Pen pen = new Pen(lineColor, lineThickness);
using (GraphicsPath bubblePath = CreateBubble(lineThickness)) using (GraphicsPath bubblePath = CreateBubble(lineThickness))
{ {
bubblePath.Widen(pen); bubblePath.Widen(pen);
if (bubblePath.IsVisible(clickedPoint)) if (bubblePath.IsVisible(clickedPoint))
{ {
return true; return true;
} }
} }
using GraphicsPath tailPath = CreateTail(); using GraphicsPath tailPath = CreateTail();
tailPath.Widen(pen); tailPath.Widen(pen);
if (tailPath.IsVisible(clickedPoint)) if (tailPath.IsVisible(clickedPoint))
{ {
return true; return true;
} }
} }
return false; return false;
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
return Contains(x, y); return Contains(x, y);
} }
/// <summary> /// <summary>
/// Additional to the Transform of the TextContainer the bubble tail coordinates also need to be moved /// Additional to the Transform of the TextContainer the bubble tail coordinates also need to be moved
/// </summary> /// </summary>
/// <param name="matrix">Matrix</param> /// <param name="matrix">Matrix</param>
public override void Transform(Matrix matrix) public override void Transform(Matrix matrix)
{ {
Point[] points = Point[] points =
{ {
TargetAdorner.Location TargetAdorner.Location
}; };
matrix.TransformPoints(points); matrix.TransformPoints(points);
TargetAdorner.Location = points[0]; TargetAdorner.Location = points[0];
base.Transform(matrix); base.Transform(matrix);
} }
} }
} }

View file

@ -1,225 +1,225 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Drawing.Fields; using System;
using Greenshot.Helpers; using System.Drawing;
using System; using System.Drawing.Drawing2D;
using System.Drawing; using System.Drawing.Text;
using System.Drawing.Drawing2D; using System.Runtime.Serialization;
using System.Drawing.Text; using Greenshot.Base.Interfaces.Drawing;
using System.Runtime.Serialization; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Helpers;
namespace Greenshot.Drawing namespace Greenshot.Editor.Drawing
{ {
/// <summary> /// <summary>
/// This is an enumerated label, every single StepLabelContainer shows the number of the order it was created. /// This is an enumerated label, every single StepLabelContainer shows the number of the order it was created.
/// To make sure that deleting recalculates, we check the location before every draw. /// To make sure that deleting recalculates, we check the location before every draw.
/// </summary> /// </summary>
[Serializable] [Serializable]
public sealed class StepLabelContainer : DrawableContainer public sealed class StepLabelContainer : DrawableContainer
{ {
[NonSerialized] private StringFormat _stringFormat = new StringFormat(); [NonSerialized] private StringFormat _stringFormat = new StringFormat();
private readonly bool _drawAsRectangle = false; private readonly bool _drawAsRectangle = false;
public StepLabelContainer(Surface parent) : base(parent) public StepLabelContainer(Surface parent) : base(parent)
{ {
parent.AddStepLabel(this); parent.AddStepLabel(this);
InitContent(); InitContent();
Init(); Init();
} }
private void Init() private void Init()
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
} }
// Used to store the number of this label, so when deserializing it can be placed back to the StepLabels list in the right location // Used to store the number of this label, so when deserializing it can be placed back to the StepLabels list in the right location
private int _number; private int _number;
// Used to store the counter start of the Surface, as the surface is NOT stored. // Used to store the counter start of the Surface, as the surface is NOT stored.
private int _counterStart = 1; private int _counterStart = 1;
public int Number public int Number
{ {
get { return _number; } get { return _number; }
set { _number = value; } set { _number = value; }
} }
/// <summary> /// <summary>
/// Retrieve the counter before serializing /// Retrieve the counter before serializing
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
[OnSerializing] [OnSerializing]
private void SetValuesOnSerializing(StreamingContext context) private void SetValuesOnSerializing(StreamingContext context)
{ {
if (Parent != null) if (Parent != null)
{ {
Number = ((Surface) Parent).CountStepLabels(this); Number = ((Surface) Parent).CountStepLabels(this);
_counterStart = ((Surface) Parent).CounterStart; _counterStart = ((Surface) Parent).CounterStart;
} }
} }
/// <summary> /// <summary>
/// Restore values that don't serialize /// Restore values that don't serialize
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
Init(); Init();
_stringFormat = new StringFormat _stringFormat = new StringFormat
{ {
Alignment = StringAlignment.Center, Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center LineAlignment = StringAlignment.Center
}; };
} }
/// <summary> /// <summary>
/// Add the StepLabel to the parent /// Add the StepLabel to the parent
/// </summary> /// </summary>
/// <param name="newParent"></param> /// <param name="newParent"></param>
protected override void SwitchParent(Surface newParent) protected override void SwitchParent(Surface newParent)
{ {
if (newParent == Parent) if (newParent == Parent)
{ {
return; return;
} }
((Surface) Parent)?.RemoveStepLabel(this); ((Surface) Parent)?.RemoveStepLabel(this);
base.SwitchParent(newParent); base.SwitchParent(newParent);
if (newParent == null) if (newParent == null)
{ {
return; return;
} }
// Make sure the counter start is restored (this unfortunately happens multiple times... -> hack) // Make sure the counter start is restored (this unfortunately happens multiple times... -> hack)
newParent.CounterStart = _counterStart; newParent.CounterStart = _counterStart;
newParent.AddStepLabel(this); newParent.AddStepLabel(this);
} }
public override Size DefaultSize => new Size(30, 30); public override Size DefaultSize => new Size(30, 30);
public override bool InitContent() public override bool InitContent()
{ {
_defaultEditMode = EditStatus.IDLE; _defaultEditMode = EditStatus.IDLE;
_stringFormat.Alignment = StringAlignment.Center; _stringFormat.Alignment = StringAlignment.Center;
_stringFormat.LineAlignment = StringAlignment.Center; _stringFormat.LineAlignment = StringAlignment.Center;
// Set defaults // Set defaults
Width = DefaultSize.Width; Width = DefaultSize.Width;
Height = DefaultSize.Height; Height = DefaultSize.Height;
return true; return true;
} }
/// <summary> /// <summary>
/// This makes it possible for the label to be placed exactly in the middle of the pointer. /// This makes it possible for the label to be placed exactly in the middle of the pointer.
/// </summary> /// </summary>
public override bool HandleMouseDown(int mouseX, int mouseY) public override bool HandleMouseDown(int mouseX, int mouseY)
{ {
return base.HandleMouseDown(mouseX - Width / 2, mouseY - Height / 2); return base.HandleMouseDown(mouseX - Width / 2, mouseY - Height / 2);
} }
/// <summary> /// <summary>
/// We set our own field values /// We set our own field values
/// </summary> /// </summary>
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.FILL_COLOR, Color.DarkRed); AddField(GetType(), FieldType.FILL_COLOR, Color.DarkRed);
AddField(GetType(), FieldType.LINE_COLOR, Color.White); AddField(GetType(), FieldType.LINE_COLOR, Color.White);
AddField(GetType(), FieldType.FLAGS, FieldFlag.COUNTER); AddField(GetType(), FieldType.FLAGS, FieldFlag.COUNTER);
} }
/// <summary> /// <summary>
/// Make sure this element is no longer referenced from the surface /// Make sure this element is no longer referenced from the surface
/// </summary> /// </summary>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
base.Dispose(disposing); base.Dispose(disposing);
if (!disposing) if (!disposing)
{ {
return; return;
} }
((Surface) Parent)?.RemoveStepLabel(this); ((Surface) Parent)?.RemoveStepLabel(this);
if (_stringFormat == null) if (_stringFormat == null)
{ {
return; return;
} }
_stringFormat.Dispose(); _stringFormat.Dispose();
_stringFormat = null; _stringFormat = null;
} }
public override bool HandleMouseMove(int x, int y) public override bool HandleMouseMove(int x, int y)
{ {
Invalidate(); Invalidate();
Left = x - Width / 2; Left = x - Width / 2;
Top = y - Height / 2; Top = y - Height / 2;
Invalidate(); Invalidate();
return true; return true;
} }
/// <summary> /// <summary>
/// Override the parent, calculate the label number, than draw /// Override the parent, calculate the label number, than draw
/// </summary> /// </summary>
/// <param name="graphics"></param> /// <param name="graphics"></param>
/// <param name="rm"></param> /// <param name="rm"></param>
public override void Draw(Graphics graphics, RenderMode rm) public override void Draw(Graphics graphics, RenderMode rm)
{ {
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.None; graphics.PixelOffsetMode = PixelOffsetMode.None;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
string text = ((Surface) Parent).CountStepLabels(this).ToString(); string text = ((Surface) Parent).CountStepLabels(this).ToString();
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
if (_drawAsRectangle) if (_drawAsRectangle)
{ {
RectangleContainer.DrawRectangle(rect, graphics, rm, 0, Color.Transparent, fillColor, false); RectangleContainer.DrawRectangle(rect, graphics, rm, 0, Color.Transparent, fillColor, false);
} }
else else
{ {
EllipseContainer.DrawEllipse(rect, graphics, rm, 0, Color.Transparent, fillColor, false); EllipseContainer.DrawEllipse(rect, graphics, rm, 0, Color.Transparent, fillColor, false);
} }
float fontSize = Math.Min(Width, Height) / 1.4f; float fontSize = Math.Min(Width, Height) / 1.4f;
using FontFamily fam = new FontFamily(FontFamily.GenericSansSerif.Name); using FontFamily fam = new FontFamily(FontFamily.GenericSansSerif.Name);
using Font font = new Font(fam, fontSize, FontStyle.Bold, GraphicsUnit.Pixel); using Font font = new Font(fam, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font); TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font);
} }
public override bool ClickableAt(int x, int y) public override bool ClickableAt(int x, int y)
{ {
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
if (_drawAsRectangle) if (_drawAsRectangle)
{ {
return RectangleContainer.RectangleClickableAt(rect, 0, fillColor, x, y); return RectangleContainer.RectangleClickableAt(rect, 0, fillColor, x, y);
} }
return EllipseContainer.EllipseClickableAt(rect, 0, fillColor, x, y); return EllipseContainer.EllipseClickableAt(rect, 0, fillColor, x, y);
} }
} }
} }

View file

@ -1,287 +1,288 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
using Greenshot.Editor.Controls;
namespace Greenshot.Forms {
public partial class ColorDialog { namespace Greenshot.Editor.Forms {
/// <summary> public partial class ColorDialog {
/// Designer variable used to keep track of non-visual components. /// <summary>
/// </summary> /// Designer variable used to keep track of non-visual components.
private System.ComponentModel.IContainer components = null; /// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form. /// <summary>
/// </summary> /// Disposes resources used by the form.
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// </summary>
protected override void Dispose(bool disposing) /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
{ protected override void Dispose(bool disposing)
if (disposing) { {
if (components != null) { if (disposing) {
components.Dispose(); if (components != null) {
} components.Dispose();
} }
base.Dispose(disposing); }
} base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support. /// <summary>
/// Do not change the method contents inside the source code editor. The Forms designer might /// This method is required for Windows Forms designer support.
/// not be able to load this method if it was changed manually. /// Do not change the method contents inside the source code editor. The Forms designer might
/// </summary> /// not be able to load this method if it was changed manually.
private void InitializeComponent() /// </summary>
{ private void InitializeComponent()
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ColorDialog)); {
this.btnTransparent = new GreenshotButton(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ColorDialog));
this.colorPanel = new System.Windows.Forms.Panel(); this.btnTransparent = new GreenshotButton();
this.labelHtmlColor = new GreenshotLabel(); this.colorPanel = new System.Windows.Forms.Panel();
this.textBoxHtmlColor = new System.Windows.Forms.TextBox(); this.labelHtmlColor = new GreenshotLabel();
this.labelRed = new GreenshotLabel(); this.textBoxHtmlColor = new System.Windows.Forms.TextBox();
this.labelGreen = new GreenshotLabel(); this.labelRed = new GreenshotLabel();
this.labelBlue = new GreenshotLabel(); this.labelGreen = new GreenshotLabel();
this.textBoxRed = new System.Windows.Forms.TextBox(); this.labelBlue = new GreenshotLabel();
this.textBoxGreen = new System.Windows.Forms.TextBox(); this.textBoxRed = new System.Windows.Forms.TextBox();
this.textBoxBlue = new System.Windows.Forms.TextBox(); this.textBoxGreen = new System.Windows.Forms.TextBox();
this.labelRecentColors = new GreenshotLabel(); this.textBoxBlue = new System.Windows.Forms.TextBox();
this.textBoxAlpha = new System.Windows.Forms.TextBox(); this.labelRecentColors = new GreenshotLabel();
this.labelAlpha = new GreenshotLabel(); this.textBoxAlpha = new System.Windows.Forms.TextBox();
this.btnApply = new GreenshotButton(); this.labelAlpha = new GreenshotLabel();
this.pipette = new Greenshot.Controls.Pipette(); this.btnApply = new GreenshotButton();
this.SuspendLayout(); this.pipette = new Pipette();
// this.SuspendLayout();
// btnTransparent //
// // btnTransparent
this.btnTransparent.BackColor = System.Drawing.Color.Transparent; //
this.btnTransparent.LanguageKey = "colorpicker_transparent"; this.btnTransparent.BackColor = System.Drawing.Color.Transparent;
this.btnTransparent.Location = new System.Drawing.Point(210, 4); this.btnTransparent.LanguageKey = "colorpicker_transparent";
this.btnTransparent.Name = "btnTransparent"; this.btnTransparent.Location = new System.Drawing.Point(210, 4);
this.btnTransparent.Size = new System.Drawing.Size(78, 23); this.btnTransparent.Name = "btnTransparent";
this.btnTransparent.TabIndex = 0; this.btnTransparent.Size = new System.Drawing.Size(78, 23);
this.btnTransparent.TabStop = false; this.btnTransparent.TabIndex = 0;
this.btnTransparent.Text = "Transparent"; this.btnTransparent.TabStop = false;
this.btnTransparent.UseVisualStyleBackColor = false; this.btnTransparent.Text = "Transparent";
this.btnTransparent.Click += new System.EventHandler(this.BtnTransparentClick); this.btnTransparent.UseVisualStyleBackColor = false;
// this.btnTransparent.Click += new System.EventHandler(this.BtnTransparentClick);
// colorPanel //
// // colorPanel
this.colorPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; //
this.colorPanel.Location = new System.Drawing.Point(213, 30); this.colorPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.colorPanel.Name = "colorPanel"; this.colorPanel.Location = new System.Drawing.Point(213, 30);
this.colorPanel.Size = new System.Drawing.Size(33, 23); this.colorPanel.Name = "colorPanel";
this.colorPanel.TabIndex = 1; this.colorPanel.Size = new System.Drawing.Size(33, 23);
// this.colorPanel.TabIndex = 1;
// labelHtmlColor //
// // labelHtmlColor
this.labelHtmlColor.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); //
this.labelHtmlColor.LanguageKey = "colorpicker_htmlcolor"; this.labelHtmlColor.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelHtmlColor.Location = new System.Drawing.Point(210, 57); this.labelHtmlColor.LanguageKey = "colorpicker_htmlcolor";
this.labelHtmlColor.Name = "labelHtmlColor"; this.labelHtmlColor.Location = new System.Drawing.Point(210, 57);
this.labelHtmlColor.Size = new System.Drawing.Size(78, 17); this.labelHtmlColor.Name = "labelHtmlColor";
this.labelHtmlColor.TabIndex = 2; this.labelHtmlColor.Size = new System.Drawing.Size(78, 17);
this.labelHtmlColor.Text = "HTML color"; this.labelHtmlColor.TabIndex = 2;
// this.labelHtmlColor.Text = "HTML color";
// textBoxHtmlColor //
// // textBoxHtmlColor
this.textBoxHtmlColor.Location = new System.Drawing.Point(210, 71); //
this.textBoxHtmlColor.Name = "textBoxHtmlColor"; this.textBoxHtmlColor.Location = new System.Drawing.Point(210, 71);
this.textBoxHtmlColor.Size = new System.Drawing.Size(78, 20); this.textBoxHtmlColor.Name = "textBoxHtmlColor";
this.textBoxHtmlColor.TabIndex = 1; this.textBoxHtmlColor.Size = new System.Drawing.Size(78, 20);
this.textBoxHtmlColor.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxHtmlColor.TabIndex = 1;
this.textBoxHtmlColor.TextChanged += new System.EventHandler(this.TextBoxHexadecimalTextChanged); this.textBoxHtmlColor.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxHtmlColor.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxHtmlColor.TextChanged += new System.EventHandler(this.TextBoxHexadecimalTextChanged);
this.textBoxHtmlColor.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxHtmlColor.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
// this.textBoxHtmlColor.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// labelRed //
// // labelRed
this.labelRed.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); //
this.labelRed.LanguageKey = "colorpicker_red"; this.labelRed.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelRed.Location = new System.Drawing.Point(210, 98); this.labelRed.LanguageKey = "colorpicker_red";
this.labelRed.Name = "labelRed"; this.labelRed.Location = new System.Drawing.Point(210, 98);
this.labelRed.Size = new System.Drawing.Size(78, 18); this.labelRed.Name = "labelRed";
this.labelRed.TabIndex = 4; this.labelRed.Size = new System.Drawing.Size(78, 18);
this.labelRed.Text = "Red"; this.labelRed.TabIndex = 4;
// this.labelRed.Text = "Red";
// labelGreen //
// // labelGreen
this.labelGreen.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); //
this.labelGreen.LanguageKey = "colorpicker_green"; this.labelGreen.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelGreen.Location = new System.Drawing.Point(210, 122); this.labelGreen.LanguageKey = "colorpicker_green";
this.labelGreen.Name = "labelGreen"; this.labelGreen.Location = new System.Drawing.Point(210, 122);
this.labelGreen.Size = new System.Drawing.Size(78, 18); this.labelGreen.Name = "labelGreen";
this.labelGreen.TabIndex = 5; this.labelGreen.Size = new System.Drawing.Size(78, 18);
this.labelGreen.Text = "Green"; this.labelGreen.TabIndex = 5;
// this.labelGreen.Text = "Green";
// labelBlue //
// // labelBlue
this.labelBlue.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); //
this.labelBlue.LanguageKey = "colorpicker_blue"; this.labelBlue.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelBlue.Location = new System.Drawing.Point(210, 146); this.labelBlue.LanguageKey = "colorpicker_blue";
this.labelBlue.Name = "labelBlue"; this.labelBlue.Location = new System.Drawing.Point(210, 146);
this.labelBlue.Size = new System.Drawing.Size(78, 18); this.labelBlue.Name = "labelBlue";
this.labelBlue.TabIndex = 6; this.labelBlue.Size = new System.Drawing.Size(78, 18);
this.labelBlue.Text = "Blue"; this.labelBlue.TabIndex = 6;
// this.labelBlue.Text = "Blue";
// textBoxRed //
// // textBoxRed
this.textBoxRed.Location = new System.Drawing.Point(258, 95); //
this.textBoxRed.Name = "textBoxRed"; this.textBoxRed.Location = new System.Drawing.Point(258, 95);
this.textBoxRed.Size = new System.Drawing.Size(30, 20); this.textBoxRed.Name = "textBoxRed";
this.textBoxRed.TabIndex = 2; this.textBoxRed.Size = new System.Drawing.Size(30, 20);
this.textBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxRed.TabIndex = 2;
this.textBoxRed.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxRed.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged); this.textBoxRed.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxRed.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxRed.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxRed.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxRed.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
// this.textBoxRed.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// textBoxGreen //
// // textBoxGreen
this.textBoxGreen.Location = new System.Drawing.Point(258, 119); //
this.textBoxGreen.Name = "textBoxGreen"; this.textBoxGreen.Location = new System.Drawing.Point(258, 119);
this.textBoxGreen.Size = new System.Drawing.Size(30, 20); this.textBoxGreen.Name = "textBoxGreen";
this.textBoxGreen.TabIndex = 3; this.textBoxGreen.Size = new System.Drawing.Size(30, 20);
this.textBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxGreen.TabIndex = 3;
this.textBoxGreen.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxGreen.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged); this.textBoxGreen.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxGreen.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxGreen.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxGreen.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxGreen.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
// this.textBoxGreen.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// textBoxBlue //
// // textBoxBlue
this.textBoxBlue.Location = new System.Drawing.Point(258, 143); //
this.textBoxBlue.Name = "textBoxBlue"; this.textBoxBlue.Location = new System.Drawing.Point(258, 143);
this.textBoxBlue.Size = new System.Drawing.Size(30, 20); this.textBoxBlue.Name = "textBoxBlue";
this.textBoxBlue.TabIndex = 4; this.textBoxBlue.Size = new System.Drawing.Size(30, 20);
this.textBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxBlue.TabIndex = 4;
this.textBoxBlue.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxBlue.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged); this.textBoxBlue.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxBlue.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxBlue.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxBlue.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxBlue.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
// this.textBoxBlue.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// labelRecentColors //
// // labelRecentColors
this.labelRecentColors.LanguageKey = "colorpicker_recentcolors"; //
this.labelRecentColors.Location = new System.Drawing.Point(3, 175); this.labelRecentColors.LanguageKey = "colorpicker_recentcolors";
this.labelRecentColors.Name = "labelRecentColors"; this.labelRecentColors.Location = new System.Drawing.Point(3, 175);
this.labelRecentColors.Size = new System.Drawing.Size(148, 13); this.labelRecentColors.Name = "labelRecentColors";
this.labelRecentColors.TabIndex = 10; this.labelRecentColors.Size = new System.Drawing.Size(148, 13);
this.labelRecentColors.Text = "Recently used colors"; this.labelRecentColors.TabIndex = 10;
// this.labelRecentColors.Text = "Recently used colors";
// textBoxAlpha //
// // textBoxAlpha
this.textBoxAlpha.Location = new System.Drawing.Point(258, 167); //
this.textBoxAlpha.Name = "textBoxAlpha"; this.textBoxAlpha.Location = new System.Drawing.Point(258, 167);
this.textBoxAlpha.Size = new System.Drawing.Size(30, 20); this.textBoxAlpha.Name = "textBoxAlpha";
this.textBoxAlpha.TabIndex = 5; this.textBoxAlpha.Size = new System.Drawing.Size(30, 20);
this.textBoxAlpha.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxAlpha.TabIndex = 5;
this.textBoxAlpha.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxAlpha.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxAlpha.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged); this.textBoxAlpha.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxAlpha.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxAlpha.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxAlpha.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxAlpha.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
// this.textBoxAlpha.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// labelAlpha //
// // labelAlpha
this.labelAlpha.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); //
this.labelAlpha.LanguageKey = "colorpicker_alpha"; this.labelAlpha.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelAlpha.Location = new System.Drawing.Point(210, 170); this.labelAlpha.LanguageKey = "colorpicker_alpha";
this.labelAlpha.Name = "labelAlpha"; this.labelAlpha.Location = new System.Drawing.Point(210, 170);
this.labelAlpha.Size = new System.Drawing.Size(78, 18); this.labelAlpha.Name = "labelAlpha";
this.labelAlpha.TabIndex = 11; this.labelAlpha.Size = new System.Drawing.Size(78, 18);
this.labelAlpha.Text = "Alpha"; this.labelAlpha.TabIndex = 11;
// this.labelAlpha.Text = "Alpha";
// btnApply //
// // btnApply
this.btnApply.BackColor = System.Drawing.Color.Transparent; //
this.btnApply.LanguageKey = "colorpicker_apply"; this.btnApply.BackColor = System.Drawing.Color.Transparent;
this.btnApply.Location = new System.Drawing.Point(210, 191); this.btnApply.LanguageKey = "colorpicker_apply";
this.btnApply.Name = "btnApply"; this.btnApply.Location = new System.Drawing.Point(210, 191);
this.btnApply.Size = new System.Drawing.Size(78, 23); this.btnApply.Name = "btnApply";
this.btnApply.TabIndex = 12; this.btnApply.Size = new System.Drawing.Size(78, 23);
this.btnApply.TabStop = false; this.btnApply.TabIndex = 12;
this.btnApply.Text = "Apply"; this.btnApply.TabStop = false;
this.btnApply.UseVisualStyleBackColor = false; this.btnApply.Text = "Apply";
this.btnApply.Click += new System.EventHandler(this.BtnApplyClick); this.btnApply.UseVisualStyleBackColor = false;
// this.btnApply.Click += new System.EventHandler(this.BtnApplyClick);
// pipette //
// // pipette
this.pipette.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; //
this.pipette.Cursor = System.Windows.Forms.Cursors.Arrow; this.pipette.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pipette.Image = ((System.Drawing.Image)(resources.GetObject("pipette.Image"))); this.pipette.Cursor = System.Windows.Forms.Cursors.Arrow;
this.pipette.Location = new System.Drawing.Point(255, 30); this.pipette.Image = ((System.Drawing.Image)(resources.GetObject("pipette.Image")));
this.pipette.Name = "pipette"; this.pipette.Location = new System.Drawing.Point(255, 30);
this.pipette.Size = new System.Drawing.Size(33, 23); this.pipette.Name = "pipette";
this.pipette.TabIndex = 13; this.pipette.Size = new System.Drawing.Size(33, 23);
this.pipette.PipetteUsed += new System.EventHandler<Greenshot.Controls.PipetteUsedArgs>(this.PipetteUsed); this.pipette.TabIndex = 13;
// this.pipette.PipetteUsed += new System.EventHandler<PipetteUsedArgs>(this.PipetteUsed);
// ColorDialog //
// // ColorDialog
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.ClientSize = new System.Drawing.Size(292, 218); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.pipette); this.ClientSize = new System.Drawing.Size(292, 218);
this.Controls.Add(this.btnApply); this.Controls.Add(this.pipette);
this.Controls.Add(this.textBoxAlpha); this.Controls.Add(this.btnApply);
this.Controls.Add(this.labelAlpha); this.Controls.Add(this.textBoxAlpha);
this.Controls.Add(this.labelRecentColors); this.Controls.Add(this.labelAlpha);
this.Controls.Add(this.textBoxBlue); this.Controls.Add(this.labelRecentColors);
this.Controls.Add(this.textBoxGreen); this.Controls.Add(this.textBoxBlue);
this.Controls.Add(this.textBoxRed); this.Controls.Add(this.textBoxGreen);
this.Controls.Add(this.labelBlue); this.Controls.Add(this.textBoxRed);
this.Controls.Add(this.labelGreen); this.Controls.Add(this.labelBlue);
this.Controls.Add(this.labelRed); this.Controls.Add(this.labelGreen);
this.Controls.Add(this.textBoxHtmlColor); this.Controls.Add(this.labelRed);
this.Controls.Add(this.labelHtmlColor); this.Controls.Add(this.textBoxHtmlColor);
this.Controls.Add(this.colorPanel); this.Controls.Add(this.labelHtmlColor);
this.Controls.Add(this.btnTransparent); this.Controls.Add(this.colorPanel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Controls.Add(this.btnTransparent);
this.LanguageKey = "colorpicker_title"; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false; this.LanguageKey = "colorpicker_title";
this.MinimizeBox = false; this.MaximizeBox = false;
this.Name = "ColorDialog"; this.MinimizeBox = false;
this.ShowIcon = false; this.Name = "ColorDialog";
this.ShowInTaskbar = false; this.ShowIcon = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.ShowInTaskbar = false;
this.Text = "Color picker"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.ResumeLayout(false); this.Text = "Color picker";
this.PerformLayout(); this.ResumeLayout(false);
this.PerformLayout();
}
private GreenshotLabel labelRed; }
private GreenshotLabel labelGreen; private GreenshotLabel labelRed;
private GreenshotLabel labelBlue; private GreenshotLabel labelGreen;
private System.Windows.Forms.TextBox textBoxHtmlColor; private GreenshotLabel labelBlue;
private GreenshotLabel labelRecentColors; private System.Windows.Forms.TextBox textBoxHtmlColor;
private GreenshotLabel labelAlpha; private GreenshotLabel labelRecentColors;
private GreenshotLabel labelHtmlColor; private GreenshotLabel labelAlpha;
private GreenshotButton btnApply; private GreenshotLabel labelHtmlColor;
private System.Windows.Forms.TextBox textBoxAlpha; private GreenshotButton btnApply;
private System.Windows.Forms.TextBox textBoxRed; private System.Windows.Forms.TextBox textBoxAlpha;
private System.Windows.Forms.TextBox textBoxGreen; private System.Windows.Forms.TextBox textBoxRed;
private System.Windows.Forms.TextBox textBoxBlue; private System.Windows.Forms.TextBox textBoxGreen;
private System.Windows.Forms.Panel colorPanel; private System.Windows.Forms.TextBox textBoxBlue;
private GreenshotButton btnTransparent; private System.Windows.Forms.Panel colorPanel;
private Greenshot.Controls.Pipette pipette; private GreenshotButton btnTransparent;
private Pipette pipette;
}
} }
}

View file

@ -1,280 +1,280 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Configuration; using Greenshot.Editor.Configuration;
using Greenshot.Controls; using Greenshot.Editor.Controls;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
/// <summary> /// <summary>
/// Description of ColorDialog. /// Description of ColorDialog.
/// </summary> /// </summary>
public partial class ColorDialog : BaseForm public partial class ColorDialog : EditorForm
{ {
private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
private static ColorDialog _instance; private static ColorDialog _instance;
public ColorDialog() public ColorDialog()
{ {
SuspendLayout(); SuspendLayout();
InitializeComponent(); InitializeComponent();
SuspendLayout(); SuspendLayout();
CreateColorPalette(5, 5, 15, 15); CreateColorPalette(5, 5, 15, 15);
CreateLastUsedColorButtonRow(5, 190, 15, 15); CreateLastUsedColorButtonRow(5, 190, 15, 15);
ResumeLayout(); ResumeLayout();
UpdateRecentColorsButtonRow(); UpdateRecentColorsButtonRow();
_instance = this; _instance = this;
} }
public static ColorDialog GetInstance() => _instance; public static ColorDialog GetInstance() => _instance;
private readonly List<Button> _colorButtons = new List<Button>(); private readonly List<Button> _colorButtons = new List<Button>();
private readonly List<Button> _recentColorButtons = new List<Button>(); private readonly List<Button> _recentColorButtons = new List<Button>();
private readonly ToolTip _toolTip = new ToolTip(); private readonly ToolTip _toolTip = new ToolTip();
private bool _updateInProgress; private bool _updateInProgress;
public Color Color public Color Color
{ {
get { return colorPanel.BackColor; } get { return colorPanel.BackColor; }
set { PreviewColor(value, this); } set { PreviewColor(value, this); }
} }
private void CreateColorPalette(int x, int y, int w, int h) private void CreateColorPalette(int x, int y, int w, int h)
{ {
CreateColorButtonColumn(255, 0, 0, x, y, w, h, 11); CreateColorButtonColumn(255, 0, 0, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255, 255 / 2, 0, x, y, w, h, 11); CreateColorButtonColumn(255, 255 / 2, 0, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255, 255, 0, x, y, w, h, 11); CreateColorButtonColumn(255, 255, 0, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255 / 2, 255, 0, x, y, w, h, 11); CreateColorButtonColumn(255 / 2, 255, 0, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(0, 255, 0, x, y, w, h, 11); CreateColorButtonColumn(0, 255, 0, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(0, 255, 255 / 2, x, y, w, h, 11); CreateColorButtonColumn(0, 255, 255 / 2, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(0, 255, 255, x, y, w, h, 11); CreateColorButtonColumn(0, 255, 255, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(0, 255 / 2, 255, x, y, w, h, 11); CreateColorButtonColumn(0, 255 / 2, 255, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(0, 0, 255, x, y, w, h, 11); CreateColorButtonColumn(0, 0, 255, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255 / 2, 0, 255, x, y, w, h, 11); CreateColorButtonColumn(255 / 2, 0, 255, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255, 0, 255, x, y, w, h, 11); CreateColorButtonColumn(255, 0, 255, x, y, w, h, 11);
x += w; x += w;
CreateColorButtonColumn(255, 0, 255 / 2, x, y, w, h, 11); CreateColorButtonColumn(255, 0, 255 / 2, x, y, w, h, 11);
x += w + 5; x += w + 5;
CreateColorButtonColumn(255 / 2, 255 / 2, 255 / 2, x, y, w, h, 11); CreateColorButtonColumn(255 / 2, 255 / 2, 255 / 2, x, y, w, h, 11);
Controls.AddRange(_colorButtons.ToArray()); Controls.AddRange(_colorButtons.ToArray());
} }
private void CreateColorButtonColumn(int red, int green, int blue, int x, int y, int w, int h, int shades) private void CreateColorButtonColumn(int red, int green, int blue, int x, int y, int w, int h, int shades)
{ {
int shadedColorsNum = (shades - 1) / 2; int shadedColorsNum = (shades - 1) / 2;
for (int i = 0; i <= shadedColorsNum; i++) for (int i = 0; i <= shadedColorsNum; i++)
{ {
_colorButtons.Add(CreateColorButton(red * i / shadedColorsNum, green * i / shadedColorsNum, blue * i / shadedColorsNum, x, y + i * h, w, h)); _colorButtons.Add(CreateColorButton(red * i / shadedColorsNum, green * i / shadedColorsNum, blue * i / shadedColorsNum, x, y + i * h, w, h));
if (i > 0) if (i > 0)
_colorButtons.Add(CreateColorButton(red + (255 - red) * i / shadedColorsNum, green + (255 - green) * i / shadedColorsNum, _colorButtons.Add(CreateColorButton(red + (255 - red) * i / shadedColorsNum, green + (255 - green) * i / shadedColorsNum,
blue + (255 - blue) * i / shadedColorsNum, x, y + (i + shadedColorsNum) * h, w, h)); blue + (255 - blue) * i / shadedColorsNum, x, y + (i + shadedColorsNum) * h, w, h));
} }
} }
private Button CreateColorButton(int red, int green, int blue, int x, int y, int w, int h) private Button CreateColorButton(int red, int green, int blue, int x, int y, int w, int h)
{ {
return CreateColorButton(Color.FromArgb(255, red, green, blue), x, y, w, h); return CreateColorButton(Color.FromArgb(255, red, green, blue), x, y, w, h);
} }
private Button CreateColorButton(Color color, int x, int y, int w, int h) private Button CreateColorButton(Color color, int x, int y, int w, int h)
{ {
Button b = new Button Button b = new Button
{ {
BackColor = color, BackColor = color,
FlatStyle = FlatStyle.Flat, FlatStyle = FlatStyle.Flat,
Location = new Point(x, y), Location = new Point(x, y),
Size = new Size(w, h), Size = new Size(w, h),
TabStop = false TabStop = false
}; };
b.FlatAppearance.BorderSize = 0; b.FlatAppearance.BorderSize = 0;
b.Click += ColorButtonClick; b.Click += ColorButtonClick;
_toolTip.SetToolTip(b, ColorTranslator.ToHtml(color) + " | R:" + color.R + ", G:" + color.G + ", B:" + color.B); _toolTip.SetToolTip(b, ColorTranslator.ToHtml(color) + " | R:" + color.R + ", G:" + color.G + ", B:" + color.B);
return b; return b;
} }
private void CreateLastUsedColorButtonRow(int x, int y, int w, int h) private void CreateLastUsedColorButtonRow(int x, int y, int w, int h)
{ {
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
{ {
Button b = CreateColorButton(Color.Transparent, x, y, w, h); Button b = CreateColorButton(Color.Transparent, x, y, w, h);
b.Enabled = false; b.Enabled = false;
_recentColorButtons.Add(b); _recentColorButtons.Add(b);
x += w; x += w;
} }
Controls.AddRange(_recentColorButtons.ToArray()); Controls.AddRange(_recentColorButtons.ToArray());
} }
private void UpdateRecentColorsButtonRow() private void UpdateRecentColorsButtonRow()
{ {
for (int i = 0; i < EditorConfig.RecentColors.Count && i < 12; i++) for (int i = 0; i < EditorConfig.RecentColors.Count && i < 12; i++)
{ {
_recentColorButtons[i].BackColor = EditorConfig.RecentColors[i]; _recentColorButtons[i].BackColor = EditorConfig.RecentColors[i];
_recentColorButtons[i].Enabled = true; _recentColorButtons[i].Enabled = true;
} }
} }
private void PreviewColor(Color colorToPreview, Control trigger) private void PreviewColor(Color colorToPreview, Control trigger)
{ {
_updateInProgress = true; _updateInProgress = true;
colorPanel.BackColor = colorToPreview; colorPanel.BackColor = colorToPreview;
if (trigger != textBoxHtmlColor) if (trigger != textBoxHtmlColor)
{ {
textBoxHtmlColor.Text = ColorTranslator.ToHtml(colorToPreview); textBoxHtmlColor.Text = ColorTranslator.ToHtml(colorToPreview);
} }
if (trigger != textBoxRed && trigger != textBoxGreen && trigger != textBoxBlue && trigger != textBoxAlpha) if (trigger != textBoxRed && trigger != textBoxGreen && trigger != textBoxBlue && trigger != textBoxAlpha)
{ {
textBoxRed.Text = colorToPreview.R.ToString(); textBoxRed.Text = colorToPreview.R.ToString();
textBoxGreen.Text = colorToPreview.G.ToString(); textBoxGreen.Text = colorToPreview.G.ToString();
textBoxBlue.Text = colorToPreview.B.ToString(); textBoxBlue.Text = colorToPreview.B.ToString();
textBoxAlpha.Text = colorToPreview.A.ToString(); textBoxAlpha.Text = colorToPreview.A.ToString();
} }
_updateInProgress = false; _updateInProgress = false;
} }
private void AddToRecentColors(Color c) private void AddToRecentColors(Color c)
{ {
EditorConfig.RecentColors.Remove(c); EditorConfig.RecentColors.Remove(c);
EditorConfig.RecentColors.Insert(0, c); EditorConfig.RecentColors.Insert(0, c);
if (EditorConfig.RecentColors.Count > 12) if (EditorConfig.RecentColors.Count > 12)
{ {
EditorConfig.RecentColors.RemoveRange(12, EditorConfig.RecentColors.Count - 12); EditorConfig.RecentColors.RemoveRange(12, EditorConfig.RecentColors.Count - 12);
} }
UpdateRecentColorsButtonRow(); UpdateRecentColorsButtonRow();
} }
private void TextBoxHexadecimalTextChanged(object sender, EventArgs e) private void TextBoxHexadecimalTextChanged(object sender, EventArgs e)
{ {
if (_updateInProgress) if (_updateInProgress)
{ {
return; return;
} }
TextBox textBox = (TextBox) sender; TextBox textBox = (TextBox) sender;
string text = textBox.Text.Replace("#", string.Empty); string text = textBox.Text.Replace("#", string.Empty);
Color c; Color c;
if (int.TryParse(text, NumberStyles.AllowHexSpecifier, Thread.CurrentThread.CurrentCulture, out var i)) if (int.TryParse(text, NumberStyles.AllowHexSpecifier, Thread.CurrentThread.CurrentCulture, out var i))
{ {
c = Color.FromArgb(i); c = Color.FromArgb(i);
} }
else else
{ {
try try
{ {
var knownColor = (KnownColor) Enum.Parse(typeof(KnownColor), text, true); var knownColor = (KnownColor) Enum.Parse(typeof(KnownColor), text, true);
c = Color.FromKnownColor(knownColor); c = Color.FromKnownColor(knownColor);
} }
catch (Exception) catch (Exception)
{ {
return; return;
} }
} }
Color opaqueColor = Color.FromArgb(255, c.R, c.G, c.B); Color opaqueColor = Color.FromArgb(255, c.R, c.G, c.B);
PreviewColor(opaqueColor, textBox); PreviewColor(opaqueColor, textBox);
} }
private void TextBoxRgbTextChanged(object sender, EventArgs e) private void TextBoxRgbTextChanged(object sender, EventArgs e)
{ {
if (_updateInProgress) if (_updateInProgress)
{ {
return; return;
} }
TextBox textBox = (TextBox) sender; TextBox textBox = (TextBox) sender;
PreviewColor( PreviewColor(
Color.FromArgb(GetColorPartIntFromString(textBoxAlpha.Text), GetColorPartIntFromString(textBoxRed.Text), GetColorPartIntFromString(textBoxGreen.Text), Color.FromArgb(GetColorPartIntFromString(textBoxAlpha.Text), GetColorPartIntFromString(textBoxRed.Text), GetColorPartIntFromString(textBoxGreen.Text),
GetColorPartIntFromString(textBoxBlue.Text)), textBox); GetColorPartIntFromString(textBoxBlue.Text)), textBox);
} }
private void TextBoxGotFocus(object sender, EventArgs e) private void TextBoxGotFocus(object sender, EventArgs e)
{ {
textBoxHtmlColor.SelectAll(); textBoxHtmlColor.SelectAll();
} }
private void TextBoxKeyDown(object sender, KeyEventArgs e) private void TextBoxKeyDown(object sender, KeyEventArgs e)
{ {
if (e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter) if (e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter)
{ {
AddToRecentColors(colorPanel.BackColor); AddToRecentColors(colorPanel.BackColor);
} }
} }
private void ColorButtonClick(object sender, EventArgs e) private void ColorButtonClick(object sender, EventArgs e)
{ {
Button b = (Button) sender; Button b = (Button) sender;
PreviewColor(b.BackColor, b); PreviewColor(b.BackColor, b);
} }
private void BtnTransparentClick(object sender, EventArgs e) private void BtnTransparentClick(object sender, EventArgs e)
{ {
ColorButtonClick(sender, e); ColorButtonClick(sender, e);
} }
private void BtnApplyClick(object sender, EventArgs e) private void BtnApplyClick(object sender, EventArgs e)
{ {
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
Hide(); Hide();
AddToRecentColors(colorPanel.BackColor); AddToRecentColors(colorPanel.BackColor);
} }
private int GetColorPartIntFromString(string s) private int GetColorPartIntFromString(string s)
{ {
int.TryParse(s, out var ret); int.TryParse(s, out var ret);
if (ret < 0) if (ret < 0)
{ {
ret = 0; ret = 0;
} }
else if (ret > 255) else if (ret > 255)
{ {
ret = 255; ret = 255;
} }
return ret; return ret;
} }
private void PipetteUsed(object sender, PipetteUsedArgs e) private void PipetteUsed(object sender, PipetteUsedArgs e)
{ {
Color = e.Color; Color = e.Color;
} }
} }
} }

View file

@ -1,135 +1,135 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value> <value>[base64 mime encoded serialized .NET Framework object]</value>
</data> </data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata"> <xsd:element name="metadata">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="data"> <xsd:element name="data">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" /> <xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
<xsd:complexType> <xsd:complexType>
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" /> <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:choice> </xsd:choice>
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pipette.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="pipette.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAABqklEQVQ4T6WTvUtCURiH34Mi YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAABqklEQVQ4T6WTvUtCURiH34Mi
Koo6CKI45HUT/4CgDwz8oMVFXLyGIVpDjTYkuDsoF6RPmtJKkIgKipYsCIoQihYXKxSCICjaGoTTe6R7 Koo6CKI45HUT/4CgDwz8oMVFXLyGIVpDjTYkuDsoF6RPmtJKkIgKipYsCIoQihYXKxSCICjaGoTTe6R7
uflBgcOPwz3wPL/3HM4FSikMkw6sVCphHPNCSE9auPf8kydCJuqEHNYIOakSMsXYjiClUPSFmVAUiHBb uflBgcOPwz3wPL/3HM4FSikMkw6sVCphHPNCSE9auPf8kydCJuqEHNYIOakSMsXYjiClUPSFmVAUiHBb
EOh7KkWPAC4lQb9mcY8J5HAzGKSP4TDdBrj+SzCGkkqTkHk2NmuWw+sAfklQBYDunAPUaLlMG4Qc9INX EOh7KkWPAC4lQb9mcY8J5HAzGKSP4TDdBrj+SzCGkkqTkHk2NmuWw+sAfklQBYDunAPUaLlMG4Qc9INX
kZEERa8Xdvx+2A0EpJR8Pv4UJe1CoaeZwb8E2WwWcrkcCILQST6fd2YymeRS6SG9j5JGKEQ3AW7XAJZF kZEERa8Xdvx+2A0EpJR8Pv4UJe1CoaeZwb8E2WwWcrkcCILQST6fd2YymeRS6SG9j5JGKEQ3AW7XAJZF
eKBAhN8+v+p7V61jJimi5AMvbgVXDIiRjiBO0A2f3b9uud3u5IzRyOMEDA4MFKCES6fTCbGZwS6XK2G3 eKBAhN8+v+p7V61jJimi5AMvbgVXDIiRjiBO0A2f3b9uud3u5IzRyOMEDA4MFKCES6fTCbGZwS6XK2G3
250RvR42ZM09E/A8D/F4PCaHOY6LWSwWzmq1wp8Cj8fjiMzOLbAzs2YEeZPJ5DCbzfAvgc1mi7L20Unv 250RvR42ZM09E/A8D/F4PCaHOY6LWSwWzmq1wp8Cj8fjiMzOLbAzs2YEeZPJ5DCbzfAvgc1mi7L20Unv
ok6ni2q12hGDwQCDBEV8nRWMdIkajWZapVLFMZxarQb8hn6CMkI3mDvMhVwwzO/8DbWQqn7YBXReAAAA ok6ni2q12hGDwQCDBEV8nRWMdIkajWZapVLFMZxarQb8hn6CMkI3mDvMhVwwzO/8DbWQqn7YBXReAAAA
AElFTkSuQmCC AElFTkSuQmCC
</value> </value>
</data> </data>
</root> </root>

View file

@ -1,101 +1,101 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Windows.Forms; using System.Windows.Forms;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
public delegate void ColorPickerEventHandler(object o, ColorPickerEventArgs e); public delegate void ColorPickerEventHandler(object o, ColorPickerEventArgs e);
public class ColorPickerToolStripButton : ToolStripButton public class ColorPickerToolStripButton : ToolStripButton
{ {
private Color _color; private Color _color;
public Point Offset = new Point(0, 0); public Point Offset = new Point(0, 0);
public event ColorPickerEventHandler ColorPicked; public event ColorPickerEventHandler ColorPicked;
private readonly ColorDialog _cd; private readonly ColorDialog _cd;
public ColorPickerToolStripButton() public ColorPickerToolStripButton()
{ {
_cd = ColorDialog.GetInstance(); _cd = ColorDialog.GetInstance();
Click += ToolStripButton1Click; Click += ToolStripButton1Click;
} }
public Color Color public Color Color
{ {
set set
{ {
_color = value; _color = value;
Invalidate(); Invalidate();
} }
get { return _color; } get { return _color; }
} }
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
{ {
base.OnPaint(e); base.OnPaint(e);
if (_color != null) if (_color != null)
{ {
// replace transparent color with selected color // replace transparent color with selected color
Graphics g = e.Graphics; Graphics g = e.Graphics;
//Graphics g = Graphics.FromImage(Image); //Graphics g = Graphics.FromImage(Image);
ColorMap[] colorMap = new ColorMap[1]; ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap colorMap[0] = new ColorMap
{ {
OldColor = Color.Magenta, //this.ImageTransparentColor; OldColor = Color.Magenta, //this.ImageTransparentColor;
NewColor = _color NewColor = _color
}; };
ImageAttributes attr = new ImageAttributes(); ImageAttributes attr = new ImageAttributes();
attr.SetRemapTable(colorMap); attr.SetRemapTable(colorMap);
Rectangle rect = new Rectangle(0, 0, Image.Width, Image.Height); Rectangle rect = new Rectangle(0, 0, Image.Width, Image.Height);
// todo find a way to retrieve transparency offset automatically // todo find a way to retrieve transparency offset automatically
// for now, we use the public variable Offset to define this manually // for now, we use the public variable Offset to define this manually
rect.Offset(Offset.X, Offset.Y); rect.Offset(Offset.X, Offset.Y);
//Image. //Image.
Debug.WriteLine("paint!" + Text + ": " + _color); Debug.WriteLine("paint!" + Text + ": " + _color);
//ssif(color.Equals(Color.Transparent)) ((Bitmap)Image).MakeTransparent(Color.Magenta); //ssif(color.Equals(Color.Transparent)) ((Bitmap)Image).MakeTransparent(Color.Magenta);
g.DrawImage(Image, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr); g.DrawImage(Image, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr);
//this.Image.In //this.Image.In
} }
} }
void ToolStripButton1Click(object sender, EventArgs e) void ToolStripButton1Click(object sender, EventArgs e)
{ {
_cd.ShowDialog(Owner); _cd.ShowDialog(Owner);
Color = _cd.Color; Color = _cd.Color;
ColorPicked?.Invoke(this, new ColorPickerEventArgs(Color)); ColorPicked?.Invoke(this, new ColorPickerEventArgs(Color));
} }
} }
public class ColorPickerEventArgs : EventArgs public class ColorPickerEventArgs : EventArgs
{ {
public Color Color; public Color Color;
public ColorPickerEventArgs(Color color) public ColorPickerEventArgs(Color color)
{ {
Color = color; Color = color;
} }
} }
} }

View file

@ -1,239 +1,239 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
namespace Greenshot.Forms { namespace Greenshot.Editor.Forms {
partial class DropShadowSettingsForm { partial class DropShadowSettingsForm {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
private System.ComponentModel.IContainer components = null; private System.ComponentModel.IContainer components = null;
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) { protected override void Dispose(bool disposing) {
if (disposing && (components != null)) { if (disposing && (components != null)) {
components.Dispose(); components.Dispose();
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() { private void InitializeComponent() {
this.thickness = new System.Windows.Forms.NumericUpDown(); this.thickness = new System.Windows.Forms.NumericUpDown();
this.offsetX = new System.Windows.Forms.NumericUpDown(); this.offsetX = new System.Windows.Forms.NumericUpDown();
this.label3 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label();
this.offsetY = new System.Windows.Forms.NumericUpDown(); this.offsetY = new System.Windows.Forms.NumericUpDown();
this.trackBar1 = new System.Windows.Forms.TrackBar(); this.trackBar1 = new System.Windows.Forms.TrackBar();
this.buttonOK = new GreenshotButton(); this.buttonOK = new GreenshotButton();
this.buttonCancel = new GreenshotButton(); this.buttonCancel = new GreenshotButton();
this.labelDarkness = new GreenshotLabel(); this.labelDarkness = new GreenshotLabel();
this.labelOffset = new GreenshotLabel(); this.labelOffset = new GreenshotLabel();
this.labelThickness = new GreenshotLabel(); this.labelThickness = new GreenshotLabel();
((System.ComponentModel.ISupportInitialize)(this.thickness)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.thickness)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.offsetX)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.offsetY)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetY)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// thickness // thickness
// //
this.thickness.Location = new System.Drawing.Point(173, 7); this.thickness.Location = new System.Drawing.Point(173, 7);
this.thickness.Maximum = new decimal(new int[] { this.thickness.Maximum = new decimal(new int[] {
20, 20,
0, 0,
0, 0,
0}); 0});
this.thickness.Minimum = new decimal(new int[] { this.thickness.Minimum = new decimal(new int[] {
1, 1,
0, 0,
0, 0,
0}); 0});
this.thickness.Name = "thickness"; this.thickness.Name = "thickness";
this.thickness.Size = new System.Drawing.Size(45, 20); this.thickness.Size = new System.Drawing.Size(45, 20);
this.thickness.TabIndex = 1; this.thickness.TabIndex = 1;
this.thickness.Value = new decimal(new int[] { this.thickness.Value = new decimal(new int[] {
9, 9,
0, 0,
0, 0,
0}); 0});
// //
// offsetX // offsetX
// //
this.offsetX.Location = new System.Drawing.Point(102, 33); this.offsetX.Location = new System.Drawing.Point(102, 33);
this.offsetX.Maximum = new decimal(new int[] { this.offsetX.Maximum = new decimal(new int[] {
20, 20,
0, 0,
0, 0,
0}); 0});
this.offsetX.Minimum = new decimal(new int[] { this.offsetX.Minimum = new decimal(new int[] {
20, 20,
0, 0,
0, 0,
-2147483648}); -2147483648});
this.offsetX.Name = "offsetX"; this.offsetX.Name = "offsetX";
this.offsetX.Size = new System.Drawing.Size(45, 20); this.offsetX.Size = new System.Drawing.Size(45, 20);
this.offsetX.TabIndex = 2; this.offsetX.TabIndex = 2;
this.offsetX.Value = new decimal(new int[] { this.offsetX.Value = new decimal(new int[] {
1, 1,
0, 0,
0, 0,
-2147483648}); -2147483648});
// //
// label3 // label3
// //
this.label3.Location = new System.Drawing.Point(153, 35); this.label3.Location = new System.Drawing.Point(153, 35);
this.label3.Name = "label3"; this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(14, 13); this.label3.Size = new System.Drawing.Size(14, 13);
this.label3.TabIndex = 5; this.label3.TabIndex = 5;
this.label3.Text = "X"; this.label3.Text = "X";
// //
// offsetY // offsetY
// //
this.offsetY.Location = new System.Drawing.Point(173, 33); this.offsetY.Location = new System.Drawing.Point(173, 33);
this.offsetY.Maximum = new decimal(new int[] { this.offsetY.Maximum = new decimal(new int[] {
20, 20,
0, 0,
0, 0,
0}); 0});
this.offsetY.Minimum = new decimal(new int[] { this.offsetY.Minimum = new decimal(new int[] {
20, 20,
0, 0,
0, 0,
-2147483648}); -2147483648});
this.offsetY.Name = "offsetY"; this.offsetY.Name = "offsetY";
this.offsetY.Size = new System.Drawing.Size(45, 20); this.offsetY.Size = new System.Drawing.Size(45, 20);
this.offsetY.TabIndex = 3; this.offsetY.TabIndex = 3;
this.offsetY.Value = new decimal(new int[] { this.offsetY.Value = new decimal(new int[] {
1, 1,
0, 0,
0, 0,
-2147483648}); -2147483648});
// //
// trackBar1 // trackBar1
// //
this.trackBar1.Location = new System.Drawing.Point(102, 59); this.trackBar1.Location = new System.Drawing.Point(102, 59);
this.trackBar1.Maximum = 40; this.trackBar1.Maximum = 40;
this.trackBar1.Minimum = 1; this.trackBar1.Minimum = 1;
this.trackBar1.Name = "trackBar1"; this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(116, 45); this.trackBar1.Size = new System.Drawing.Size(116, 45);
this.trackBar1.TabIndex = 4; this.trackBar1.TabIndex = 4;
this.trackBar1.Value = 40; this.trackBar1.Value = 40;
// //
// buttonOK // buttonOK
// //
this.buttonOK.LanguageKey = "OK"; this.buttonOK.LanguageKey = "OK";
this.buttonOK.Location = new System.Drawing.Point(62, 110); this.buttonOK.Location = new System.Drawing.Point(62, 110);
this.buttonOK.Name = "buttonOK"; this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 11; this.buttonOK.TabIndex = 11;
this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
// //
// buttonCancel // buttonCancel
// //
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.LanguageKey = "CANCEL"; this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.Location = new System.Drawing.Point(143, 110); this.buttonCancel.Location = new System.Drawing.Point(143, 110);
this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 12; this.buttonCancel.TabIndex = 12;
this.buttonCancel.UseVisualStyleBackColor = true; this.buttonCancel.UseVisualStyleBackColor = true;
// //
// labelDarkness // labelDarkness
// //
this.labelDarkness.LanguageKey = "editor_dropshadow_darkness"; this.labelDarkness.LanguageKey = "editor_dropshadow_darkness";
this.labelDarkness.Location = new System.Drawing.Point(12, 73); this.labelDarkness.Location = new System.Drawing.Point(12, 73);
this.labelDarkness.Name = "labelDarkness"; this.labelDarkness.Name = "labelDarkness";
this.labelDarkness.Size = new System.Drawing.Size(92, 13); this.labelDarkness.Size = new System.Drawing.Size(92, 13);
this.labelDarkness.TabIndex = 13; this.labelDarkness.TabIndex = 13;
// //
// labelOffset // labelOffset
// //
this.labelOffset.LanguageKey = "editor_dropshadow_offset"; this.labelOffset.LanguageKey = "editor_dropshadow_offset";
this.labelOffset.Location = new System.Drawing.Point(12, 35); this.labelOffset.Location = new System.Drawing.Point(12, 35);
this.labelOffset.Name = "labelOffset"; this.labelOffset.Name = "labelOffset";
this.labelOffset.Size = new System.Drawing.Size(75, 13); this.labelOffset.Size = new System.Drawing.Size(75, 13);
this.labelOffset.TabIndex = 14; this.labelOffset.TabIndex = 14;
// //
// labelThickness // labelThickness
// //
this.labelThickness.LanguageKey = "editor_dropshadow_thickness"; this.labelThickness.LanguageKey = "editor_dropshadow_thickness";
this.labelThickness.Location = new System.Drawing.Point(12, 9); this.labelThickness.Location = new System.Drawing.Point(12, 9);
this.labelThickness.Name = "labelThickness"; this.labelThickness.Name = "labelThickness";
this.labelThickness.Size = new System.Drawing.Size(94, 13); this.labelThickness.Size = new System.Drawing.Size(94, 13);
this.labelThickness.TabIndex = 15; this.labelThickness.TabIndex = 15;
// //
// DropShadowSettingsForm // DropShadowSettingsForm
// //
this.AcceptButton = this.buttonOK; this.AcceptButton = this.buttonOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.CancelButton = this.buttonCancel; this.CancelButton = this.buttonCancel;
this.ClientSize = new System.Drawing.Size(230, 154); this.ClientSize = new System.Drawing.Size(230, 154);
this.ControlBox = false; this.ControlBox = false;
this.Controls.Add(this.labelThickness); this.Controls.Add(this.labelThickness);
this.Controls.Add(this.labelOffset); this.Controls.Add(this.labelOffset);
this.Controls.Add(this.labelDarkness); this.Controls.Add(this.labelDarkness);
this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK); this.Controls.Add(this.buttonOK);
this.Controls.Add(this.trackBar1); this.Controls.Add(this.trackBar1);
this.Controls.Add(this.offsetY); this.Controls.Add(this.offsetY);
this.Controls.Add(this.label3); this.Controls.Add(this.label3);
this.Controls.Add(this.offsetX); this.Controls.Add(this.offsetX);
this.Controls.Add(this.thickness); this.Controls.Add(this.thickness);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.LanguageKey = "editor_dropshadow_settings"; this.LanguageKey = "editor_dropshadow_settings";
this.MaximizeBox = false; this.MaximizeBox = false;
this.MinimizeBox = false; this.MinimizeBox = false;
this.Name = "DropShadowSettingsForm"; this.Name = "DropShadowSettingsForm";
this.ShowIcon = false; this.ShowIcon = false;
((System.ComponentModel.ISupportInitialize)(this.thickness)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.thickness)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.offsetX)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetX)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.offsetY)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetY)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
} }
#endregion #endregion
private System.Windows.Forms.NumericUpDown thickness; private System.Windows.Forms.NumericUpDown thickness;
private System.Windows.Forms.NumericUpDown offsetX; private System.Windows.Forms.NumericUpDown offsetX;
private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label3;
private System.Windows.Forms.NumericUpDown offsetY; private System.Windows.Forms.NumericUpDown offsetY;
private System.Windows.Forms.TrackBar trackBar1; private System.Windows.Forms.TrackBar trackBar1;
private GreenshotButton buttonOK; private GreenshotButton buttonOK;
private GreenshotButton buttonCancel; private GreenshotButton buttonCancel;
private GreenshotLabel labelDarkness; private GreenshotLabel labelDarkness;
private GreenshotLabel labelOffset; private GreenshotLabel labelOffset;
private GreenshotLabel labelThickness; private GreenshotLabel labelThickness;
} }
} }

View file

@ -1,59 +1,59 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Effects; using Greenshot.Base.Effects;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
public partial class DropShadowSettingsForm : BaseForm public partial class DropShadowSettingsForm : EditorForm
{ {
private readonly DropShadowEffect _effect; private readonly DropShadowEffect _effect;
public DropShadowSettingsForm(DropShadowEffect effect) public DropShadowSettingsForm(DropShadowEffect effect)
{ {
_effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
ShowSettings(); ShowSettings();
} }
/// <summary> /// <summary>
/// Apply the settings from the effect to the view /// Apply the settings from the effect to the view
/// </summary> /// </summary>
private void ShowSettings() private void ShowSettings()
{ {
trackBar1.Value = (int) (_effect.Darkness * 40); trackBar1.Value = (int) (_effect.Darkness * 40);
offsetX.Value = _effect.ShadowOffset.X; offsetX.Value = _effect.ShadowOffset.X;
offsetY.Value = _effect.ShadowOffset.Y; offsetY.Value = _effect.ShadowOffset.Y;
thickness.Value = _effect.ShadowSize; thickness.Value = _effect.ShadowSize;
} }
private void ButtonOK_Click(object sender, EventArgs e) private void ButtonOK_Click(object sender, EventArgs e)
{ {
_effect.Darkness = trackBar1.Value / (float) 40; _effect.Darkness = trackBar1.Value / (float) 40;
_effect.ShadowOffset = new Point((int) offsetX.Value, (int) offsetY.Value); _effect.ShadowOffset = new Point((int) offsetX.Value, (int) offsetY.Value);
_effect.ShadowSize = (int) thickness.Value; _effect.ShadowSize = (int) thickness.Value;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
} }
} }

View file

@ -0,0 +1,29 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
*
* For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using Greenshot.Base.Controls;
namespace Greenshot.Editor.Forms
{
public class EditorForm : GreenshotForm
{
}
}

View file

@ -1,183 +1,183 @@
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
partial class MovableShowColorForm partial class MovableShowColorForm
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.
/// </summary> /// </summary>
private System.ComponentModel.IContainer components = null; private System.ComponentModel.IContainer components = null;
/// <summary> /// <summary>
/// Clean up any resources being used. /// Clean up any resources being used.
/// </summary> /// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing && (components != null)) if (disposing && (components != null))
{ {
components.Dispose(); components.Dispose();
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
#region Windows Form Designer generated code #region Windows Form Designer generated code
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.panel1 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel();
this.html = new System.Windows.Forms.Label(); this.html = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.preview = new System.Windows.Forms.Label(); this.preview = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label();
this.red = new System.Windows.Forms.Label(); this.red = new System.Windows.Forms.Label();
this.green = new System.Windows.Forms.Label(); this.green = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label();
this.blue = new System.Windows.Forms.Label(); this.blue = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label();
this.alpha = new System.Windows.Forms.Label(); this.alpha = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label();
this.panel1.SuspendLayout(); this.panel1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// html // html
// //
this.html.Location = new System.Drawing.Point(40, 18); this.html.Location = new System.Drawing.Point(40, 18);
this.html.Name = "html"; this.html.Name = "html";
this.html.Size = new System.Drawing.Size(59, 19); this.html.Size = new System.Drawing.Size(59, 19);
this.html.TabIndex = 2; this.html.TabIndex = 2;
// //
// label1 // label1
// //
this.label1.Location = new System.Drawing.Point(40, 5); this.label1.Location = new System.Drawing.Point(40, 5);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(37, 13); this.label1.Size = new System.Drawing.Size(37, 13);
this.label1.TabIndex = 1; this.label1.TabIndex = 1;
this.label1.Text = "HTML"; this.label1.Text = "HTML";
// //
// preview // preview
// //
this.preview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.preview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.preview.Location = new System.Drawing.Point(5, 5); this.preview.Location = new System.Drawing.Point(5, 5);
this.preview.Name = "preview"; this.preview.Name = "preview";
this.preview.Size = new System.Drawing.Size(32, 32); this.preview.Size = new System.Drawing.Size(32, 32);
this.preview.TabIndex = 0; this.preview.TabIndex = 0;
// //
// label2 // label2
// //
this.label2.Location = new System.Drawing.Point(2, 37); this.label2.Location = new System.Drawing.Point(2, 37);
this.label2.Name = "label2"; this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(33, 13); this.label2.Size = new System.Drawing.Size(33, 13);
this.label2.TabIndex = 3; this.label2.TabIndex = 3;
this.label2.Text = "Red: "; this.label2.Text = "Red: ";
// //
// red // red
// //
this.red.Location = new System.Drawing.Point(43, 37); this.red.Location = new System.Drawing.Point(43, 37);
this.red.Name = "red"; this.red.Name = "red";
this.red.Size = new System.Drawing.Size(55, 13); this.red.Size = new System.Drawing.Size(55, 13);
this.red.TabIndex = 4; this.red.TabIndex = 4;
// //
// green // green
// //
this.green.Location = new System.Drawing.Point(43, 50); this.green.Location = new System.Drawing.Point(43, 50);
this.green.Name = "green"; this.green.Name = "green";
this.green.Size = new System.Drawing.Size(55, 13); this.green.Size = new System.Drawing.Size(55, 13);
this.green.TabIndex = 6; this.green.TabIndex = 6;
// //
// label4 // label4
// //
this.label4.Location = new System.Drawing.Point(2, 50); this.label4.Location = new System.Drawing.Point(2, 50);
this.label4.Name = "label4"; this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(42, 13); this.label4.Size = new System.Drawing.Size(42, 13);
this.label4.TabIndex = 5; this.label4.TabIndex = 5;
this.label4.Text = "Green: "; this.label4.Text = "Green: ";
// //
// blue // blue
// //
this.blue.Location = new System.Drawing.Point(43, 63); this.blue.Location = new System.Drawing.Point(43, 63);
this.blue.Name = "blue"; this.blue.Name = "blue";
this.blue.Size = new System.Drawing.Size(55, 13); this.blue.Size = new System.Drawing.Size(55, 13);
this.blue.TabIndex = 8; this.blue.TabIndex = 8;
// //
// label6 // label6
// //
this.label6.Location = new System.Drawing.Point(2, 63); this.label6.Location = new System.Drawing.Point(2, 63);
this.label6.Name = "label6"; this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(34, 13); this.label6.Size = new System.Drawing.Size(34, 13);
this.label6.TabIndex = 7; this.label6.TabIndex = 7;
this.label6.Text = "Blue: "; this.label6.Text = "Blue: ";
// //
// alpha // alpha
// //
this.alpha.Location = new System.Drawing.Point(43, 76); this.alpha.Location = new System.Drawing.Point(43, 76);
this.alpha.Name = "alpha"; this.alpha.Name = "alpha";
this.alpha.Size = new System.Drawing.Size(55, 13); this.alpha.Size = new System.Drawing.Size(55, 13);
this.alpha.TabIndex = 10; this.alpha.TabIndex = 10;
// //
// label5 // label5
// //
this.label5.Location = new System.Drawing.Point(2, 76); this.label5.Location = new System.Drawing.Point(2, 76);
this.label5.Name = "label5"; this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(40, 13); this.label5.Size = new System.Drawing.Size(40, 13);
this.label5.TabIndex = 9; this.label5.TabIndex = 9;
this.label5.Text = "Alpha: "; this.label5.Text = "Alpha: ";
// //
// panel1 // panel1
// //
this.panel1.BackColor = System.Drawing.SystemColors.Info; this.panel1.BackColor = System.Drawing.SystemColors.Info;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.alpha); this.panel1.Controls.Add(this.alpha);
this.panel1.Controls.Add(this.label5); this.panel1.Controls.Add(this.label5);
this.panel1.Controls.Add(this.blue); this.panel1.Controls.Add(this.blue);
this.panel1.Controls.Add(this.label6); this.panel1.Controls.Add(this.label6);
this.panel1.Controls.Add(this.green); this.panel1.Controls.Add(this.green);
this.panel1.Controls.Add(this.label4); this.panel1.Controls.Add(this.label4);
this.panel1.Controls.Add(this.red); this.panel1.Controls.Add(this.red);
this.panel1.Controls.Add(this.label2); this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.html); this.panel1.Controls.Add(this.html);
this.panel1.Controls.Add(this.label1); this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.preview); this.panel1.Controls.Add(this.preview);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0); this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1"; this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(100, 100); this.panel1.Size = new System.Drawing.Size(100, 100);
this.panel1.TabIndex = 0; this.panel1.TabIndex = 0;
// //
// Zoomer // Zoomer
// //
this.Visible = false; this.Visible = false;
this.Location = new System.Drawing.Point(-10000,-10000); this.Location = new System.Drawing.Point(-10000,-10000);
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(100, 100); this.ClientSize = new System.Drawing.Size(100, 100);
this.Controls.Add(this.panel1); this.Controls.Add(this.panel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Zoomer"; this.Name = "Zoomer";
this.ShowIcon = false; this.ShowIcon = false;
this.ShowInTaskbar = false; this.ShowInTaskbar = false;
this.Text = "Zoomer"; this.Text = "Zoomer";
this.TopMost = true; this.TopMost = true;
this.panel1.ResumeLayout(true); this.panel1.ResumeLayout(true);
this.ResumeLayout(true); this.ResumeLayout(true);
} }
#endregion #endregion
private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label html; private System.Windows.Forms.Label html;
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label preview; private System.Windows.Forms.Label preview;
private System.Windows.Forms.Label alpha; private System.Windows.Forms.Label alpha;
private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label blue; private System.Windows.Forms.Label blue;
private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label green; private System.Windows.Forms.Label green;
private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label red; private System.Windows.Forms.Label red;
private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label2;
} }
} }

View file

@ -1,117 +1,117 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Windows.Forms; using System.Drawing;
using System.Drawing; using System.Windows.Forms;
using Greenshot.Base.UnmanagedHelpers; using Greenshot.Base.UnmanagedHelpers;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
/// <summary> /// <summary>
/// This code was supplied by Hi-Coder as a patch for Greenshot /// This code was supplied by Hi-Coder as a patch for Greenshot
/// Needed some modifications to be stable. /// Needed some modifications to be stable.
/// </summary> /// </summary>
public partial class MovableShowColorForm : Form public partial class MovableShowColorForm : Form
{ {
public Color color public Color color
{ {
get { return preview.BackColor; } get { return preview.BackColor; }
} }
public MovableShowColorForm() public MovableShowColorForm()
{ {
InitializeComponent(); InitializeComponent();
} }
/// <summary> /// <summary>
/// Move the MovableShowColorForm to the specified location and display the color under the (current mouse) coordinates /// Move the MovableShowColorForm to the specified location and display the color under the (current mouse) coordinates
/// </summary> /// </summary>
/// <param name="screenCoordinates">Coordinates</param> /// <param name="screenCoordinates">Coordinates</param>
public void MoveTo(Point screenCoordinates) public void MoveTo(Point screenCoordinates)
{ {
Color c = GetPixelColor(screenCoordinates); Color c = GetPixelColor(screenCoordinates);
preview.BackColor = c; preview.BackColor = c;
html.Text = "#" + c.Name.Substring(2).ToUpper(); html.Text = "#" + c.Name.Substring(2).ToUpper();
red.Text = string.Empty + c.R; red.Text = string.Empty + c.R;
blue.Text = string.Empty + c.B; blue.Text = string.Empty + c.B;
green.Text = string.Empty + c.G; green.Text = string.Empty + c.G;
alpha.Text = string.Empty + c.A; alpha.Text = string.Empty + c.A;
Size cursorSize = Cursor.Current.Size; Size cursorSize = Cursor.Current.Size;
Point hotspot = Cursor.Current.HotSpot; Point hotspot = Cursor.Current.HotSpot;
Point zoomerLocation = new Point(screenCoordinates.X, screenCoordinates.Y); Point zoomerLocation = new Point(screenCoordinates.X, screenCoordinates.Y);
zoomerLocation.X += cursorSize.Width + 5 - hotspot.X; zoomerLocation.X += cursorSize.Width + 5 - hotspot.X;
zoomerLocation.Y += cursorSize.Height + 5 - hotspot.Y; zoomerLocation.Y += cursorSize.Height + 5 - hotspot.Y;
foreach (Screen screen in Screen.AllScreens) foreach (Screen screen in Screen.AllScreens)
{ {
Rectangle screenRectangle = screen.Bounds; Rectangle screenRectangle = screen.Bounds;
if (screen.Bounds.Contains(screenCoordinates)) if (screen.Bounds.Contains(screenCoordinates))
{ {
if (zoomerLocation.X < screenRectangle.X) if (zoomerLocation.X < screenRectangle.X)
{ {
zoomerLocation.X = screenRectangle.X; zoomerLocation.X = screenRectangle.X;
} }
else if (zoomerLocation.X + Width > screenRectangle.X + screenRectangle.Width) else if (zoomerLocation.X + Width > screenRectangle.X + screenRectangle.Width)
{ {
zoomerLocation.X = screenCoordinates.X - Width - 5 - hotspot.X; zoomerLocation.X = screenCoordinates.X - Width - 5 - hotspot.X;
} }
if (zoomerLocation.Y < screenRectangle.Y) if (zoomerLocation.Y < screenRectangle.Y)
{ {
zoomerLocation.Y = screenRectangle.Y; zoomerLocation.Y = screenRectangle.Y;
} }
else if (zoomerLocation.Y + Height > screenRectangle.Y + screenRectangle.Height) else if (zoomerLocation.Y + Height > screenRectangle.Y + screenRectangle.Height)
{ {
zoomerLocation.Y = screenCoordinates.Y - Height - 5 - hotspot.Y; zoomerLocation.Y = screenCoordinates.Y - Height - 5 - hotspot.Y;
} }
break; break;
} }
} }
Location = zoomerLocation; Location = zoomerLocation;
Update(); Update();
} }
/// <summary> /// <summary>
/// Get the color from the pixel on the screen at "x,y" /// Get the color from the pixel on the screen at "x,y"
/// </summary> /// </summary>
/// <param name="screenCoordinates">Point with the coordinates</param> /// <param name="screenCoordinates">Point with the coordinates</param>
/// <returns>Color at the specified screenCoordinates</returns> /// <returns>Color at the specified screenCoordinates</returns>
private static Color GetPixelColor(Point screenCoordinates) private static Color GetPixelColor(Point screenCoordinates)
{ {
using SafeWindowDcHandle screenDC = SafeWindowDcHandle.FromDesktop(); using SafeWindowDcHandle screenDC = SafeWindowDcHandle.FromDesktop();
try try
{ {
uint pixel = GDI32.GetPixel(screenDC, screenCoordinates.X, screenCoordinates.Y); uint pixel = GDI32.GetPixel(screenDC, screenCoordinates.X, screenCoordinates.Y);
Color color = Color.FromArgb(255, (int) (pixel & 0xFF), (int) (pixel & 0xFF00) >> 8, (int) (pixel & 0xFF0000) >> 16); Color color = Color.FromArgb(255, (int) (pixel & 0xFF), (int) (pixel & 0xFF00) >> 8, (int) (pixel & 0xFF0000) >> 16);
return color; return color;
} }
catch (Exception) catch (Exception)
{ {
return Color.Empty; return Color.Empty;
} }
} }
} }
} }

View file

@ -1,183 +1,182 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Windows.Forms; using Greenshot.Base.Controls;
using Greenshot.Base.Controls;
namespace Greenshot.Editor.Forms {
namespace Greenshot.Forms { partial class ResizeSettingsForm {
partial class ResizeSettingsForm { /// <summary>
/// <summary> /// Required designer variable.
/// Required designer variable. /// </summary>
/// </summary> private System.ComponentModel.IContainer components = null;
private System.ComponentModel.IContainer components = null;
/// <summary>
/// <summary> /// Clean up any resources being used.
/// Clean up any resources being used. /// </summary>
/// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) {
protected override void Dispose(bool disposing) { if (disposing && (components != null)) {
if (disposing && (components != null)) { components.Dispose();
components.Dispose(); }
} base.Dispose(disposing);
base.Dispose(disposing); }
}
#region Windows Form Designer generated code
#region Windows Form Designer generated code
/// <summary>
/// <summary> /// Required method for Designer support - do not modify
/// Required method for Designer support - do not modify /// the contents of this method with the code editor.
/// the contents of this method with the code editor. /// </summary>
/// </summary> private void InitializeComponent() {
private void InitializeComponent() { this.buttonOK = new GreenshotButton();
this.buttonOK = new GreenshotButton(); this.buttonCancel = new GreenshotButton();
this.buttonCancel = new GreenshotButton(); this.checkbox_aspectratio = new GreenshotCheckBox();
this.checkbox_aspectratio = new GreenshotCheckBox(); this.label_width = new GreenshotLabel();
this.label_width = new GreenshotLabel(); this.label_height = new GreenshotLabel();
this.label_height = new GreenshotLabel(); this.textbox_height = new System.Windows.Forms.TextBox();
this.textbox_height = new System.Windows.Forms.TextBox(); this.textbox_width = new System.Windows.Forms.TextBox();
this.textbox_width = new System.Windows.Forms.TextBox(); this.combobox_width = new System.Windows.Forms.ComboBox();
this.combobox_width = new System.Windows.Forms.ComboBox(); this.combobox_height = new System.Windows.Forms.ComboBox();
this.combobox_height = new System.Windows.Forms.ComboBox(); this.SuspendLayout();
this.SuspendLayout(); //
// // buttonOK
// buttonOK //
// this.buttonOK.LanguageKey = "OK";
this.buttonOK.LanguageKey = "OK"; this.buttonOK.Location = new System.Drawing.Point(76, 87);
this.buttonOK.Location = new System.Drawing.Point(76, 87); this.buttonOK.Name = "buttonOK";
this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.TabIndex = 6;
this.buttonOK.TabIndex = 6; this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); //
// // buttonCancel
// buttonCancel //
// this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.LanguageKey = "CANCEL"; this.buttonCancel.Location = new System.Drawing.Point(157, 87);
this.buttonCancel.Location = new System.Drawing.Point(157, 87); this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.TabIndex = 7;
this.buttonCancel.TabIndex = 7; this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.UseVisualStyleBackColor = true; //
// // checkbox_aspectratio
// checkbox_aspectratio //
// this.checkbox_aspectratio.LanguageKey = "editor_resize_aspectratio";
this.checkbox_aspectratio.LanguageKey = "editor_resize_aspectratio"; this.checkbox_aspectratio.Location = new System.Drawing.Point(22, 64);
this.checkbox_aspectratio.Location = new System.Drawing.Point(22, 64); this.checkbox_aspectratio.Name = "checkbox_aspectratio";
this.checkbox_aspectratio.Name = "checkbox_aspectratio"; this.checkbox_aspectratio.Size = new System.Drawing.Size(124, 17);
this.checkbox_aspectratio.Size = new System.Drawing.Size(124, 17); this.checkbox_aspectratio.TabIndex = 5;
this.checkbox_aspectratio.TabIndex = 5; this.checkbox_aspectratio.UseVisualStyleBackColor = true;
this.checkbox_aspectratio.UseVisualStyleBackColor = true; //
// // label_width
// label_width //
// this.label_width.LanguageKey = "editor_resize_width";
this.label_width.LanguageKey = "editor_resize_width"; this.label_width.Location = new System.Drawing.Point(19, 15);
this.label_width.Location = new System.Drawing.Point(19, 15); this.label_width.Name = "label_width";
this.label_width.Name = "label_width"; this.label_width.Size = new System.Drawing.Size(35, 13);
this.label_width.Size = new System.Drawing.Size(35, 13); this.label_width.TabIndex = 14;
this.label_width.TabIndex = 14; //
// // label_height
// label_height //
// this.label_height.LanguageKey = "editor_resize_height";
this.label_height.LanguageKey = "editor_resize_height"; this.label_height.Location = new System.Drawing.Point(19, 38);
this.label_height.Location = new System.Drawing.Point(19, 38); this.label_height.Name = "label_height";
this.label_height.Name = "label_height"; this.label_height.Size = new System.Drawing.Size(38, 13);
this.label_height.Size = new System.Drawing.Size(38, 13); this.label_height.TabIndex = 15;
this.label_height.TabIndex = 15; //
// // textbox_height
// textbox_height //
// this.textbox_height.Location = new System.Drawing.Point(90, 38);
this.textbox_height.Location = new System.Drawing.Point(90, 38); this.textbox_height.Name = "textbox_height";
this.textbox_height.Name = "textbox_height"; this.textbox_height.Size = new System.Drawing.Size(69, 20);
this.textbox_height.Size = new System.Drawing.Size(69, 20); this.textbox_height.TabIndex = 3;
this.textbox_height.TabIndex = 3; this.textbox_height.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Textbox_KeyUp);
this.textbox_height.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Textbox_KeyUp); this.textbox_height.Validating += new System.ComponentModel.CancelEventHandler(this.Textbox_Validating);
this.textbox_height.Validating += new System.ComponentModel.CancelEventHandler(this.Textbox_Validating); //
// // textbox_width
// textbox_width //
// this.textbox_width.Location = new System.Drawing.Point(90, 12);
this.textbox_width.Location = new System.Drawing.Point(90, 12); this.textbox_width.Name = "textbox_width";
this.textbox_width.Name = "textbox_width"; this.textbox_width.Size = new System.Drawing.Size(69, 20);
this.textbox_width.Size = new System.Drawing.Size(69, 20); this.textbox_width.TabIndex = 1;
this.textbox_width.TabIndex = 1; this.textbox_width.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Textbox_KeyUp);
this.textbox_width.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Textbox_KeyUp); this.textbox_width.Validating += new System.ComponentModel.CancelEventHandler(this.Textbox_Validating);
this.textbox_width.Validating += new System.ComponentModel.CancelEventHandler(this.Textbox_Validating); //
// // combobox_width
// combobox_width //
// this.combobox_width.FormattingEnabled = true;
this.combobox_width.FormattingEnabled = true; this.combobox_width.Location = new System.Drawing.Point(165, 11);
this.combobox_width.Location = new System.Drawing.Point(165, 11); this.combobox_width.Name = "combobox_width";
this.combobox_width.Name = "combobox_width"; this.combobox_width.Size = new System.Drawing.Size(65, 21);
this.combobox_width.Size = new System.Drawing.Size(65, 21); this.combobox_width.TabIndex = 2;
this.combobox_width.TabIndex = 2; this.combobox_width.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.combobox_width.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; //
// // combobox_height
// combobox_height //
// this.combobox_height.FormattingEnabled = true;
this.combobox_height.FormattingEnabled = true; this.combobox_height.ItemHeight = 13;
this.combobox_height.ItemHeight = 13; this.combobox_height.Location = new System.Drawing.Point(165, 38);
this.combobox_height.Location = new System.Drawing.Point(165, 38); this.combobox_height.Name = "combobox_height";
this.combobox_height.Name = "combobox_height"; this.combobox_height.Size = new System.Drawing.Size(65, 21);
this.combobox_height.Size = new System.Drawing.Size(65, 21); this.combobox_height.TabIndex = 4;
this.combobox_height.TabIndex = 4; this.combobox_height.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.combobox_height.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; //
// // ResizeSettingsForm
// ResizeSettingsForm //
// this.AcceptButton = this.buttonOK;
this.AcceptButton = this.buttonOK; this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.CancelButton = this.buttonCancel;
this.CancelButton = this.buttonCancel; this.ClientSize = new System.Drawing.Size(244, 122);
this.ClientSize = new System.Drawing.Size(244, 122); this.ControlBox = false;
this.ControlBox = false; this.Controls.Add(this.combobox_height);
this.Controls.Add(this.combobox_height); this.Controls.Add(this.combobox_width);
this.Controls.Add(this.combobox_width); this.Controls.Add(this.textbox_width);
this.Controls.Add(this.textbox_width); this.Controls.Add(this.textbox_height);
this.Controls.Add(this.textbox_height); this.Controls.Add(this.label_height);
this.Controls.Add(this.label_height); this.Controls.Add(this.label_width);
this.Controls.Add(this.label_width); this.Controls.Add(this.checkbox_aspectratio);
this.Controls.Add(this.checkbox_aspectratio); this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonOK);
this.Controls.Add(this.buttonOK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.LanguageKey = "editor_resize_settings";
this.LanguageKey = "editor_resize_settings"; this.MaximizeBox = false;
this.MaximizeBox = false; this.MinimizeBox = false;
this.MinimizeBox = false; this.Name = "ResizeSettingsForm";
this.Name = "ResizeSettingsForm"; this.ShowIcon = false;
this.ShowIcon = false; this.ResumeLayout(false);
this.ResumeLayout(false); this.PerformLayout();
this.PerformLayout();
}
}
#endregion
#endregion
private GreenshotButton buttonOK;
private GreenshotButton buttonOK; private GreenshotButton buttonCancel;
private GreenshotButton buttonCancel; private GreenshotCheckBox checkbox_aspectratio;
private GreenshotCheckBox checkbox_aspectratio; private GreenshotLabel label_width;
private GreenshotLabel label_width; private GreenshotLabel label_height;
private GreenshotLabel label_height; private System.Windows.Forms.TextBox textbox_height;
private System.Windows.Forms.TextBox textbox_height; private System.Windows.Forms.TextBox textbox_width;
private System.Windows.Forms.TextBox textbox_width; private System.Windows.Forms.ComboBox combobox_width;
private System.Windows.Forms.ComboBox combobox_width; private System.Windows.Forms.ComboBox combobox_height;
private System.Windows.Forms.ComboBox combobox_height; }
}
} }

View file

@ -1,214 +1,214 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Effects; using Greenshot.Base.Effects;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
/// <summary> /// <summary>
/// A form to set the resize settings /// A form to set the resize settings
/// </summary> /// </summary>
public partial class ResizeSettingsForm : BaseForm public partial class ResizeSettingsForm : EditorForm
{ {
private readonly ResizeEffect _effect; private readonly ResizeEffect _effect;
private readonly string _valuePercent; private readonly string _valuePercent;
private double _newWidth, _newHeight; private double _newWidth, _newHeight;
public ResizeSettingsForm(ResizeEffect effect) public ResizeSettingsForm(ResizeEffect effect)
{ {
_effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
var valuePixel = Language.GetString("editor_resize_pixel"); var valuePixel = Language.GetString("editor_resize_pixel");
_valuePercent = Language.GetString("editor_resize_percent"); _valuePercent = Language.GetString("editor_resize_percent");
combobox_width.Items.Add(valuePixel); combobox_width.Items.Add(valuePixel);
combobox_width.Items.Add(_valuePercent); combobox_width.Items.Add(_valuePercent);
combobox_width.SelectedItem = valuePixel; combobox_width.SelectedItem = valuePixel;
combobox_height.Items.Add(valuePixel); combobox_height.Items.Add(valuePixel);
combobox_height.Items.Add(_valuePercent); combobox_height.Items.Add(_valuePercent);
combobox_height.SelectedItem = valuePixel; combobox_height.SelectedItem = valuePixel;
textbox_width.Text = effect.Width.ToString(); textbox_width.Text = effect.Width.ToString();
textbox_height.Text = effect.Height.ToString(); textbox_height.Text = effect.Height.ToString();
_newWidth = effect.Width; _newWidth = effect.Width;
_newHeight = effect.Height; _newHeight = effect.Height;
combobox_width.SelectedIndexChanged += Combobox_SelectedIndexChanged; combobox_width.SelectedIndexChanged += Combobox_SelectedIndexChanged;
combobox_height.SelectedIndexChanged += Combobox_SelectedIndexChanged; combobox_height.SelectedIndexChanged += Combobox_SelectedIndexChanged;
checkbox_aspectratio.Checked = effect.MaintainAspectRatio; checkbox_aspectratio.Checked = effect.MaintainAspectRatio;
} }
private void ButtonOK_Click(object sender, EventArgs e) private void ButtonOK_Click(object sender, EventArgs e)
{ {
const double tolerance = 3 * double.Epsilon; const double tolerance = 3 * double.Epsilon;
if (Math.Abs(_newWidth - _effect.Width) > tolerance || Math.Abs(_newHeight - _effect.Height) > tolerance) if (Math.Abs(_newWidth - _effect.Width) > tolerance || Math.Abs(_newHeight - _effect.Height) > tolerance)
{ {
_effect.Width = (int) _newWidth; _effect.Width = (int) _newWidth;
_effect.Height = (int) _newHeight; _effect.Height = (int) _newHeight;
_effect.MaintainAspectRatio = checkbox_aspectratio.Checked; _effect.MaintainAspectRatio = checkbox_aspectratio.Checked;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
} }
private static bool Validate(object sender) private static bool Validate(object sender)
{ {
if (sender is not TextBox textBox) if (sender is not TextBox textBox)
{ {
return true; return true;
} }
if (!double.TryParse(textBox.Text, out _)) if (!double.TryParse(textBox.Text, out _))
{ {
textBox.BackColor = Color.Red; textBox.BackColor = Color.Red;
return false; return false;
} }
textBox.BackColor = Color.White; textBox.BackColor = Color.White;
return true; return true;
} }
private void DisplayWidth() private void DisplayWidth()
{ {
double displayValue; double displayValue;
if (_valuePercent.Equals(combobox_width.SelectedItem)) if (_valuePercent.Equals(combobox_width.SelectedItem))
{ {
displayValue = _newWidth / _effect.Width * 100d; displayValue = _newWidth / _effect.Width * 100d;
} }
else else
{ {
displayValue = _newWidth; displayValue = _newWidth;
} }
textbox_width.Text = ((int) displayValue).ToString(); textbox_width.Text = ((int) displayValue).ToString();
} }
private void DisplayHeight() private void DisplayHeight()
{ {
double displayValue; double displayValue;
if (_valuePercent.Equals(combobox_height.SelectedItem)) if (_valuePercent.Equals(combobox_height.SelectedItem))
{ {
displayValue = _newHeight / _effect.Height * 100d; displayValue = _newHeight / _effect.Height * 100d;
} }
else else
{ {
displayValue = _newHeight; displayValue = _newHeight;
} }
textbox_height.Text = ((int) displayValue).ToString(); textbox_height.Text = ((int) displayValue).ToString();
} }
private void Textbox_KeyUp(object sender, KeyEventArgs e) private void Textbox_KeyUp(object sender, KeyEventArgs e)
{ {
if (!Validate(sender)) if (!Validate(sender))
{ {
return; return;
} }
TextBox textbox = sender as TextBox; TextBox textbox = sender as TextBox;
if (string.IsNullOrEmpty(textbox?.Text)) if (string.IsNullOrEmpty(textbox?.Text))
{ {
return; return;
} }
bool isWidth = textbox == textbox_width; bool isWidth = textbox == textbox_width;
if (!checkbox_aspectratio.Checked) if (!checkbox_aspectratio.Checked)
{ {
if (isWidth) if (isWidth)
{ {
_newWidth = double.Parse(textbox_width.Text); _newWidth = double.Parse(textbox_width.Text);
} }
else else
{ {
_newHeight = double.Parse(textbox_height.Text); _newHeight = double.Parse(textbox_height.Text);
} }
return; return;
} }
var isPercent = _valuePercent.Equals(isWidth ? combobox_width.SelectedItem : combobox_height.SelectedItem); var isPercent = _valuePercent.Equals(isWidth ? combobox_width.SelectedItem : combobox_height.SelectedItem);
double percent; double percent;
if (isWidth) if (isWidth)
{ {
if (isPercent) if (isPercent)
{ {
percent = double.Parse(textbox_width.Text); percent = double.Parse(textbox_width.Text);
_newWidth = _effect.Width / 100d * percent; _newWidth = _effect.Width / 100d * percent;
} }
else else
{ {
_newWidth = double.Parse(textbox_width.Text); _newWidth = double.Parse(textbox_width.Text);
percent = double.Parse(textbox_width.Text) / _effect.Width * 100d; percent = double.Parse(textbox_width.Text) / _effect.Width * 100d;
} }
if (checkbox_aspectratio.Checked) if (checkbox_aspectratio.Checked)
{ {
_newHeight = _effect.Height / 100d * percent; _newHeight = _effect.Height / 100d * percent;
DisplayHeight(); DisplayHeight();
} }
} }
else else
{ {
if (isPercent) if (isPercent)
{ {
percent = double.Parse(textbox_height.Text); percent = double.Parse(textbox_height.Text);
_newHeight = _effect.Height / 100d * percent; _newHeight = _effect.Height / 100d * percent;
} }
else else
{ {
_newHeight = double.Parse(textbox_height.Text); _newHeight = double.Parse(textbox_height.Text);
percent = double.Parse(textbox_height.Text) / _effect.Height * 100d; percent = double.Parse(textbox_height.Text) / _effect.Height * 100d;
} }
if (checkbox_aspectratio.Checked) if (checkbox_aspectratio.Checked)
{ {
_newWidth = _effect.Width / 100d * percent; _newWidth = _effect.Width / 100d * percent;
DisplayWidth(); DisplayWidth();
} }
} }
} }
private void Textbox_Validating(object sender, System.ComponentModel.CancelEventArgs e) private void Textbox_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{ {
Validate(sender); Validate(sender);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Combobox_SelectedIndexChanged(object sender, EventArgs e) private void Combobox_SelectedIndexChanged(object sender, EventArgs e)
{ {
if (Validate(textbox_width)) if (Validate(textbox_width))
{ {
DisplayWidth(); DisplayWidth();
} }
if (Validate(textbox_height)) if (Validate(textbox_height))
{ {
DisplayHeight(); DisplayHeight();
} }
} }
} }
} }

View file

@ -1,440 +1,439 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Windows.Forms; using Greenshot.Base.Controls;
using Greenshot.Base.Controls;
namespace Greenshot.Editor.Forms {
namespace Greenshot.Forms { partial class TornEdgeSettingsForm {
partial class TornEdgeSettingsForm { /// <summary>
/// <summary> /// Required designer variable.
/// Required designer variable. /// </summary>
/// </summary> private System.ComponentModel.IContainer components = null;
private System.ComponentModel.IContainer components = null;
/// <summary>
/// <summary> /// Clean up any resources being used.
/// Clean up any resources being used. /// </summary>
/// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) {
protected override void Dispose(bool disposing) { if (disposing && (components != null)) {
if (disposing && (components != null)) { components.Dispose();
components.Dispose(); }
} base.Dispose(disposing);
base.Dispose(disposing); }
}
#region Windows Form Designer generated code
#region Windows Form Designer generated code
/// <summary>
/// <summary> /// Required method for Designer support - do not modify
/// Required method for Designer support - do not modify /// the contents of this method with the code editor.
/// the contents of this method with the code editor. /// </summary>
/// </summary> private void InitializeComponent() {
private void InitializeComponent() { this.thickness = new System.Windows.Forms.NumericUpDown();
this.thickness = new System.Windows.Forms.NumericUpDown(); this.offsetX = new System.Windows.Forms.NumericUpDown();
this.offsetX = new System.Windows.Forms.NumericUpDown(); this.label3 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label(); this.offsetY = new System.Windows.Forms.NumericUpDown();
this.offsetY = new System.Windows.Forms.NumericUpDown(); this.shadowDarkness = new System.Windows.Forms.TrackBar();
this.shadowDarkness = new System.Windows.Forms.TrackBar(); this.buttonOK = new GreenshotButton();
this.buttonOK = new GreenshotButton(); this.buttonCancel = new GreenshotButton();
this.buttonCancel = new GreenshotButton(); this.labelDarkness = new GreenshotLabel();
this.labelDarkness = new GreenshotLabel(); this.labelOffset = new GreenshotLabel();
this.labelOffset = new GreenshotLabel(); this.labelThickness = new GreenshotLabel();
this.labelThickness = new GreenshotLabel(); this.toothsize = new System.Windows.Forms.NumericUpDown();
this.toothsize = new System.Windows.Forms.NumericUpDown(); this.label_toothsize = new GreenshotLabel();
this.label_toothsize = new GreenshotLabel(); this.label_horizontaltoothrange = new GreenshotLabel();
this.label_horizontaltoothrange = new GreenshotLabel(); this.horizontaltoothrange = new System.Windows.Forms.NumericUpDown();
this.horizontaltoothrange = new System.Windows.Forms.NumericUpDown(); this.labelVerticaltoothrange = new GreenshotLabel();
this.labelVerticaltoothrange = new GreenshotLabel(); this.verticaltoothrange = new System.Windows.Forms.NumericUpDown();
this.verticaltoothrange = new System.Windows.Forms.NumericUpDown(); this.top = new GreenshotCheckBox();
this.top = new GreenshotCheckBox(); this.right = new GreenshotCheckBox();
this.right = new GreenshotCheckBox(); this.bottom = new GreenshotCheckBox();
this.bottom = new GreenshotCheckBox(); this.left = new GreenshotCheckBox();
this.left = new GreenshotCheckBox(); this.shadowCheckbox = new GreenshotCheckBox();
this.shadowCheckbox = new GreenshotCheckBox(); this.all = new GreenshotCheckBox();
this.all = new GreenshotCheckBox(); ((System.ComponentModel.ISupportInitialize)(this.thickness)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.thickness)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.offsetX)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetY)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.offsetY)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.shadowDarkness)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.shadowDarkness)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.toothsize)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.toothsize)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.horizontaltoothrange)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.horizontaltoothrange)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.verticaltoothrange)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.verticaltoothrange)).BeginInit(); this.SuspendLayout();
this.SuspendLayout(); //
// // thickness
// thickness //
// this.thickness.Location = new System.Drawing.Point(173, 35);
this.thickness.Location = new System.Drawing.Point(173, 35); this.thickness.Maximum = new decimal(new int[] {
this.thickness.Maximum = new decimal(new int[] { 20,
20, 0,
0, 0,
0, 0});
0}); this.thickness.Minimum = new decimal(new int[] {
this.thickness.Minimum = new decimal(new int[] { 1,
1, 0,
0, 0,
0, 0});
0}); this.thickness.Name = "thickness";
this.thickness.Name = "thickness"; this.thickness.Size = new System.Drawing.Size(45, 20);
this.thickness.Size = new System.Drawing.Size(45, 20); this.thickness.TabIndex = 2;
this.thickness.TabIndex = 2; this.thickness.Value = new decimal(new int[] {
this.thickness.Value = new decimal(new int[] { 9,
9, 0,
0, 0,
0, 0});
0}); //
// // offsetX
// offsetX //
// this.offsetX.Location = new System.Drawing.Point(102, 61);
this.offsetX.Location = new System.Drawing.Point(102, 61); this.offsetX.Maximum = new decimal(new int[] {
this.offsetX.Maximum = new decimal(new int[] { 20,
20, 0,
0, 0,
0, 0});
0}); this.offsetX.Minimum = new decimal(new int[] {
this.offsetX.Minimum = new decimal(new int[] { 20,
20, 0,
0, 0,
0, -2147483648});
-2147483648}); this.offsetX.Name = "offsetX";
this.offsetX.Name = "offsetX"; this.offsetX.Size = new System.Drawing.Size(45, 20);
this.offsetX.Size = new System.Drawing.Size(45, 20); this.offsetX.TabIndex = 3;
this.offsetX.TabIndex = 3; this.offsetX.Value = new decimal(new int[] {
this.offsetX.Value = new decimal(new int[] { 1,
1, 0,
0, 0,
0, -2147483648});
-2147483648}); //
// // label3
// label3 //
// this.label3.Location = new System.Drawing.Point(153, 63);
this.label3.Location = new System.Drawing.Point(153, 63); this.label3.Name = "label3";
this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(12, 13);
this.label3.Size = new System.Drawing.Size(12, 13); this.label3.TabIndex = 5;
this.label3.TabIndex = 5; this.label3.Text = "x";
this.label3.Text = "x"; //
// // offsetY
// offsetY //
// this.offsetY.Location = new System.Drawing.Point(173, 61);
this.offsetY.Location = new System.Drawing.Point(173, 61); this.offsetY.Maximum = new decimal(new int[] {
this.offsetY.Maximum = new decimal(new int[] { 20,
20, 0,
0, 0,
0, 0});
0}); this.offsetY.Minimum = new decimal(new int[] {
this.offsetY.Minimum = new decimal(new int[] { 20,
20, 0,
0, 0,
0, -2147483648});
-2147483648}); this.offsetY.Name = "offsetY";
this.offsetY.Name = "offsetY"; this.offsetY.Size = new System.Drawing.Size(45, 20);
this.offsetY.Size = new System.Drawing.Size(45, 20); this.offsetY.TabIndex = 4;
this.offsetY.TabIndex = 4; this.offsetY.Value = new decimal(new int[] {
this.offsetY.Value = new decimal(new int[] { 1,
1, 0,
0, 0,
0, -2147483648});
-2147483648}); //
// // shadowDarkness
// shadowDarkness //
// this.shadowDarkness.Location = new System.Drawing.Point(102, 87);
this.shadowDarkness.Location = new System.Drawing.Point(102, 87); this.shadowDarkness.Maximum = 40;
this.shadowDarkness.Maximum = 40; this.shadowDarkness.Minimum = 1;
this.shadowDarkness.Minimum = 1; this.shadowDarkness.Name = "shadowDarkness";
this.shadowDarkness.Name = "shadowDarkness"; this.shadowDarkness.Size = new System.Drawing.Size(116, 45);
this.shadowDarkness.Size = new System.Drawing.Size(116, 45); this.shadowDarkness.TabIndex = 5;
this.shadowDarkness.TabIndex = 5; this.shadowDarkness.Value = 40;
this.shadowDarkness.Value = 40; //
// // buttonOK
// buttonOK //
// this.buttonOK.LanguageKey = "OK";
this.buttonOK.LanguageKey = "OK"; this.buttonOK.Location = new System.Drawing.Point(334, 192);
this.buttonOK.Location = new System.Drawing.Point(334, 192); this.buttonOK.Name = "buttonOK";
this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.TabIndex = 20;
this.buttonOK.TabIndex = 20; this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); //
// // buttonCancel
// buttonCancel //
// this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.LanguageKey = "CANCEL"; this.buttonCancel.Location = new System.Drawing.Point(415, 192);
this.buttonCancel.Location = new System.Drawing.Point(415, 192); this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.TabIndex = 21;
this.buttonCancel.TabIndex = 21; this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.UseVisualStyleBackColor = true; //
// // labelDarkness
// labelDarkness //
// this.labelDarkness.LanguageKey = "editor_dropshadow_darkness";
this.labelDarkness.LanguageKey = "editor_dropshadow_darkness"; this.labelDarkness.Location = new System.Drawing.Point(12, 97);
this.labelDarkness.Location = new System.Drawing.Point(12, 97); this.labelDarkness.Name = "labelDarkness";
this.labelDarkness.Name = "labelDarkness"; this.labelDarkness.Size = new System.Drawing.Size(92, 13);
this.labelDarkness.Size = new System.Drawing.Size(92, 13); this.labelDarkness.TabIndex = 13;
this.labelDarkness.TabIndex = 13; this.labelDarkness.Text = "Shadow darkness";
this.labelDarkness.Text = "Shadow darkness"; //
// // labelOffset
// labelOffset //
// this.labelOffset.LanguageKey = "editor_dropshadow_offset";
this.labelOffset.LanguageKey = "editor_dropshadow_offset"; this.labelOffset.Location = new System.Drawing.Point(12, 63);
this.labelOffset.Location = new System.Drawing.Point(12, 63); this.labelOffset.Name = "labelOffset";
this.labelOffset.Name = "labelOffset"; this.labelOffset.Size = new System.Drawing.Size(75, 13);
this.labelOffset.Size = new System.Drawing.Size(75, 13); this.labelOffset.TabIndex = 14;
this.labelOffset.TabIndex = 14; //
// // labelThickness
// labelThickness //
// this.labelThickness.LanguageKey = "editor_dropshadow_thickness";
this.labelThickness.LanguageKey = "editor_dropshadow_thickness"; this.labelThickness.Location = new System.Drawing.Point(12, 37);
this.labelThickness.Location = new System.Drawing.Point(12, 37); this.labelThickness.Name = "labelThickness";
this.labelThickness.Name = "labelThickness"; this.labelThickness.Size = new System.Drawing.Size(94, 13);
this.labelThickness.Size = new System.Drawing.Size(94, 13); this.labelThickness.TabIndex = 15;
this.labelThickness.TabIndex = 15; //
// // toothsize
// toothsize //
// this.toothsize.Location = new System.Drawing.Point(173, 138);
this.toothsize.Location = new System.Drawing.Point(173, 138); this.toothsize.Maximum = new decimal(new int[] {
this.toothsize.Maximum = new decimal(new int[] { 40,
40, 0,
0, 0,
0, 0});
0}); this.toothsize.Minimum = new decimal(new int[] {
this.toothsize.Minimum = new decimal(new int[] { 2,
2, 0,
0, 0,
0, 0});
0}); this.toothsize.Name = "toothsize";
this.toothsize.Name = "toothsize"; this.toothsize.Size = new System.Drawing.Size(45, 20);
this.toothsize.Size = new System.Drawing.Size(45, 20); this.toothsize.TabIndex = 6;
this.toothsize.TabIndex = 6; this.toothsize.Value = new decimal(new int[] {
this.toothsize.Value = new decimal(new int[] { 12,
12, 0,
0, 0,
0, 0});
0}); //
// // label_toothsize
// label_toothsize //
// this.label_toothsize.LanguageKey = "editor_tornedge_toothsize";
this.label_toothsize.LanguageKey = "editor_tornedge_toothsize"; this.label_toothsize.Location = new System.Drawing.Point(12, 140);
this.label_toothsize.Location = new System.Drawing.Point(12, 140); this.label_toothsize.Name = "label_toothsize";
this.label_toothsize.Name = "label_toothsize"; this.label_toothsize.Size = new System.Drawing.Size(56, 13);
this.label_toothsize.Size = new System.Drawing.Size(56, 13); this.label_toothsize.TabIndex = 17;
this.label_toothsize.TabIndex = 17; //
// // label_horizontaltoothrange
// label_horizontaltoothrange //
// this.label_horizontaltoothrange.LanguageKey = "editor_tornedge_horizontaltoothrange";
this.label_horizontaltoothrange.LanguageKey = "editor_tornedge_horizontaltoothrange"; this.label_horizontaltoothrange.Location = new System.Drawing.Point(12, 166);
this.label_horizontaltoothrange.Location = new System.Drawing.Point(12, 166); this.label_horizontaltoothrange.Name = "label_horizontaltoothrange";
this.label_horizontaltoothrange.Name = "label_horizontaltoothrange"; this.label_horizontaltoothrange.Size = new System.Drawing.Size(111, 13);
this.label_horizontaltoothrange.Size = new System.Drawing.Size(111, 13); this.label_horizontaltoothrange.TabIndex = 19; //
this.label_horizontaltoothrange.TabIndex = 19; // // horizontaltoothrange
// horizontaltoothrange //
// this.horizontaltoothrange.Location = new System.Drawing.Point(173, 164);
this.horizontaltoothrange.Location = new System.Drawing.Point(173, 164); this.horizontaltoothrange.Maximum = new decimal(new int[] {
this.horizontaltoothrange.Maximum = new decimal(new int[] { 40,
40, 0,
0, 0,
0, 0});
0}); this.horizontaltoothrange.Minimum = new decimal(new int[] {
this.horizontaltoothrange.Minimum = new decimal(new int[] { 2,
2, 0,
0, 0,
0, 0});
0}); this.horizontaltoothrange.Name = "horizontaltoothrange";
this.horizontaltoothrange.Name = "horizontaltoothrange"; this.horizontaltoothrange.Size = new System.Drawing.Size(45, 20);
this.horizontaltoothrange.Size = new System.Drawing.Size(45, 20); this.horizontaltoothrange.TabIndex = 7;
this.horizontaltoothrange.TabIndex = 7; this.horizontaltoothrange.Value = new decimal(new int[] {
this.horizontaltoothrange.Value = new decimal(new int[] { 20,
20, 0,
0, 0,
0, 0});
0}); //
// // labelVerticaltoothrange
// labelVerticaltoothrange //
// this.labelVerticaltoothrange.LanguageKey = "editor_tornedge_verticaltoothrange";
this.labelVerticaltoothrange.LanguageKey = "editor_tornedge_verticaltoothrange"; this.labelVerticaltoothrange.Location = new System.Drawing.Point(12, 192);
this.labelVerticaltoothrange.Location = new System.Drawing.Point(12, 192); this.labelVerticaltoothrange.Name = "labelVerticaltoothrange";
this.labelVerticaltoothrange.Name = "labelVerticaltoothrange"; this.labelVerticaltoothrange.Size = new System.Drawing.Size(99, 13);
this.labelVerticaltoothrange.Size = new System.Drawing.Size(99, 13); this.labelVerticaltoothrange.TabIndex = 21;
this.labelVerticaltoothrange.TabIndex = 21; //
// // verticaltoothrange
// verticaltoothrange //
// this.verticaltoothrange.Location = new System.Drawing.Point(173, 190);
this.verticaltoothrange.Location = new System.Drawing.Point(173, 190); this.verticaltoothrange.Maximum = new decimal(new int[] {
this.verticaltoothrange.Maximum = new decimal(new int[] { 40,
40, 0,
0, 0,
0, 0});
0}); this.verticaltoothrange.Minimum = new decimal(new int[] {
this.verticaltoothrange.Minimum = new decimal(new int[] { 2,
2, 0,
0, 0,
0, 0});
0}); this.verticaltoothrange.Name = "verticaltoothrange";
this.verticaltoothrange.Name = "verticaltoothrange"; this.verticaltoothrange.Size = new System.Drawing.Size(45, 20);
this.verticaltoothrange.Size = new System.Drawing.Size(45, 20); this.verticaltoothrange.TabIndex = 8;
this.verticaltoothrange.TabIndex = 8; this.verticaltoothrange.Value = new decimal(new int[] {
this.verticaltoothrange.Value = new decimal(new int[] { 20,
20, 0,
0, 0,
0, 0});
0}); //
// // top
// top //
// this.top.CheckAlign = System.Drawing.ContentAlignment.BottomCenter;
this.top.CheckAlign = System.Drawing.ContentAlignment.BottomCenter; this.top.LanguageKey = "editor_tornedge_top";
this.top.LanguageKey = "editor_tornedge_top"; this.top.Location = new System.Drawing.Point(263, 35);
this.top.Location = new System.Drawing.Point(263, 35); this.top.Name = "top";
this.top.Name = "top"; this.top.Size = new System.Drawing.Size(228, 33);
this.top.Size = new System.Drawing.Size(228, 33); this.top.TabIndex = 10;
this.top.TabIndex = 10; this.top.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
this.top.TextAlign = System.Drawing.ContentAlignment.BottomCenter; this.top.UseVisualStyleBackColor = true;
this.top.UseVisualStyleBackColor = true; this.top.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged);
this.top.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged); //
// // right
// right //
// this.right.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.right.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.right.LanguageKey = "editor_tornedge_right";
this.right.LanguageKey = "editor_tornedge_right"; this.right.Location = new System.Drawing.Point(393, 60);
this.right.Location = new System.Drawing.Point(393, 60); this.right.Name = "right";
this.right.Name = "right"; this.right.Size = new System.Drawing.Size(98, 49);
this.right.Size = new System.Drawing.Size(98, 49); this.right.TabIndex = 11;
this.right.TabIndex = 11; this.right.UseVisualStyleBackColor = true;
this.right.UseVisualStyleBackColor = true; this.right.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged);
this.right.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged); //
// // bottom
// bottom //
// this.bottom.CheckAlign = System.Drawing.ContentAlignment.TopCenter;
this.bottom.CheckAlign = System.Drawing.ContentAlignment.TopCenter; this.bottom.LanguageKey = "editor_tornedge_bottom";
this.bottom.LanguageKey = "editor_tornedge_bottom"; this.bottom.Location = new System.Drawing.Point(263, 98);
this.bottom.Location = new System.Drawing.Point(263, 98); this.bottom.Name = "bottom";
this.bottom.Name = "bottom"; this.bottom.Size = new System.Drawing.Size(228, 31);
this.bottom.Size = new System.Drawing.Size(228, 31); this.bottom.TabIndex = 12;
this.bottom.TabIndex = 12; this.bottom.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.bottom.TextAlign = System.Drawing.ContentAlignment.TopCenter; this.bottom.UseVisualStyleBackColor = true;
this.bottom.UseVisualStyleBackColor = true; this.bottom.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged);
this.bottom.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged); //
// // left
// left //
// this.left.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
this.left.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; this.left.LanguageKey = "editor_tornedge_left";
this.left.LanguageKey = "editor_tornedge_left"; this.left.Location = new System.Drawing.Point(243, 60);
this.left.Location = new System.Drawing.Point(243, 60); this.left.Name = "left";
this.left.Name = "left"; this.left.Size = new System.Drawing.Size(118, 49);
this.left.Size = new System.Drawing.Size(118, 49); this.left.TabIndex = 13;
this.left.TabIndex = 13; this.left.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.left.TextAlign = System.Drawing.ContentAlignment.MiddleRight; this.left.UseVisualStyleBackColor = true;
this.left.UseVisualStyleBackColor = true; this.left.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged);
this.left.CheckedChanged += new System.EventHandler(this.AnySideCheckedChanged); //
// // shadowCheckbox
// shadowCheckbox //
// this.shadowCheckbox.LanguageKey = "editor_tornedge_shadow";
this.shadowCheckbox.LanguageKey = "editor_tornedge_shadow"; this.shadowCheckbox.Location = new System.Drawing.Point(12, 12);
this.shadowCheckbox.Location = new System.Drawing.Point(12, 12); this.shadowCheckbox.Name = "shadowCheckbox";
this.shadowCheckbox.Name = "shadowCheckbox"; this.shadowCheckbox.Size = new System.Drawing.Size(110, 17);
this.shadowCheckbox.Size = new System.Drawing.Size(110, 17); this.shadowCheckbox.TabIndex = 1;
this.shadowCheckbox.TabIndex = 1; this.shadowCheckbox.UseVisualStyleBackColor = true;
this.shadowCheckbox.UseVisualStyleBackColor = true; this.shadowCheckbox.CheckedChanged += new System.EventHandler(this.ShadowCheckbox_CheckedChanged);
this.shadowCheckbox.CheckedChanged += new System.EventHandler(this.ShadowCheckbox_CheckedChanged); //
// // all
// all //
// this.all.LanguageKey = "editor_tornedge_all";
this.all.LanguageKey = "editor_tornedge_all"; this.all.Location = new System.Drawing.Point(251, 12);
this.all.Location = new System.Drawing.Point(251, 12); this.all.Name = "all";
this.all.Name = "all"; this.all.Size = new System.Drawing.Size(88, 17);
this.all.Size = new System.Drawing.Size(88, 17); this.all.TabIndex = 9;
this.all.TabIndex = 9; this.all.UseVisualStyleBackColor = true;
this.all.UseVisualStyleBackColor = true; this.all.CheckedChanged += new System.EventHandler(this.all_CheckedChanged);
this.all.CheckedChanged += new System.EventHandler(this.all_CheckedChanged); //
// // TornEdgeSettingsForm
// TornEdgeSettingsForm //
// this.AcceptButton = this.buttonOK;
this.AcceptButton = this.buttonOK; this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.CancelButton = this.buttonCancel;
this.CancelButton = this.buttonCancel; this.ClientSize = new System.Drawing.Size(502, 223);
this.ClientSize = new System.Drawing.Size(502, 223); this.ControlBox = false;
this.ControlBox = false; this.Controls.Add(this.all);
this.Controls.Add(this.all); this.Controls.Add(this.shadowCheckbox);
this.Controls.Add(this.shadowCheckbox); this.Controls.Add(this.left);
this.Controls.Add(this.left); this.Controls.Add(this.bottom);
this.Controls.Add(this.bottom); this.Controls.Add(this.right);
this.Controls.Add(this.right); this.Controls.Add(this.top);
this.Controls.Add(this.top); this.Controls.Add(this.labelVerticaltoothrange);
this.Controls.Add(this.labelVerticaltoothrange); this.Controls.Add(this.verticaltoothrange);
this.Controls.Add(this.verticaltoothrange); this.Controls.Add(this.label_horizontaltoothrange);
this.Controls.Add(this.label_horizontaltoothrange); this.Controls.Add(this.horizontaltoothrange);
this.Controls.Add(this.horizontaltoothrange); this.Controls.Add(this.label_toothsize);
this.Controls.Add(this.label_toothsize); this.Controls.Add(this.toothsize);
this.Controls.Add(this.toothsize); this.Controls.Add(this.labelThickness);
this.Controls.Add(this.labelThickness); this.Controls.Add(this.labelOffset);
this.Controls.Add(this.labelOffset); this.Controls.Add(this.labelDarkness);
this.Controls.Add(this.labelDarkness); this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonOK);
this.Controls.Add(this.buttonOK); this.Controls.Add(this.shadowDarkness);
this.Controls.Add(this.shadowDarkness); this.Controls.Add(this.offsetY);
this.Controls.Add(this.offsetY); this.Controls.Add(this.label3);
this.Controls.Add(this.label3); this.Controls.Add(this.offsetX);
this.Controls.Add(this.offsetX); this.Controls.Add(this.thickness);
this.Controls.Add(this.thickness); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.LanguageKey = "editor_tornedge_settings";
this.LanguageKey = "editor_tornedge_settings"; this.MaximizeBox = false;
this.MaximizeBox = false; this.MinimizeBox = false;
this.MinimizeBox = false; this.Name = "TornEdgeSettingsForm";
this.Name = "TornEdgeSettingsForm"; this.ShowIcon = false;
this.ShowIcon = false; this.Load += new System.EventHandler(this.TornEdgeSettingsForm_Load);
this.Load += new System.EventHandler(this.TornEdgeSettingsForm_Load); ((System.ComponentModel.ISupportInitialize)(this.thickness)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.thickness)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetX)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.offsetX)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.offsetY)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.offsetY)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.shadowDarkness)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.shadowDarkness)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.toothsize)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.toothsize)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.horizontaltoothrange)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.horizontaltoothrange)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.verticaltoothrange)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.verticaltoothrange)).EndInit(); this.ResumeLayout(false);
this.ResumeLayout(false); this.PerformLayout();
this.PerformLayout();
}
}
#endregion
#endregion
private System.Windows.Forms.NumericUpDown thickness;
private System.Windows.Forms.NumericUpDown thickness; private System.Windows.Forms.NumericUpDown offsetX;
private System.Windows.Forms.NumericUpDown offsetX; private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label3; private System.Windows.Forms.NumericUpDown offsetY;
private System.Windows.Forms.NumericUpDown offsetY; private System.Windows.Forms.TrackBar shadowDarkness;
private System.Windows.Forms.TrackBar shadowDarkness; private GreenshotButton buttonOK;
private GreenshotButton buttonOK; private GreenshotButton buttonCancel;
private GreenshotButton buttonCancel; private GreenshotLabel labelDarkness;
private GreenshotLabel labelDarkness; private GreenshotLabel labelOffset;
private GreenshotLabel labelOffset; private GreenshotLabel labelThickness;
private GreenshotLabel labelThickness; private System.Windows.Forms.NumericUpDown toothsize;
private System.Windows.Forms.NumericUpDown toothsize; private GreenshotLabel label_toothsize;
private GreenshotLabel label_toothsize; private GreenshotLabel label_horizontaltoothrange;
private GreenshotLabel label_horizontaltoothrange; private System.Windows.Forms.NumericUpDown horizontaltoothrange;
private System.Windows.Forms.NumericUpDown horizontaltoothrange; private GreenshotLabel labelVerticaltoothrange;
private GreenshotLabel labelVerticaltoothrange; private System.Windows.Forms.NumericUpDown verticaltoothrange;
private System.Windows.Forms.NumericUpDown verticaltoothrange; private GreenshotCheckBox top;
private GreenshotCheckBox top; private GreenshotCheckBox right;
private GreenshotCheckBox right; private GreenshotCheckBox bottom;
private GreenshotCheckBox bottom; private GreenshotCheckBox left;
private GreenshotCheckBox left; private GreenshotCheckBox shadowCheckbox;
private GreenshotCheckBox shadowCheckbox; private GreenshotCheckBox all;
private GreenshotCheckBox all; }
}
} }

View file

@ -1,115 +1,115 @@
/* /*
* Greenshot - a free and open source screenshot tool * Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
* *
* For more information see: https://getgreenshot.org/ * For more information see: https://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or * the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Effects; using Greenshot.Base.Effects;
namespace Greenshot.Forms namespace Greenshot.Editor.Forms
{ {
public partial class TornEdgeSettingsForm : BaseForm public partial class TornEdgeSettingsForm : EditorForm
{ {
private readonly TornEdgeEffect _effect; private readonly TornEdgeEffect _effect;
public TornEdgeSettingsForm(TornEdgeEffect effect) public TornEdgeSettingsForm(TornEdgeEffect effect)
{ {
_effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
ShowSettings(); ShowSettings();
} }
private void ShowSettings() private void ShowSettings()
{ {
shadowCheckbox.Checked = _effect.GenerateShadow; shadowCheckbox.Checked = _effect.GenerateShadow;
// Fix to prevent BUG-1753 // Fix to prevent BUG-1753
shadowDarkness.Value = Math.Max(shadowDarkness.Minimum, Math.Min(shadowDarkness.Maximum, (int) (_effect.Darkness * shadowDarkness.Maximum))); shadowDarkness.Value = Math.Max(shadowDarkness.Minimum, Math.Min(shadowDarkness.Maximum, (int) (_effect.Darkness * shadowDarkness.Maximum)));
offsetX.Value = _effect.ShadowOffset.X; offsetX.Value = _effect.ShadowOffset.X;
offsetY.Value = _effect.ShadowOffset.Y; offsetY.Value = _effect.ShadowOffset.Y;
toothsize.Value = _effect.ToothHeight; toothsize.Value = _effect.ToothHeight;
verticaltoothrange.Value = _effect.VerticalToothRange; verticaltoothrange.Value = _effect.VerticalToothRange;
horizontaltoothrange.Value = _effect.HorizontalToothRange; horizontaltoothrange.Value = _effect.HorizontalToothRange;
top.Checked = _effect.Edges[0]; top.Checked = _effect.Edges[0];
right.Checked = _effect.Edges[1]; right.Checked = _effect.Edges[1];
bottom.Checked = _effect.Edges[2]; bottom.Checked = _effect.Edges[2];
left.Checked = _effect.Edges[3]; left.Checked = _effect.Edges[3];
} }
private void ButtonOK_Click(object sender, EventArgs e) private void ButtonOK_Click(object sender, EventArgs e)
{ {
_effect.Darkness = shadowDarkness.Value / (float) 40; _effect.Darkness = shadowDarkness.Value / (float) 40;
_effect.ShadowOffset = new Point((int) offsetX.Value, (int) offsetY.Value); _effect.ShadowOffset = new Point((int) offsetX.Value, (int) offsetY.Value);
_effect.ShadowSize = (int) thickness.Value; _effect.ShadowSize = (int) thickness.Value;
_effect.ToothHeight = (int) toothsize.Value; _effect.ToothHeight = (int) toothsize.Value;
_effect.VerticalToothRange = (int) verticaltoothrange.Value; _effect.VerticalToothRange = (int) verticaltoothrange.Value;
_effect.HorizontalToothRange = (int) horizontaltoothrange.Value; _effect.HorizontalToothRange = (int) horizontaltoothrange.Value;
_effect.Edges = new[] _effect.Edges = new[]
{ {
top.Checked, right.Checked, bottom.Checked, left.Checked top.Checked, right.Checked, bottom.Checked, left.Checked
}; };
_effect.GenerateShadow = shadowCheckbox.Checked; _effect.GenerateShadow = shadowCheckbox.Checked;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
private void ShadowCheckbox_CheckedChanged(object sender, EventArgs e) private void ShadowCheckbox_CheckedChanged(object sender, EventArgs e)
{ {
thickness.Enabled = shadowCheckbox.Checked; thickness.Enabled = shadowCheckbox.Checked;
offsetX.Enabled = shadowCheckbox.Checked; offsetX.Enabled = shadowCheckbox.Checked;
offsetY.Enabled = shadowCheckbox.Checked; offsetY.Enabled = shadowCheckbox.Checked;
shadowDarkness.Enabled = shadowCheckbox.Checked; shadowDarkness.Enabled = shadowCheckbox.Checked;
} }
private void all_CheckedChanged(object sender, EventArgs e) private void all_CheckedChanged(object sender, EventArgs e)
{ {
AnySideChangeChecked(top, all.Checked); AnySideChangeChecked(top, all.Checked);
AnySideChangeChecked(right, all.Checked); AnySideChangeChecked(right, all.Checked);
AnySideChangeChecked(bottom, all.Checked); AnySideChangeChecked(bottom, all.Checked);
AnySideChangeChecked(left, all.Checked); AnySideChangeChecked(left, all.Checked);
} }
private void AnySideCheckedChanged(object sender, EventArgs e) private void AnySideCheckedChanged(object sender, EventArgs e)
{ {
all.CheckedChanged -= all_CheckedChanged; all.CheckedChanged -= all_CheckedChanged;
all.Checked = top.Checked && right.Checked && bottom.Checked && left.Checked; all.Checked = top.Checked && right.Checked && bottom.Checked && left.Checked;
all.CheckedChanged += all_CheckedChanged; all.CheckedChanged += all_CheckedChanged;
} }
/// <summary> /// <summary>
/// changes the Checked property of top/right/bottom/left checkboxes without triggering AnySideCheckedChange /// changes the Checked property of top/right/bottom/left checkboxes without triggering AnySideCheckedChange
/// </summary> /// </summary>
/// <param name="cb">Checkbox to change Checked</param> /// <param name="cb">Checkbox to change Checked</param>
/// <param name="status">true to check</param> /// <param name="status">true to check</param>
private void AnySideChangeChecked(CheckBox cb, bool status) private void AnySideChangeChecked(CheckBox cb, bool status)
{ {
if (status != cb.Checked) if (status != cb.Checked)
{ {
cb.CheckedChanged -= AnySideCheckedChanged; cb.CheckedChanged -= AnySideCheckedChanged;
cb.Checked = status; cb.Checked = status;
cb.CheckedChanged += AnySideCheckedChanged; cb.CheckedChanged += AnySideCheckedChanged;
} }
} }
private void TornEdgeSettingsForm_Load(object sender, EventArgs e) private void TornEdgeSettingsForm_Load(object sender, EventArgs e)
{ {
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show more