Skip to content

Commit

Permalink
Fixes #786
Browse files Browse the repository at this point in the history
  • Loading branch information
batzen committed Apr 18, 2020
1 parent d321b98 commit 06b01b3
Show file tree
Hide file tree
Showing 9 changed files with 534 additions and 103 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next
- ### Bug fixes
- [#786](../../issues/786) - InRibbonGallery: Dynamic ItemWidth / use translated Text in items
- [#788](../../issues/788) - Maximize icon is incorrectly drawn on high-dpi displays
- [#789](../../issues/789) - Opening gallery messes up InRibbonGallery resizing.

Expand Down
1 change: 0 additions & 1 deletion Fluent.Ribbon.Showcase/TestContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,6 @@ Pellentesque nec dolor sed lacus tristique rutrum sed vitae urna. Sed eu pharetr
IsCollapsed="False"
SizeDefinition="Large"
Orientation="Horizontal"
ItemWidth="40"
ItemHeight="56"
GroupBy="Group"
CanCollapseToButton="True"
Expand Down
172 changes: 166 additions & 6 deletions Fluent.Ribbon.Tests/Integration/InRibbonGalleryIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public class InRibbonGalleryIntegrationTests
{
[Test]
public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
public void Opening_And_Closing_DropDown_Should_Not_Change_Size_For_Fixed_Item_Width()
{
var ribbonGroupsContainer = new RibbonGroupsContainer
{
Expand All @@ -33,7 +33,7 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
ItemHeight = 18,
GroupBy = "Group",
ResizeMode = ContextMenuResizeMode.Both,
ItemsSource = this.sampleDataItems
ItemsSource = this.sampleDataItemsForFixedWidth
};

groupBox.Items.Add(firstInRibbonGallery);
Expand All @@ -46,7 +46,7 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
ItemHeight = 18,
GroupBy = "Group",
ResizeMode = ContextMenuResizeMode.Both,
ItemsSource = this.sampleDataItems
ItemsSource = this.sampleDataItemsForFixedWidth
};

groupBox.Items.Add(secondInRibbonGallery);
Expand Down Expand Up @@ -84,7 +84,7 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(219));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(219));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(int.MaxValue));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(0));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(4));

Assert.That(groupBox.ActualWidth, Is.EqualTo(456));
Expand All @@ -108,7 +108,7 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(219));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(219));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(4));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(int.MaxValue));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(0));

Assert.That(groupBox.ActualWidth, Is.EqualTo(456));

Expand Down Expand Up @@ -147,7 +147,154 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
}
}

private readonly SampleDataItem[] sampleDataItems =
[Test]
public void Opening_And_Closing_DropDown_Should_Not_Change_Size_For_Dynamic_Item_Width()
{
var ribbonGroupsContainer = new RibbonGroupsContainer
{
Height = RibbonTabControl.DefaultContentHeight,
ReduceOrder = "(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup),(MyGroup)"
};

var groupBox = new RibbonGroupBox
{
Name = "MyGroup",
BorderBrush = Brushes.Red
};

ribbonGroupsContainer.Children.Add(groupBox);

var firstInRibbonGallery = new InRibbonGallery
{
MinItemsInRow = 1,
MaxItemsInRow = 5,
ItemHeight = 18,
GroupBy = "Group",
ResizeMode = ContextMenuResizeMode.Both,
ItemsSource = this.sampleDataItemsForDynamicWidth
};

groupBox.Items.Add(firstInRibbonGallery);

var secondInRibbonGallery = new InRibbonGallery
{
MinItemsInRow = 1,
MaxItemsInRow = 5,
ItemHeight = 18,
GroupBy = "Group",
ResizeMode = ContextMenuResizeMode.Both,
ItemsSource = this.sampleDataItemsForDynamicWidth
};

groupBox.Items.Add(secondInRibbonGallery);

using (new TestRibbonWindow(ribbonGroupsContainer))
{
UIHelper.DoEvents();

ribbonGroupsContainer.Width = 620;

UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));

for (var i = 0; i < 5; i++)
{
UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));

// open and close first
{
firstInRibbonGallery.IsDropDownOpen = true;
UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(0));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));

firstInRibbonGallery.IsDropDownOpen = false;
UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));
}

// open and close second
{
secondInRibbonGallery.IsDropDownOpen = true;
UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(0));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));

secondInRibbonGallery.IsDropDownOpen = false;
UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));
}

++ribbonGroupsContainer.Width;
}

UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(247));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(3));

Assert.That(groupBox.ActualWidth, Is.EqualTo(512));

ribbonGroupsContainer.Width = 670;

UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(323));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(323));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(4));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(4));
Assert.That(groupBox.ActualWidth, Is.EqualTo(664));

ribbonGroupsContainer.Width = 900;

UIHelper.DoEvents();

Assert.That(firstInRibbonGallery.ActualWidth, Is.EqualTo(399));
Assert.That(secondInRibbonGallery.ActualWidth, Is.EqualTo(399));
Assert.That(firstInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(5));
Assert.That(secondInRibbonGallery.CurrentGalleryPanelState.GalleryPanel.MaxItemsInRow, Is.EqualTo(5));
Assert.That(groupBox.ActualWidth, Is.EqualTo(816));
}
}

private readonly SampleDataItem[] sampleDataItemsForFixedWidth =
{
new SampleDataItem("A", "Blue"),
new SampleDataItem("A", "Brown"),
Expand All @@ -160,6 +307,19 @@ public void Opening_And_Closing_DropDown_Should_Not_Change_Size()
new SampleDataItem("B", "Yellow")
};

private readonly SampleDataItem[] sampleDataItemsForDynamicWidth =
{
new SampleDataItem("A", "Blue"),
new SampleDataItem("A", "Brown"),
new SampleDataItem("A", "Hallo text text"),
new SampleDataItem("A", "Green"),
new SampleDataItem("A", "Orange"),

new SampleDataItem("B", "Pink"),
new SampleDataItem("B", "Red"),
new SampleDataItem("B", "Yellow")
};

private class SampleDataItem
{
public SampleDataItem(string group, string text)
Expand Down
2 changes: 1 addition & 1 deletion Fluent.Ribbon/Controls/Gallery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public int MaxItemsInRow
/// Using a DependencyProperty as the backing store for MaxItemsInRow.
/// This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(Gallery), new PropertyMetadata(int.MaxValue));
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(Gallery), new PropertyMetadata(0));

#endregion

Expand Down
55 changes: 13 additions & 42 deletions Fluent.Ribbon/Controls/GalleryGroupContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public int MaxItemsInRow
/// <summary>
/// <see cref="DependencyProperty"/> for <see cref="MaxItemsInRow"/>.
/// </summary>
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(GalleryGroupContainer), new FrameworkPropertyMetadata(int.MaxValue, FrameworkPropertyMetadataOptions.AffectsMeasure, OnMaxItemsInRowChanged));
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(GalleryGroupContainer), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure, OnMaxItemsInRowChanged));

private static void OnMaxItemsInRowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Expand Down Expand Up @@ -202,7 +202,7 @@ protected override void OnItemsPanelChanged(ItemsPanelTemplate oldItemsPanel, It
#region MaxWidth Updating

// Sets MaxWidth of the items panel based of ItemsInRow property
private void UpdateMinAndMaxWidth()
private void UpdateMinAndMaxWidth(Size constraint)
{
if (this.minMaxWidthNeedsToBeUpdated == false)
{
Expand Down Expand Up @@ -251,15 +251,17 @@ private void UpdateMinAndMaxWidth()
return;
}

var itemWidth = this.GetItemWidth();
var itemWidth = this.GetItemSize().Width;
if (double.IsNaN(itemWidth))
{
// We can't calc item's width now
return;
}

this.targetForSizeConstraints.MinWidth = (Math.Min(this.Items.Count, this.MinItemsInRow) * itemWidth) + 0.1;
this.targetForSizeConstraints.MaxWidth = (Math.Min(this.Items.Count, this.MaxItemsInRow) * itemWidth) + 0.1;
this.targetForSizeConstraints.MaxWidth = this.MaxItemsInRow == 0
? constraint.Width
: (Math.Min(this.Items.Count, this.MaxItemsInRow) * itemWidth) + 0.1;
}

private void HandleLoaded(object sender, RoutedEventArgs e)
Expand All @@ -282,51 +284,20 @@ private void HandleUnloaded(object sender, RoutedEventArgs e)
}

/// <summary>
/// Determinates item's size (return Size.Empty in case of it is not possible)
/// Determines the desired item size.
/// </summary>
/// <returns></returns>
/// <returns>
/// <see cref="Size"/> constructed from <see cref="ItemWidth"/> and <see cref="ItemHeight"/>.
/// If no items are present <see cref="Size.Empty"/>.
/// </returns>
public Size GetItemSize()
{
if (!double.IsNaN(this.ItemWidth)
&& !double.IsNaN(this.ItemHeight))
{
return new Size(this.ItemWidth, this.ItemHeight);
}

if (this.Items.Count == 0)
{
return Size.Empty;
}

var anItem = this.ItemContainerGenerator.ContainerOrContainerContentFromItem<UIElement>(this.Items[0]);
if (anItem == null)
{
return Size.Empty;
}

anItem.Measure(SizeConstants.Infinite);
var result = anItem.DesiredSize;
anItem.InvalidateMeasure();

// We only land here if only size is defined as NaN.
// In such cases we have to measure one size and take the other one from the settings.
if (!double.IsNaN(this.ItemWidth))
{
return new Size(this.ItemWidth, result.Height);
}

if (!double.IsNaN(this.ItemHeight))
{
return new Size(result.Width, this.ItemHeight);
}

return result;
}

// Determinates item's width (return Double.NaN in case of it is not possible)
private double GetItemWidth()
{
return this.GetItemSize().Width;
return new Size(this.ItemWidth, this.ItemHeight);
}

// Finds panel with IsItemsHost, or null if such panel is not found
Expand Down Expand Up @@ -362,7 +333,7 @@ protected override Size MeasureOverride(Size constraint)
this.previousItemsCount = this.Items.Count;
this.minMaxWidthNeedsToBeUpdated = true;

this.UpdateMinAndMaxWidth();
this.UpdateMinAndMaxWidth(constraint);
}

if (this.targetForSizeConstraints != null)
Expand Down
27 changes: 3 additions & 24 deletions Fluent.Ribbon/Controls/GalleryPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public int MaxItemsInRow
/// Using a DependencyProperty as the backing store for ItemsInRow.
/// This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(GalleryPanel), new PropertyMetadata(int.MaxValue, OnMaxItemsInRowChanged));
public static readonly DependencyProperty MaxItemsInRowProperty = DependencyProperty.Register(nameof(MaxItemsInRow), typeof(int), typeof(GalleryPanel), new PropertyMetadata(0, OnMaxItemsInRowChanged));

private static void OnMaxItemsInRowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Expand Down Expand Up @@ -353,28 +353,6 @@ private static void InvalidateMeasureRecursive(UIElement visual)

#endregion

#region GetItemSize

/// <summary>
/// Determinates item's size (return Size.Empty in case of it is not possible)
/// </summary>
/// <returns></returns>
public Size GetItemSize()
{
foreach (var galleryGroupContainer in this.galleryGroupContainers)
{
var size = galleryGroupContainer.GetItemSize();
if (size.IsEmpty == false)
{
return size;
}
}

return Size.Empty;
}

#endregion

#region Refresh

private bool areUpdatesSuspsended;
Expand Down Expand Up @@ -522,7 +500,8 @@ private void Refresh()
this.visualCollection.Add(galleryGroupContainer);
}

dictionary[propertyValue].Items.Add(new GalleryItemPlaceholder(item));
var galleryItemPlaceholder = new GalleryItemPlaceholder(item);
dictionary[propertyValue].Items.Add(galleryItemPlaceholder);
}

if ((this.IsGrouped == false || (this.GroupBy == null && this.GroupByAdvanced == null))
Expand Down
Loading

0 comments on commit 06b01b3

Please sign in to comment.