From d6a5b752c9bed02950e3fc949907795130cd8c6c Mon Sep 17 00:00:00 2001 From: Terry MacDonald Date: Sun, 28 Feb 2021 21:34:59 +1300 Subject: [PATCH] [WIP] partial profiles ILV render creation --- DisplayMagician/UIForms/DisplayProfileForm.cs | 16 +- .../UIForms/ImageListViewRenderers.cs | 362 +++++++++++++----- .../UIForms/ShortcutLibraryForm.cs | 5 +- DisplayMagicianShared/ProfileItem.cs | 5 - 4 files changed, 283 insertions(+), 105 deletions(-) diff --git a/DisplayMagician/UIForms/DisplayProfileForm.cs b/DisplayMagician/UIForms/DisplayProfileForm.cs index 21f8a98..81a8bf9 100644 --- a/DisplayMagician/UIForms/DisplayProfileForm.cs +++ b/DisplayMagician/UIForms/DisplayProfileForm.cs @@ -1,14 +1,12 @@ using System; using System.IO; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; using DisplayMagician.Resources; using DisplayMagicianShared; using Manina.Windows.Forms; -using System.Text.RegularExpressions; -using System.Diagnostics; +using System.Drawing; +using System.Collections.Generic; namespace DisplayMagician.UIForms { @@ -20,11 +18,17 @@ namespace DisplayMagician.UIForms //private static bool _inDialog = false; private static ProfileItem _profileToLoad = null; private ProfileAdaptor _profileAdaptor = new ProfileAdaptor(); + public static Dictionary profileValidity = new Dictionary(); public DisplayProfileForm() { InitializeComponent(); this.AcceptButton = this.btn_save_or_rename; + ilv_saved_profiles.MultiSelect = false; + ilv_saved_profiles.ThumbnailSize = new Size(100, 100); + ilv_saved_profiles.AllowDrag = false; + ilv_saved_profiles.AllowDrop = false; + ilv_saved_profiles.SetRenderer(new ProfileILVRenderer()); } public DisplayProfileForm(ProfileItem profileToLoad) : this() @@ -119,6 +123,8 @@ namespace DisplayMagician.UIForms // Empty the imageListView ilv_saved_profiles.Items.Clear(); + profileValidity.Clear(); + // Fill it back up with the Profiles we have foreach (ProfileItem profile in ProfileRepository.AllProfiles.OrderBy(p=>p.Name)) { @@ -129,6 +135,8 @@ namespace DisplayMagician.UIForms if (_selectedProfile is ProfileItem && _selectedProfile.Equals(profile)) newItem.Selected = true; + profileValidity[profile.Name] = profile.IsPossible; + // Add it to the list! ilv_saved_profiles.Items.Add(newItem, _profileAdaptor); diff --git a/DisplayMagician/UIForms/ImageListViewRenderers.cs b/DisplayMagician/UIForms/ImageListViewRenderers.cs index aec64d6..bc7876e 100644 --- a/DisplayMagician/UIForms/ImageListViewRenderers.cs +++ b/DisplayMagician/UIForms/ImageListViewRenderers.cs @@ -78,18 +78,6 @@ namespace DisplayMagician.UIForms } } - // Paint background Disabled - /*if ((state & ItemState.Disabled) != ItemState.None) - { - using (Brush bDisabled = new LinearGradientBrush(bounds, ImageListView.Colors.DisabledColor1, ImageListView.Colors.DisabledColor2, LinearGradientMode.Vertical)) - { - Utility.FillRoundedRectangle(g, bDisabled, bounds, 4); - } - }*/ - - // Paint background Selected - /*if ((ImageListView.Focused && ((state & ItemState.Selected) != ItemState.None)) || - (!ImageListView.Focused && ((state & ItemState.Selected) != ItemState.None) && ((state & ItemState.Hovered) != ItemState.None)))*/ if ((state & ItemState.Selected) != ItemState.None) { //using (Brush bSelected = new LinearGradientBrush(bounds, ImageListView.Colors.SelectedColor1, ImageListView.Colors.SelectedColor2, LinearGradientMode.Vertical)) @@ -99,24 +87,6 @@ namespace DisplayMagician.UIForms } } - // Paint background unfocused - /*else if (!ImageListView.Focused && ((state & ItemState.Selected) != ItemState.None)) - { - using (Brush bGray64 = new LinearGradientBrush(bounds, ImageListView.Colors.UnFocusedColor1, ImageListView.Colors.UnFocusedColor2, LinearGradientMode.Vertical)) - { - Utility.FillRoundedRectangle(g, bGray64, bounds, 4); - } - }*/ - - // Paint background Hovered - /*if ((state & ItemState.Hovered) != ItemState.None) - { - using (Brush bHovered = new LinearGradientBrush(bounds, ImageListView.Colors.HoverColor1, ImageListView.Colors.HoverColor2, LinearGradientMode.Vertical)) - { - Utility.FillRoundedRectangle(g, bHovered, bounds, 4); - } - }*/ - // Draw the image Image img = RoundCorners(item.GetCachedImage(CachedImageType.Thumbnail),20); if (img != null) @@ -148,13 +118,6 @@ namespace DisplayMagician.UIForms //g.DrawRectangle(pOuterBorder, pos); DrawRoundedRectangle(g, pOuterBorder, pos,9); } - /*if (System.Math.Min(ImageListView.ThumbnailSize.Width, ImageListView.ThumbnailSize.Height) > 32) - { - using (Pen pInnerBorder = new Pen(ImageListView.Colors.ImageInnerBorderColor)) - { - g.DrawRectangle(pInnerBorder, Rectangle.Inflate(pos, -1, -1)); - } - }*/ } } @@ -172,70 +135,14 @@ namespace DisplayMagician.UIForms foreColor = ImageListView.Colors.UnFocusedForeColor; } - - // Item border - /*if (ImageListView.View != View.Details) - { - //using (Pen pWhite128 = new Pen(Color.FromArgb(255, ImageListView.Colors.ControlBackColor))) - using (Pen pWhite128 = new Pen(Color.FromArgb(255, ImageListView.Colors.ControlBackColor))) - { - Utility.DrawRoundedRectangle(g, pWhite128, bounds.Left + 1, bounds.Top + 1, bounds.Width - 3, bounds.Height - 3, (ImageListView.View == View.Details ? 2 : 4)); - } - }*/ - /*if (((state & ItemState.Disabled) != ItemState.None)) - { - using (Pen pHighlight128 = new Pen(ImageListView.Colors.DisabledBorderColor)) - { - Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - } - }*/ - /* else if (ImageListView.Focused && ((state & ItemState.Selected) != ItemState.None)) - { - using (Pen pHighlight128 = new Pen(ImageListView.Colors.SelectedBorderColor)) - { - Utility.DrawRoundedRectangle(g, pHighlight128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - } - }*/ - /*else if (!ImageListView.Focused && ((state & ItemState.Selected) != ItemState.None)) - { - using (Pen pGray128 = new Pen(ImageListView.Colors.UnFocusedBorderColor)) - { - Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - } - }*/ if ((state & ItemState.Selected) != ItemState.None) { - /*using (Pen pGray128 = new Pen(ImageListView.Colors.UnFocusedBorderColor)) - { - Utility.DrawRoundedRectangle(g, pGray128, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - }*/ using (Pen pSelectedBorder = new Pen(Color.Brown,4)) { //DrawRoundedRectangle(g, pSelectedBorder, bounds, 9); Utility.DrawRoundedRectangle(g, pSelectedBorder, bounds.Left+3, bounds.Top+3, bounds.Width - 5, bounds.Height - 5, 10); } } - /*else if (ImageListView.View != View.Details && (state & ItemState.Selected) == ItemState.None) - { - using (Pen pGray64 = new Pen(ImageListView.Colors.BorderColor)) - { - Utility.DrawRoundedRectangle(g, pGray64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - } - }*/ - - /*if (ImageListView.Focused && ((state & ItemState.Hovered) != ItemState.None)) - { - using (Pen pHighlight64 = new Pen(ImageListView.Colors.HoverBorderColor)) - { - Utility.DrawRoundedRectangle(g, pHighlight64, bounds.Left, bounds.Top, bounds.Width - 1, bounds.Height - 1, 4); - } - } - - // Focus rectangle - if (ImageListView.Focused && ((state & ItemState.Focused) != ItemState.None)) - { - //ControlPaint.DrawFocusRectangle(g, bounds); - }*/ } public Image RoundCorners(Image StartImage, int CornerRadius) @@ -368,4 +275,273 @@ namespace DisplayMagician.UIForms return newBitmap; } } + +#pragma warning disable CS3009 // Base type is not CLS-compliant + public class ProfileILVRenderer : ImageListView.ImageListViewRenderer +#pragma warning restore CS3009 // Base type is not CLS-compliant + { + // Returns item size for the given view mode. +#pragma warning disable CS3001 // Argument type is not CLS-compliant + public override Size MeasureItem(View view) +#pragma warning restore CS3001 // Argument type is not CLS-compliant + { + Size itemPadding = new Size(4, 4); + Size sz = ImageListView.ThumbnailSize + + itemPadding + itemPadding; + return sz; + + /*if (view == View.Thumbnails) + { + //Size itemPadding = new Size(4, 4); + //Size sz = ImageListView.ThumbnailSize + + // itemPadding + itemPadding; + Size sz = ImageListView.ThumbnailSize; + return sz; + } + else + return base.MeasureItem(view);*/ + } + // Draws the background of the control. + public override void DrawBackground(Graphics g, Rectangle bounds) + { + if (ImageListView.View == View.Thumbnails) + g.Clear(Color.FromArgb(255, 255, 255)); + else + base.DrawBackground(g, bounds); + } + // Draws the specified item on the given graphics. +#pragma warning disable CS3001 // Argument type is not CLS-compliant + public override void DrawItem(Graphics g, ImageListViewItem item, ItemState state, Rectangle bounds) +#pragma warning restore CS3001 // Argument type is not CLS-compliant + { + if (g is null) + { + throw new ArgumentNullException(nameof(g)); + } + + if (item is null) + { + throw new ArgumentNullException(nameof(item)); + } + + Size itemPadding = new Size(4, 4); + bool alternate = (item.Index % 2 == 1); + + // Paint background + if (ImageListView.Enabled) + { + using (Brush bItemBack = new SolidBrush(alternate && ImageListView.View == View.Details ? + ImageListView.Colors.AlternateBackColor : ImageListView.Colors.BackColor)) + { + g.FillRectangle(bItemBack, bounds); + } + } + else + { + using (Brush bItemBack = new SolidBrush(ImageListView.Colors.DisabledBackColor)) + { + g.FillRectangle(bItemBack, bounds); + } + } + + if ((state & ItemState.Selected) != ItemState.None) + { + //using (Brush bSelected = new LinearGradientBrush(bounds, ImageListView.Colors.SelectedColor1, ImageListView.Colors.SelectedColor2, LinearGradientMode.Vertical)) + using (Brush bSelected = new LinearGradientBrush(bounds, Color.WhiteSmoke, Color.LightGray, LinearGradientMode.Vertical)) + { + Utility.FillRoundedRectangle(g, bSelected, bounds, 12); + } + } + + // Draw the image + Image img = RoundCorners(item.GetCachedImage(CachedImageType.Thumbnail), 20); + if (img != null) + { + Rectangle pos = Utility.GetSizedImageBounds(img, new Rectangle(bounds.Location + itemPadding, ImageListView.ThumbnailSize)); + + if (DisplayProfileForm.profileValidity[item.Text]) + { + // Draw the full color image as the shortcuts is not invalid + g.DrawImage(img, pos); + } + else + { + // THe shortcut is invalid + // so we make the image grayscale + Image grayImg = MakeGrayscale(img); + g.DrawImage(grayImg, pos); + + // Draw a warning triangle over it + // right in the centre + g.DrawImage(Properties.Resources.Warning, pos.X + 30, pos.Y + 30, 40, 40); + } + + // Draw image border + if (Math.Min(pos.Width, pos.Height) > 32) + { + using (Pen pOuterBorder = new Pen(ImageListView.Colors.ImageOuterBorderColor)) + { + //g.DrawRectangle(pOuterBorder, pos); + DrawRoundedRectangle(g, pOuterBorder, pos, 9); + } + } + } + + // Draw item text + Color foreColor = ImageListView.Colors.ForeColor; + if ((state & ItemState.Disabled) != ItemState.None) + { + foreColor = ImageListView.Colors.DisabledForeColor; + } + else if ((state & ItemState.Selected) != ItemState.None) + { + if (ImageListView.Focused) + foreColor = ImageListView.Colors.SelectedForeColor; + else + foreColor = ImageListView.Colors.UnFocusedForeColor; + } + + if ((state & ItemState.Selected) != ItemState.None) + { + using (Pen pSelectedBorder = new Pen(Color.Brown, 4)) + { + //DrawRoundedRectangle(g, pSelectedBorder, bounds, 9); + Utility.DrawRoundedRectangle(g, pSelectedBorder, bounds.Left + 3, bounds.Top + 3, bounds.Width - 5, bounds.Height - 5, 10); + } + } + } + + public Image RoundCorners(Image StartImage, int CornerRadius) + { + CornerRadius *= 2; + Bitmap RoundedImage = new Bitmap(StartImage.Width, StartImage.Height); + using (Graphics g = Graphics.FromImage(RoundedImage)) + { + g.Clear(Color.Transparent); + g.SmoothingMode = SmoothingMode.HighQuality; + Brush brush = new TextureBrush(StartImage); + GraphicsPath gp = new GraphicsPath(); + gp.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90); + gp.AddArc(0 + RoundedImage.Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90); + gp.AddArc(0 + RoundedImage.Width - CornerRadius, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 0, 90); + gp.AddArc(0, 0 + RoundedImage.Height - CornerRadius, CornerRadius, CornerRadius, 90, 90); + g.FillPath(brush, gp); + return RoundedImage; + } + } + + // Draws the selection rectangle. + public override void DrawSelectionRectangle(Graphics g, Rectangle selection) + { + using (Brush b = new HatchBrush( + HatchStyle.DarkDownwardDiagonal, + Color.FromArgb(128, Color.Black), + Color.FromArgb(128, SystemColors.Highlight))) + { + g.FillRectangle(b, selection); + } + using (Pen p = new Pen(SystemColors.Highlight)) + { + g.DrawRectangle(p, selection.X, selection.Y, + selection.Width, selection.Height); + } + } + + public void DrawRoundedRectangle(Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius) + { + if (graphics == null) + throw new ArgumentNullException("graphics"); + if (pen == null) + throw new ArgumentNullException("pen"); + + using (GraphicsPath path = RoundedRect(bounds, cornerRadius)) + { + graphics.DrawPath(pen, path); + } + } + + public void FillRoundedRectangle(Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius) + { + if (graphics == null) + throw new ArgumentNullException("graphics"); + if (brush == null) + throw new ArgumentNullException("brush"); + + using (GraphicsPath path = RoundedRect(bounds, cornerRadius)) + { + graphics.FillPath(brush, path); + } + } + + public GraphicsPath RoundedRect(Rectangle bounds, int radius) + { + int diameter = radius * 2; + Size size = new Size(diameter, diameter); + Rectangle arc = new Rectangle(bounds.Location, size); + GraphicsPath path = new GraphicsPath(); + + if (radius == 0) + { + path.AddRectangle(bounds); + return path; + } + + // top left arc + path.AddArc(arc, 180, 90); + + // top right arc + arc.X = bounds.Right - diameter; + path.AddArc(arc, 270, 90); + + // bottom right arc + arc.Y = bounds.Bottom - diameter; + path.AddArc(arc, 0, 90); + + // bottom left arc + arc.X = bounds.Left; + path.AddArc(arc, 90, 90); + + path.CloseFigure(); + return path; + } + + public static Image MakeGrayscale(Image original) + { + //create a blank bitmap the same size as original + Image newBitmap = new Bitmap(original.Width, original.Height); + + //get a graphics object from the new image + using (Graphics g = Graphics.FromImage(newBitmap)) + { + + //create the grayscale ColorMatrix + ColorMatrix colorMatrix = new ColorMatrix( + new float[][] + { + new float[] {.3f, .3f, .3f, 0, 0}, + new float[] {.59f, .59f, .59f, 0, 0}, + new float[] {.11f, .11f, .11f, 0, 0}, + new float[] {0, 0, 0, 1, 0}, + new float[] {0, 0, 0, 0, 1} + }); + + //create some image attributes + using (ImageAttributes attributes = new ImageAttributes()) + { + + //set the color matrix attribute + attributes.SetColorMatrix(colorMatrix); + + //draw the original image on the new image + //using the grayscale color matrix + g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), + 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); + } + } + return newBitmap; + } + } + + } + diff --git a/DisplayMagician/UIForms/ShortcutLibraryForm.cs b/DisplayMagician/UIForms/ShortcutLibraryForm.cs index a2f1ea6..e915d0a 100644 --- a/DisplayMagician/UIForms/ShortcutLibraryForm.cs +++ b/DisplayMagician/UIForms/ShortcutLibraryForm.cs @@ -28,6 +28,7 @@ namespace DisplayMagician.UIForms ilv_saved_shortcuts.ThumbnailSize = new Size(100,100); ilv_saved_shortcuts.AllowDrag = false; ilv_saved_shortcuts.AllowDrop = false; + ilv_saved_shortcuts.SetRenderer(new ShortcutILVRenderer()); } private void btn_back_Click(object sender, EventArgs e) @@ -53,9 +54,7 @@ namespace DisplayMagician.UIForms // Temporarily stop updating the saved_profiles listview - ilv_saved_shortcuts.SuspendLayout(); - - ilv_saved_shortcuts.SetRenderer(new ShortcutILVRenderer()); + ilv_saved_shortcuts.SuspendLayout(); ImageListViewItem newItem = null; ilv_saved_shortcuts.Items.Clear(); diff --git a/DisplayMagicianShared/ProfileItem.cs b/DisplayMagicianShared/ProfileItem.cs index a09479a..46cf221 100644 --- a/DisplayMagicianShared/ProfileItem.cs +++ b/DisplayMagicianShared/ProfileItem.cs @@ -26,17 +26,12 @@ namespace DisplayMagicianShared private ProfileIcon _profileIcon; private Bitmap _profileBitmap, _profileShortcutBitmap; private List _profileDisplayIdentifiers = new List(); - //private static List _availableDisplays; - //private static List _unavailableDisplays; internal static string AppDataPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician"); private static readonly string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$"; private string _uuid = ""; - //private Version _version; - //private bool _isActive = false; private bool _isPossible = false; - private bool _isPossibleRenewalDue = true; #region JsonConverterBitmap