From 9df25bdd7626611f1c868752b239e8161df19680 Mon Sep 17 00:00:00 2001 From: RKrom Date: Wed, 5 Nov 2014 12:38:01 +0100 Subject: [PATCH] FEATURE-758: This commit enhances the already made changes to also fix the size of the icons in the destination picker and the context menu. On top of that, if a large icon size is selected we try to get a larger (more defined) icon from the application unfortunately that doesn't improve the build in icons. --- .../Configuration/EditorConfiguration.cs | 6 +-- ...ontextMenuToolStripProfessionalRenderer.cs | 45 +++++++++++++++++++ Greenshot/Forms/ImageEditorForm.Designer.cs | 10 ++--- Greenshot/Forms/MainForm.Designer.cs | 5 ++- Greenshot/Forms/SettingsForm.cs | 10 +++-- Greenshot/Forms/ToolStripMenuSelectList.cs | 10 ++++- Greenshot/Greenshot.csproj | 1 + .../additional_files/readme.txt.template | 2 +- GreenshotPlugin/Core/AbstractDestination.cs | 1 + GreenshotPlugin/Core/CoreConfiguration.cs | 33 ++++++++++++++ GreenshotPlugin/Core/ImageHelper.cs | 8 +++- GreenshotPlugin/Core/PluginUtils.cs | 15 ++++--- GreenshotPlugin/Core/WindowsHelper.cs | 10 ++++- 13 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 Greenshot/Controls/ContextMenuToolStripProfessionalRenderer.cs diff --git a/Greenshot/Configuration/EditorConfiguration.cs b/Greenshot/Configuration/EditorConfiguration.cs index 8ddff7897..9dc0c25f4 100644 --- a/Greenshot/Configuration/EditorConfiguration.cs +++ b/Greenshot/Configuration/EditorConfiguration.cs @@ -56,18 +56,14 @@ namespace Greenshot.Configuration { public int FreehandSensitivity; [IniProperty("SuppressSaveDialogAtClose", Description="Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue="False")] public bool SuppressSaveDialogAtClose; - [IniProperty("ButtonIconSize", Description = "Defines the size of the icons for the buttons in the editor, default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")] - public Size ButtonIconSize; public override void AfterLoad() { base.AfterLoad(); if (RecentColors == null) { RecentColors = new List(); } - if (ButtonIconSize == Size.Empty) { - ButtonIconSize = new Size(16,16); - } } + /// Type of the class for which to create the field /// FieldType of the field to construct /// FieldType of the field to construct diff --git a/Greenshot/Controls/ContextMenuToolStripProfessionalRenderer.cs b/Greenshot/Controls/ContextMenuToolStripProfessionalRenderer.cs new file mode 100644 index 000000000..738d277ea --- /dev/null +++ b/Greenshot/Controls/ContextMenuToolStripProfessionalRenderer.cs @@ -0,0 +1,45 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2014 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: http://getgreenshot.org/ + * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 . + */ + +using Greenshot.IniFile; +using GreenshotPlugin.Core; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace Greenshot.Controls { + /// + /// ToolStripProfessionalRenderer which draws the Check correctly when the icons are larger + /// + public class ContextMenuToolStripProfessionalRenderer : ToolStripProfessionalRenderer { + private static CoreConfiguration coreConfiguration = IniConfig.GetIniSection(); + private static Image scaledCheckbox; + + protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) { + if (scaledCheckbox == null) { + scaledCheckbox = ImageHelper.ResizeImage(e.Image, true, coreConfiguration.IconSize.Width, coreConfiguration.IconSize.Height, null); + } + Rectangle old = e.ImageRectangle; + ToolStripItemImageRenderEventArgs clone = new ToolStripItemImageRenderEventArgs(e.Graphics, e.Item, scaledCheckbox, new Rectangle(old.X, 0, old.Width, old.Height)); + base.OnRenderItemCheck(clone); + } + } +} diff --git a/Greenshot/Forms/ImageEditorForm.Designer.cs b/Greenshot/Forms/ImageEditorForm.Designer.cs index 5fac3aab7..8dc8f7cf9 100644 --- a/Greenshot/Forms/ImageEditorForm.Designer.cs +++ b/Greenshot/Forms/ImageEditorForm.Designer.cs @@ -291,7 +291,7 @@ namespace Greenshot { // toolsToolStrip // this.toolsToolStrip.ClickThrough = true; - this.toolsToolStrip.ImageScalingSize = editorConfiguration.ButtonIconSize; + this.toolsToolStrip.ImageScalingSize = coreConfiguration.IconSize; this.toolsToolStrip.Dock = System.Windows.Forms.DockStyle.None; this.toolsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolsToolStrip.Renderer = new CustomToolStripProfessionalRenderer(); @@ -527,7 +527,7 @@ namespace Greenshot { // menuStrip1 // this.menuStrip1.ClickThrough = true; - this.menuStrip1.ImageScalingSize = editorConfiguration.ButtonIconSize; + this.menuStrip1.ImageScalingSize = coreConfiguration.IconSize; this.menuStrip1.Dock = System.Windows.Forms.DockStyle.Fill; this.menuStrip1.Stretch = true; this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -856,7 +856,7 @@ namespace Greenshot { // destinationsToolStrip // this.destinationsToolStrip.ClickThrough = true; - this.destinationsToolStrip.ImageScalingSize = editorConfiguration.ButtonIconSize; + this.destinationsToolStrip.ImageScalingSize = coreConfiguration.IconSize; this.destinationsToolStrip.Dock = System.Windows.Forms.DockStyle.Fill; this.destinationsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.destinationsToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1011,7 +1011,7 @@ namespace Greenshot { // propertiesToolStrip // this.propertiesToolStrip.ClickThrough = true; - this.propertiesToolStrip.ImageScalingSize = editorConfiguration.ButtonIconSize; + this.propertiesToolStrip.ImageScalingSize = coreConfiguration.IconSize; this.propertiesToolStrip.Dock = System.Windows.Forms.DockStyle.Fill; this.propertiesToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.propertiesToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1045,7 +1045,7 @@ namespace Greenshot { this.toolStripSeparator10, this.btnConfirm, this.btnCancel}); - this.propertiesToolStrip.MinimumSize = new System.Drawing.Size(0, editorConfiguration.ButtonIconSize.Height + 8); + this.propertiesToolStrip.MinimumSize = new System.Drawing.Size(0, coreConfiguration.IconSize.Height + 8); this.propertiesToolStrip.Name = "propertiesToolStrip"; this.propertiesToolStrip.Stretch = true; this.propertiesToolStrip.TabIndex = 2; diff --git a/Greenshot/Forms/MainForm.Designer.cs b/Greenshot/Forms/MainForm.Designer.cs index 448425932..b1ada93df 100644 --- a/Greenshot/Forms/MainForm.Designer.cs +++ b/Greenshot/Forms/MainForm.Designer.cs @@ -103,9 +103,10 @@ namespace Greenshot { this.toolStripCloseSeparator, this.contextmenu_exit}); this.contextMenu.Name = "contextMenu"; - this.contextMenu.Size = new System.Drawing.Size(171, 392); this.contextMenu.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.ContextMenuClosing); this.contextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuOpening); + this.contextMenu.ImageScalingSize = coreConfiguration.IconSize; + this.contextMenu.Renderer = new Greenshot.Controls.ContextMenuToolStripProfessionalRenderer(); // // contextmenu_capturearea // @@ -204,7 +205,7 @@ namespace Greenshot { // contextmenu_quicksettings // this.contextmenu_quicksettings.Name = "contextmenu_quicksettings"; - this.contextmenu_quicksettings.Size = new System.Drawing.Size(170, 22); + this.contextmenu_quicksettings.Size = new System.Drawing.Size(170, coreConfiguration.IconSize.Height + 8); // // contextmenu_settings // diff --git a/Greenshot/Forms/SettingsForm.cs b/Greenshot/Forms/SettingsForm.cs index acb7dbba8..2b928552a 100644 --- a/Greenshot/Forms/SettingsForm.cs +++ b/Greenshot/Forms/SettingsForm.cs @@ -368,8 +368,9 @@ namespace Greenshot { numericUpDown_daysbetweencheck.Value = coreConfiguration.UpdateCheckInterval; numericUpDown_daysbetweencheck.Enabled = !coreConfiguration.Values["UpdateCheckInterval"].IsFixed; - text_icon_width.Text = editorConfiguration.ButtonIconSize.Width.ToString(CultureInfo.InvariantCulture); - text_icon_height.Text = editorConfiguration.ButtonIconSize.Height.ToString(CultureInfo.InvariantCulture); + coreConfiguration.FixIconSize(); + text_icon_width.Text = coreConfiguration.IconSize.Width.ToString(CultureInfo.InvariantCulture); + text_icon_height.Text = coreConfiguration.IconSize.Height.ToString(CultureInfo.InvariantCulture); CheckDestinationSettings(); } @@ -416,12 +417,13 @@ namespace Greenshot { int iconWidth; if (int.TryParse(text_icon_width.Text, out iconWidth)) { - editorConfiguration.ButtonIconSize.Width = iconWidth; + coreConfiguration.IconSize.Width = iconWidth; } int iconHeight; if (int.TryParse(text_icon_height.Text, out iconHeight)) { - editorConfiguration.ButtonIconSize.Height = iconHeight; + coreConfiguration.IconSize.Height = iconHeight; } + coreConfiguration.FixIconSize(); try { if (checkbox_autostartshortcut.Checked) { // It's checked, so we set the RunUser if the RunAll isn't set. diff --git a/Greenshot/Forms/ToolStripMenuSelectList.cs b/Greenshot/Forms/ToolStripMenuSelectList.cs index 197253f57..3d2b0db53 100644 --- a/Greenshot/Forms/ToolStripMenuSelectList.cs +++ b/Greenshot/Forms/ToolStripMenuSelectList.cs @@ -19,6 +19,8 @@ * along with this program. If not, see . */ +using Greenshot.IniFile; +using GreenshotPlugin.Core; using System; using System.Collections; using System.Collections.Generic; @@ -30,8 +32,10 @@ namespace Greenshot.Forms { /// the ToolStripMenuSelectList makes it possible to have a single or multi-check menu /// public class ToolStripMenuSelectList : ToolStripMenuItem { + private static CoreConfiguration coreConfiguration = IniConfig.GetIniSection(); private bool multiCheckAllowed = false; private bool updateInProgress = false; + private static Image defaultImage = ImageHelper.CreateEmpty(coreConfiguration.IconSize.Width, coreConfiguration.IconSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Color.Transparent, 96f, 96f); /// /// Occurs when one of the list's child element's Checked state changes. /// @@ -45,6 +49,7 @@ namespace Greenshot.Forms { Identifier = identifier; CheckOnClick = false; multiCheckAllowed = allowMultiCheck; + Image = defaultImage; } public ToolStripMenuSelectList() : this(null,false) {} public ToolStripMenuSelectList(Object identifier) : this(identifier,false) {} @@ -142,6 +147,10 @@ namespace Greenshot.Forms { public void AddItem(string label, Image image, Object data, bool isChecked) { ToolStripMenuSelectListItem newItem = new ToolStripMenuSelectListItem(); newItem.Text = label; + if (image == null) { + image = defaultImage; + } + newItem.DisplayStyle = ToolStripItemDisplayStyle.Text; newItem.Image = image; newItem.CheckOnClick = true; newItem.CheckStateChanged += ItemCheckStateChanged; @@ -243,7 +252,6 @@ namespace Greenshot.Forms { /// Also the Checked property hides the normal checked property so we can render our own check /// public class ToolStripMenuSelectListItem : ToolStripMenuItem { - public object Data { get; set; diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index ca24bac6f..8023bd3d0 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -44,6 +44,7 @@ Component + Component diff --git a/Greenshot/releases/additional_files/readme.txt.template b/Greenshot/releases/additional_files/readme.txt.template index 18acc3324..cc0fe2ab3 100644 --- a/Greenshot/releases/additional_files/readme.txt.template +++ b/Greenshot/releases/additional_files/readme.txt.template @@ -11,10 +11,10 @@ Features: * Due to BUG-1667 we had to remove the horizontal text alignment, this afflicts the textbox and the speech bubble. * Added the possibility to select the region to capture by using the keyboard, use the cursor keys to move the cursor (ctrl-key speeds up the movement) and the enter key to mark the start and ending. * FEATURE-757: Greenshot will now store the last used region in the greenshot.ini, which makes it also available after a restart. +* FEATURE-758: Due to the fact that more and more high DPI displays are used, we added a setting to change the icon size. Changes: * JIRA: With JIRA 6.x using the SOAP (Webservice) API the access has gotten really slow, we improved the performance slightly by loading some information parallel. (In Greenshot 2.x we will move to another API.) -* Editor: Due to the amount of high DPI screens, we are testing the possibility to change the icon size. Look for the ButtonIconSize in the editor section of the greenshot.ini. Disadvantage: As the icons are bitmaps, enlarging them does look ugly. Bugs Resolved: * BUG-1667: removed horizontal alignment of textbox in input mode, as it caused problems with textbox focus and could not be implemented consistently anyway (no vertical alignment possible) diff --git a/GreenshotPlugin/Core/AbstractDestination.cs b/GreenshotPlugin/Core/AbstractDestination.cs index 136d5c700..4ec551f6b 100644 --- a/GreenshotPlugin/Core/AbstractDestination.cs +++ b/GreenshotPlugin/Core/AbstractDestination.cs @@ -172,6 +172,7 @@ namespace GreenshotPlugin.Core { // Generate an empty ExportInformation object, for when nothing was selected. ExportInformation exportInformation = new ExportInformation(Designation, Language.GetString("settings_destination_picker")); ContextMenuStrip menu = new ContextMenuStrip(); + menu.ImageScalingSize = configuration.IconSize; menu.Tag = null; menu.Closing += delegate(object source, ToolStripDropDownClosingEventArgs eventArgs) { diff --git a/GreenshotPlugin/Core/CoreConfiguration.cs b/GreenshotPlugin/Core/CoreConfiguration.cs index fa2a5d0e7..fa32e2c19 100644 --- a/GreenshotPlugin/Core/CoreConfiguration.cs +++ b/GreenshotPlugin/Core/CoreConfiguration.cs @@ -256,9 +256,18 @@ namespace GreenshotPlugin.Core { [IniProperty("LastCapturedRegion", Description = "The last used region, for reuse in the capture last region")] public Rectangle LastCapturedRegion; + [IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")] + public Size IconSize; + // Specifies what THIS build is public BuildStates BuildState = BuildStates.RELEASE_CANDIDATE; + public bool UseLargeIcons { + get { + return IconSize.Width >= 32 || IconSize.Height >= 32; + } + } + /// /// A helper method which returns true if the supplied experimental feature is enabled /// @@ -432,6 +441,30 @@ namespace GreenshotPlugin.Core { if (OutputFileReduceColorsTo > 256) { OutputFileReduceColorsTo = 256; } + FixIconSize(); + } + + /// + /// Validation & correction of the icon size + /// + public void FixIconSize() { + if (IconSize == Size.Empty) { + IconSize = new Size(16, 16); + } else { + if (IconSize.Width < 16) { + IconSize.Width = 16; + } + if (IconSize.Width > 256) { + IconSize.Width = 256; + } + if (IconSize.Height < 16) { + IconSize.Height = 16; + } + if (IconSize.Height > 256) { + IconSize.Height = 256; + } + } + } } } \ No newline at end of file diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs index b35556974..8b37804c5 100644 --- a/GreenshotPlugin/Core/ImageHelper.cs +++ b/GreenshotPlugin/Core/ImageHelper.cs @@ -1392,10 +1392,14 @@ namespace GreenshotPlugin.Core { Image newImage = null; if (maintainAspectRatio && canvasUseNewSize) { newImage = CreateEmpty(newWidth, newHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); - matrix.Scale((float)newWidth / sourceImage.Width, (float)newHeight / sourceImage.Height, MatrixOrder.Append); + if (matrix != null) { + matrix.Scale((float)newWidth / sourceImage.Width, (float)newHeight / sourceImage.Height, MatrixOrder.Append); + } } else { newImage = CreateEmpty(destWidth, destHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); - matrix.Scale((float)destWidth / sourceImage.Width, (float)destHeight / sourceImage.Height, MatrixOrder.Append); + if (matrix != null) { + matrix.Scale((float)destWidth / sourceImage.Width, (float)destHeight / sourceImage.Height, MatrixOrder.Append); + } } using (Graphics graphics = Graphics.FromImage(newImage)) { diff --git a/GreenshotPlugin/Core/PluginUtils.cs b/GreenshotPlugin/Core/PluginUtils.cs index 94cbc6242..183a345ad 100644 --- a/GreenshotPlugin/Core/PluginUtils.cs +++ b/GreenshotPlugin/Core/PluginUtils.cs @@ -18,14 +18,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + +using Greenshot.IniFile; +using Greenshot.Plugin; +using GreenshotPlugin.UnmanagedHelpers; +using log4net; +using Microsoft.Win32; using System; using System.Drawing; using System.IO; using System.Windows.Forms; -using Greenshot.Plugin; -using log4net; -using Microsoft.Win32; -using GreenshotPlugin.UnmanagedHelpers; namespace GreenshotPlugin.Core { /// @@ -33,6 +35,7 @@ namespace GreenshotPlugin.Core { /// public static class PluginUtils { private static readonly ILog LOG = LogManager.GetLogger(typeof(PluginUtils)); + private static CoreConfiguration conf = IniConfig.GetIniSection(); private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"; /// @@ -79,12 +82,12 @@ namespace GreenshotPlugin.Core { return null; } try { - using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, false)) { + using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, conf.UseLargeIcons)) { if (appIcon != null) { return appIcon.ToBitmap(); } } - using (Icon appIcon = Shell32.GetFileIcon(path, Shell32.IconSize.Small, false)) { + using (Icon appIcon = Shell32.GetFileIcon(path, conf.UseLargeIcons ? Shell32.IconSize.Large : Shell32.IconSize.Small, false)) { if (appIcon != null) { return appIcon.ToBitmap(); } diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs index 488063fa4..d50ddadeb 100644 --- a/GreenshotPlugin/Core/WindowsHelper.cs +++ b/GreenshotPlugin/Core/WindowsHelper.cs @@ -336,7 +336,15 @@ namespace GreenshotPlugin.Core { IntPtr ICON_BIG = new IntPtr(1); IntPtr ICON_SMALL2 = new IntPtr(2); - IntPtr iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_SMALL2, IntPtr.Zero); + IntPtr iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_BIG, IntPtr.Zero); + if (conf.UseLargeIcons) { + iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_BIG, IntPtr.Zero); + if (iconHandle == IntPtr.Zero) { + iconHandle = User32.GetClassLongWrapper(hwnd, (int)ClassLongIndex.GCL_HICON); + } + } else { + iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_SMALL2, IntPtr.Zero); + } if (iconHandle == IntPtr.Zero) { iconHandle = User32.SendMessage(hwnd, (int)WindowsMessages.WM_GETICON, ICON_SMALL, IntPtr.Zero); }