Skip to content

Commit

Permalink
Merge pull request #2450 from cwensley/curtis/style-segmented-button
Browse files Browse the repository at this point in the history
Allow better SegmentedButton theming
  • Loading branch information
cwensley committed Mar 23, 2023
2 parents 25d9dd8 + 5058fdf commit 76eff31
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 32 deletions.
1 change: 0 additions & 1 deletion src/Eto.Wpf/Forms/Controls/ButtonHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ public int ImageLabelSpacing
protected override void Initialize()
{
Control.Click += (sender, e) => Callback.OnClick(Widget, EventArgs.Empty);
Control.Padding = new sw.Thickness(2);
LabelPart = new WpfLabel
{
IsHitTestVisible = false,
Expand Down
27 changes: 19 additions & 8 deletions src/Eto.Wpf/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
using Eto.Shared.Forms;
using System.Linq;
using System.Diagnostics;

namespace Eto.Wpf
{
public class Platform : Eto.Platform
Expand All @@ -38,16 +37,28 @@ static Platform()

Style.Add<ThemedSegmentedButtonHandler>(null, h =>
{
h.Control.Styles.Add<ToggleButtonHandler>(null, tb =>
h.Widget.Items.CollectionChanged += (sender, e) =>
{
if (tb.Widget.Parent is TableLayout tl && tl.Rows.Count > 0 && tl.Spacing.Width == 0)
for (int i = 0; i < h.Widget.Items.Count; i++)
{
var isFirst = ReferenceEquals(tl.Rows[0].Cells[0].Control, tb.Widget);
var thickness = tb.Control.BorderThickness;
thickness.Left = isFirst ? thickness.Right : 0;
tb.Control.BorderThickness = thickness;
SegmentedItem item = h.Widget.Items[i];
if (item.ControlObject is Control control)
{
var native = control.ToNative();
if (native != null)
{
WpfProperties.SetEtoStyle(native, "SegmentedButton");
if (i == 0)
WpfProperties.SetEtoModifier(native, "first");
else if (i == h.Widget.Items.Count - 1)
WpfProperties.SetEtoModifier(native, "last");
else
native.ClearValue(WpfProperties.EtoModifierProperty);
}
}
}
});
};
});
}

Expand Down
25 changes: 25 additions & 0 deletions src/Eto.Wpf/WpfProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
using sw = System.Windows;

namespace Eto.Wpf
{
public static class WpfProperties
{
public static string GetEtoStyle(sw.DependencyObject obj) => (string)obj.GetValue(EtoStyleProperty);
public static void SetEtoStyle(sw.DependencyObject obj, string value) => obj.SetValue(EtoStyleProperty, value);

public static readonly sw.DependencyProperty EtoStyleProperty =
sw.DependencyProperty.RegisterAttached("EtoStyle", typeof(string), typeof(WpfProperties), new sw.UIPropertyMetadata(string.Empty));



public static string GetEtoModifier(sw.DependencyObject obj) => (string)obj.GetValue(EtoModifierProperty);
public static void SetEtoModifier(sw.DependencyObject obj, string value) => obj.SetValue(EtoModifierProperty, value);

public static readonly sw.DependencyProperty EtoModifierProperty =
sw.DependencyProperty.RegisterAttached("EtoModifier", typeof(string), typeof(WpfProperties), new sw.UIPropertyMetadata(string.Empty));

}
}
51 changes: 51 additions & 0 deletions src/Eto.Wpf/themes/generic.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:r="clr-namespace:Eto.Wpf.CustomControls.TreeGridView"
xmlns:efc="clr-namespace:Eto.Wpf.Forms.Controls"
xmlns:e="clr-namespace:Eto.Wpf"
xmlns:s="clr-namespace:System;assembly=mscorlib">

<ResourceDictionary.MergedDictionaries>
Expand Down Expand Up @@ -94,5 +95,55 @@
</Setter>
</Style.Setters>
</Style>

<Style TargetType="efc:EtoButton">
<Setter Property="Padding" Value="2" />
</Style>

<Style TargetType="efc:EtoToggleButton">
<Setter Property="Padding" Value="2" />
<Style.Resources>
<Style TargetType="Border">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(e:WpfProperties.EtoStyle), RelativeSource={RelativeSource AncestorType={x:Type efc:EtoToggleButton}}}" Value="SegmentedButton" />
<Condition Binding="{Binding Path=(e:WpfProperties.EtoModifier), RelativeSource={RelativeSource AncestorType={x:Type efc:EtoToggleButton}}}" Value="first" />
</MultiDataTrigger.Conditions>
<Setter Property="CornerRadius" Value="4,0,0,4" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(e:WpfProperties.EtoStyle), RelativeSource={RelativeSource AncestorType={x:Type efc:EtoToggleButton}}}" Value="SegmentedButton" />
<Condition Binding="{Binding Path=(e:WpfProperties.EtoModifier), RelativeSource={RelativeSource AncestorType={x:Type efc:EtoToggleButton}}}" Value="last" />
</MultiDataTrigger.Conditions>
<Setter Property="CornerRadius" Value="0,4,4,0" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
<Style.Triggers>
<Trigger Property="e:WpfProperties.EtoStyle" Value="SegmentedButton">
<Setter Property="BorderThickness" Value=".5,1" />
<Setter Property="Padding" Value="4,2" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="e:WpfProperties.EtoStyle" Value="SegmentedButton"/>
<Condition Property="e:WpfProperties.EtoModifier" Value="first"/>
</MultiTrigger.Conditions>
<Setter Property="BorderThickness" Value="1,1,.5,1" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="e:WpfProperties.EtoStyle" Value="SegmentedButton"/>
<Condition Property="e:WpfProperties.EtoModifier" Value="last"/>
</MultiTrigger.Conditions>
<Setter Property="BorderThickness" Value=".5,1,1,1" />
</MultiTrigger>

</Style.Triggers>
</Style>


</ResourceDictionary>
2 changes: 2 additions & 0 deletions src/Eto/Forms/SegmentedButton/SegmentedButton.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ static SegmentedButton()
public SegmentedButton()
{
Items = new SegmentedItemCollection(this);
Initialize();
}

/// <inheritdoc />
Expand Down Expand Up @@ -328,6 +329,7 @@ public new interface ICallback : Control.ICallback
/// <summary>
/// Handler interface for <see cref="SegmentedButton"/>.
/// </summary>
[AutoInitialize(false)]
public new interface IHandler : Control.IHandler
{
/// <summary>
Expand Down
8 changes: 5 additions & 3 deletions src/Eto/Forms/SegmentedButton/SegmentedItemCollection.cs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace Eto.Forms;

/// <summary>
/// Collection of <see cref="SegmentedItem"/> objects for the <see cref="SegmentedButton"/>.
/// </summary>
public class SegmentedItemCollection : Collection<SegmentedItem>
public class SegmentedItemCollection : ObservableCollection<SegmentedItem>
{
SegmentedButton Parent { get; }
SegmentedButton.IHandler Handler => Parent.Handler as SegmentedButton.IHandler;
Expand Down Expand Up @@ -64,7 +65,8 @@ protected override void RemoveItem(int index)
/// <param name="item">Item to replace with.</param>
protected override void SetItem(int index, SegmentedItem item)
{
this[index].Parent = null;
var oldItem = this[index];
oldItem.Parent = null;
base.SetItem(index, item);
Handler.SetItem(index, item);
item.Parent = Parent;
Expand Down
40 changes: 20 additions & 20 deletions src/Eto/Forms/ThemedControls/ThemedSegmentedButtonHandler.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ public class ThemedMenuSegmentedItemHandler : ThemedSegmentedItemHandler<MenuSeg
/// <summary>
/// Delay for the menu to show when the mouse is down and <see cref="CanSelect"/> is <c>true</c>.
/// </summary>
public TimeSpan MenuDelay { get; set; } = TimeSpan.FromSeconds(0.5);
public virtual TimeSpan MenuDelay { get; set; } = TimeSpan.FromSeconds(0.5);

/// <summary>
/// Gets or sets the indicator to show to the right of the text.
/// </summary>
/// <value>The menu indicator.</value>
public string MenuIndicator
public virtual string MenuIndicator
{
get => menuIndicator;
set
Expand All @@ -36,10 +36,10 @@ public string MenuIndicator
}

/// <inheritdoc/>
public ContextMenu Menu { get; set; }
public virtual ContextMenu Menu { get; set; }

/// <inheritdoc/>
public bool CanSelect { get; set; }
public virtual bool CanSelect { get; set; }

/// <inheritdoc/>
public override string Text
Expand Down Expand Up @@ -125,13 +125,13 @@ public abstract class ThemedSegmentedItemHandler<TWidget, TCallback> : WidgetHan
protected ThemedSegmentedButtonHandler ParentHandler => Widget.Parent?.Handler as ThemedSegmentedButtonHandler;

/// <inheritdoc/>
public bool Enabled { get => Control.Enabled; set => Control.Enabled = value; }
public virtual bool Enabled { get => Control.Enabled; set => Control.Enabled = value; }
/// <inheritdoc/>
public bool Visible { get => Control.Visible; set => Control.Visible = value; }
public virtual bool Visible { get => Control.Visible; set => Control.Visible = value; }
/// <inheritdoc/>
public string ToolTip { get => Control.ToolTip; set => Control.ToolTip = value; }
public virtual string ToolTip { get => Control.ToolTip; set => Control.ToolTip = value; }
/// <inheritdoc/>
public int Width { get => Control.Width; set => Control.Width = value; }
public virtual int Width { get => Control.Width; set => Control.Width = value; }
/// <inheritdoc/>
public virtual string Text
{
Expand All @@ -143,9 +143,9 @@ public virtual string Text
}
}
/// <inheritdoc/>
public Image Image { get => Control.Image; set => Control.Image = value; }
public virtual Image Image { get => Control.Image; set => Control.Image = value; }
/// <inheritdoc/>
public bool Selected
public virtual bool Selected
{
get => Control.Checked;
set
Expand Down Expand Up @@ -224,7 +224,7 @@ public class ThemedSegmentedButtonHandler : ThemedControlHandler<Panel, Segmente
protected override Panel CreateControl() => new Panel();

/// <inheritdoc/>
public SegmentedSelectionMode SelectionMode
public virtual SegmentedSelectionMode SelectionMode
{
get => selectionMode;
set
Expand All @@ -247,10 +247,10 @@ public SegmentedSelectionMode SelectionMode
/// Gets or sets the spacing between the buttons
/// </summary>
/// <value>The spacing between the buttons.</value>
public int Spacing { get; set; }
public virtual int Spacing { get; set; }

/// <inheritdoc/>
public int SelectedIndex
public virtual int SelectedIndex
{
get
{
Expand All @@ -273,7 +273,7 @@ public int SelectedIndex
}

/// <inheritdoc/>
public IEnumerable<int> SelectedIndexes
public virtual IEnumerable<int> SelectedIndexes
{
get
{
Expand Down Expand Up @@ -309,7 +309,7 @@ public IEnumerable<int> SelectedIndexes
}

/// <inheritdoc/>
public void ClearItems()
public virtual void ClearItems()
{
var hasSelected = SelectedIndex != -1;
CreateTable(false);
Expand All @@ -322,7 +322,7 @@ public void ClearItems()
TableCell GetCell(SegmentedItem item) => new TableCell(GetControl(item));

/// <inheritdoc/>
public void ClearSelection()
public virtual void ClearSelection()
{
suppressSelectionChanged++;
var wasSelected = false;
Expand All @@ -338,7 +338,7 @@ public void ClearSelection()
}

/// <inheritdoc/>
public void InsertItem(int index, SegmentedItem item)
public virtual void InsertItem(int index, SegmentedItem item)
{
var isSelected = item.Selected;
CreateTable(false);
Expand All @@ -354,7 +354,7 @@ public void InsertItem(int index, SegmentedItem item)
}

/// <inheritdoc/>
public void RemoveItem(int index, SegmentedItem item)
public virtual void RemoveItem(int index, SegmentedItem item)
{
var wasSelected = item.Selected;
CreateTable(false);
Expand All @@ -363,7 +363,7 @@ public void RemoveItem(int index, SegmentedItem item)
}

/// <inheritdoc/>
public void SelectAll()
public virtual void SelectAll()
{
suppressSelectionChanged++;
bool wasChanged = false;
Expand All @@ -378,7 +378,7 @@ public void SelectAll()
}

/// <inheritdoc/>
public void SetItem(int index, SegmentedItem item)
public virtual void SetItem(int index, SegmentedItem item)
{
var wasSelected = Widget.Items[index].Selected;
var isSelected = item.Selected;
Expand Down

0 comments on commit 76eff31

Please sign in to comment.