From 4018384803cab9ff175281ca139a000126360a06 Mon Sep 17 00:00:00 2001 From: Bastian Schmidt Date: Sat, 18 Apr 2020 21:29:07 +0200 Subject: [PATCH] Fixing various issues with the popup of InRibbonGallery --- Fluent.Ribbon/Controls/InRibbonGallery.cs | 74 +++++++++++++++++-- Fluent.Ribbon/Internal/KnownBoxes/IntBoxes.cs | 5 ++ 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/Fluent.Ribbon/Controls/InRibbonGallery.cs b/Fluent.Ribbon/Controls/InRibbonGallery.cs index e5b5efc9a..7543fee8e 100644 --- a/Fluent.Ribbon/Controls/InRibbonGallery.cs +++ b/Fluent.Ribbon/Controls/InRibbonGallery.cs @@ -1,4 +1,4 @@ -// ReSharper disable once CheckNamespace +// ReSharper disable once CheckNamespace namespace Fluent { using System; @@ -41,6 +41,9 @@ namespace Fluent [TemplatePart(Name = "PART_ContentPresenter", Type = typeof(ContentControl))] [TemplatePart(Name = "PART_PopupContentPresenter", Type = typeof(ContentControl))] [TemplatePart(Name = "PART_ScrollViewer", Type = typeof(ScrollViewer))] + + [TemplatePart(Name = "PART_PopupMenuPresenter", Type = typeof(FrameworkElement))] + [TemplatePart(Name = "PART_PopupResizeBorder", Type = typeof(FrameworkElement))] public class InRibbonGallery : Selector, IScalableRibbonControl, IDropDownControl, IRibbonControl, IQuickAccessItemProvider, IRibbonSizeChangedSink, ILargeIconProvider { #region Fields @@ -80,9 +83,14 @@ public class InRibbonGallery : Selector, IScalableRibbonControl, IDropDownContro private FrameworkElement layoutRoot; + private FrameworkElement popupMenuPresenter; + private FrameworkElement popupResizeBorder; + [CanBeNull] internal GalleryPanelState CurrentGalleryPanelState { get; private set; } + internal PopupState CurrentPopupState { get; } = new PopupState(); + #endregion #region Properties @@ -186,7 +194,7 @@ public int MinItemsInDropDownRow /// Using a DependencyProperty as the backing store for MinItemsInDropDownRow. This enables animation, styling, binding, etc... /// public static readonly DependencyProperty MinItemsInDropDownRowProperty = - DependencyProperty.Register(nameof(MinItemsInDropDownRow), typeof(int), typeof(InRibbonGallery), new PropertyMetadata(1)); + DependencyProperty.Register(nameof(MinItemsInDropDownRow), typeof(int), typeof(InRibbonGallery), new PropertyMetadata(IntBoxes.One)); #endregion @@ -204,7 +212,8 @@ public int MaxItemsInDropDownRow /// /// Using a DependencyProperty as the backing store for MaxItemsInDropDownRow. This enables animation, styling, binding, etc... /// - public static readonly DependencyProperty MaxItemsInDropDownRowProperty = DependencyProperty.Register(nameof(MaxItemsInDropDownRow), typeof(int), typeof(InRibbonGallery), new PropertyMetadata(0)); + public static readonly DependencyProperty MaxItemsInDropDownRowProperty = + DependencyProperty.Register(nameof(MaxItemsInDropDownRow), typeof(int), typeof(InRibbonGallery), new PropertyMetadata(IntBoxes.Zero)); #endregion @@ -1128,6 +1137,9 @@ public override void OnApplyTemplate() this.popupControlPresenter = this.GetTemplateChild("PART_PopupContentPresenter") as ContentControl; this.scrollViewer = this.GetTemplateChild("PART_ScrollViewer") as ScrollViewer; + + this.popupMenuPresenter = this.GetTemplateChild("PART_PopupMenuPresenter") as FrameworkElement; + this.popupResizeBorder = this.GetTemplateChild("PART_PopupResizeBorder") as FrameworkElement; } private void OnPopupPreviewMouseUp(object sender, MouseButtonEventArgs e) @@ -1207,6 +1219,8 @@ private void OnDropDownOpened(object sender, EventArgs e) this.galleryPanel.MinItemsInRow = this.MinItemsInDropDownRow; this.galleryPanel.MaxItemsInRow = this.MaxItemsInDropDownRow; this.galleryPanel.IsGrouped = true; + + this.CurrentPopupState.Restore(this.galleryPanel, this.menuPanel); } } @@ -1344,28 +1358,42 @@ private void OnResizeBothDelta(object sender, DragDeltaEventArgs e) { this.OnResizeVerticalDelta(sender, e); - this.menuPanel.Width = double.NaN; + if (DoubleUtil.AreClose(e.HorizontalChange, 0)) + { + return; + } if (this.galleryPanel.IsNotNull()) { if (double.IsNaN(this.galleryPanel.Width)) { - this.galleryPanel.Width = this.galleryPanel.ActualWidth; + this.galleryPanel.SetCurrentValue(WidthProperty, this.galleryPanel.ActualWidth); } - this.galleryPanel.Width = Math.Max(this.layoutRoot.ActualWidth, this.galleryPanel.Width + e.HorizontalChange); + var minimumWidth = this.snappedImage.ActualWidth; + this.galleryPanel.SetCurrentValue(WidthProperty, Math.Max(minimumWidth, this.galleryPanel.Width + e.HorizontalChange)); } + + this.CurrentPopupState.Save(this.galleryPanel, this.menuPanel); } // Handles resize vertical drag private void OnResizeVerticalDelta(object sender, DragDeltaEventArgs e) { + if (DoubleUtil.AreClose(e.VerticalChange, 0)) + { + return; + } + if (double.IsNaN(this.menuPanel.Height)) { - this.menuPanel.Height = this.menuPanel.ActualHeight; + this.menuPanel.SetCurrentValue(HeightProperty, this.menuPanel.ActualHeight); } - this.menuPanel.Height = Math.Max(this.layoutRoot.ActualHeight, Math.Min(this.menuPanel.Height + e.VerticalChange, this.MaxDropDownHeight)); + var minimumHeight = this.layoutRoot.ActualHeight + this.popupMenuPresenter.ActualHeight + this.popupResizeBorder.ActualHeight + 10; + this.menuPanel.SetCurrentValue(HeightProperty, Math.Max(minimumHeight, Math.Min(this.menuPanel.Height + e.VerticalChange, this.MaxDropDownHeight))); + + this.CurrentPopupState.Save(this.galleryPanel, this.menuPanel); } #endregion @@ -1610,5 +1638,35 @@ public void Restore() this.GalleryPanel.MaxItemsInRow = this.MaxItemsInRow; } } + + internal class PopupState + { + public double Width { get; private set; } = double.NaN; + + public double Height { get; private set; } = double.NaN; + + public void Save(FrameworkElement widthControl, FrameworkElement heightControl) + { + this.Width = widthControl.Width; + this.Height = heightControl.Height; + } + + public void Restore(FrameworkElement widthControl, FrameworkElement heightControl) + { + if (double.IsNaN(this.Width) == false) + { + widthControl.SetCurrentValue(WidthProperty, this.Width); + } + else + { + widthControl.SetCurrentValue(WidthProperty, widthControl.ActualWidth); + } + + if (double.IsNaN(this.Height) == false) + { + heightControl.SetCurrentValue(HeightProperty, this.Height); + } + } + } } } \ No newline at end of file diff --git a/Fluent.Ribbon/Internal/KnownBoxes/IntBoxes.cs b/Fluent.Ribbon/Internal/KnownBoxes/IntBoxes.cs index 4b5750b98..1624d4617 100644 --- a/Fluent.Ribbon/Internal/KnownBoxes/IntBoxes.cs +++ b/Fluent.Ribbon/Internal/KnownBoxes/IntBoxes.cs @@ -10,6 +10,11 @@ internal static class IntBoxes /// internal static readonly object Zero = 0; + /// + /// Gets a boxed value for 1. + /// + internal static readonly object One = 1; + /// /// Gets a boxed value for . ///