Skip to content

Commit 92e8ba6

Browse files
committed
Added list style support to RichEditToolbar
1 parent e5b2233 commit 92e8ba6

File tree

9 files changed

+305
-8
lines changed

9 files changed

+305
-8
lines changed

samples/MADE.Samples/MADE.Samples.Shared/Features/Samples/Assets/RichEditToolbar/CustomRichEditToolbarXaml.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
<made:RichEditToolbar
88
x:Name="CustomRichEditToolbarControl"
99
ShowFontSizeOptions="True"
10-
ShowTextColorOptions="True">
10+
ShowTextColorOptions="True"
11+
ShowListStyleOptions="True">
1112
<made:RichEditToolbar.CustomOptions>
1213
<AppBarSeparator />
1314
<AppBarButton x:Name="SaveButton" Icon="Save" Label="Save" />

src/MADE.UI.Controls.RichEditToolbar/IRichEditToolbar.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public interface IRichEditToolbar
2727
/// </summary>
2828
event RichEditToolbarTextColorChangedEventHandler TextColorChanged;
2929

30+
/// <summary>
31+
/// Occurs when the list style has changed.
32+
/// </summary>
33+
event RichEditToolbarListStyleChangedEventHandler ListStyleChanged;
34+
3035
#if WINDOWS_UWP
3136
/// <summary>
3237
/// Gets or sets the associated <see cref="RichEditBox"/> control.
@@ -53,5 +58,10 @@ public interface IRichEditToolbar
5358
/// Gets or sets a value indicating whether to show text color options.
5459
/// </summary>
5560
bool ShowTextColorOptions { get; set; }
61+
62+
/// <summary>
63+
/// Gets or sets a value indicating whether to show list style options.
64+
/// </summary>
65+
bool ShowListStyleOptions { get; set; }
5666
}
5767
}

src/MADE.UI.Controls.RichEditToolbar/RichEditToolbar.FontSize.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ private void SetupFontSizeOptions()
5555
this.FontSizeIncreaseButton = this.GetChildView<Button>(RichEditToolbarIncreaseTextSizeButtonPart);
5656
this.FontSizeDecreaseButton = this.GetChildView<Button>(RichEditToolbarDecreaseTextSizeButtonPart);
5757

58+
this.UpdateFontSizeOptionsVisibility();
59+
5860
if (this.FontSizeDecreaseButton != null)
5961
{
6062
this.FontSizeDecreaseButton.Click += this.OnFontSizeDecreaseClicked;
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
namespace MADE.UI.Controls
2+
{
3+
using Windows.UI.Text;
4+
using Windows.UI.Xaml;
5+
using Windows.UI.Xaml.Controls.Primitives;
6+
using Extensions;
7+
8+
/// <summary>
9+
/// Defines the list style logic for the <see cref="RichEditToolbar"/>.
10+
/// </summary>
11+
public partial class RichEditToolbar
12+
{
13+
/// <summary>
14+
/// Identifies the <see cref="ShowListStyleOptions"/> dependency property.
15+
/// </summary>
16+
public static readonly DependencyProperty ShowListStyleOptionsProperty = DependencyProperty.Register(
17+
nameof(ShowListStyleOptions),
18+
typeof(bool),
19+
typeof(RichEditToolbar),
20+
new PropertyMetadata(true, (o, args) => ((RichEditToolbar)o).UpdateListStyleOptionsVisibility()));
21+
22+
private const string RichEditToolbarBulletListButtonPart = "RichEditToolbarBulletListButton";
23+
private const string RichEditToolbarNumberListButtonPart = "RichEditToolbarNumberListButton";
24+
25+
/// <summary>
26+
/// Occurs when the list style has changed.
27+
/// </summary>
28+
public event RichEditToolbarListStyleChangedEventHandler ListStyleChanged;
29+
30+
/// <summary>
31+
/// Gets or sets a value indicating whether to show list style options.
32+
/// </summary>
33+
public bool ShowListStyleOptions
34+
{
35+
get => (bool)GetValue(ShowListStyleOptionsProperty);
36+
set => SetValue(ShowListStyleOptionsProperty, value);
37+
}
38+
39+
/// <summary>
40+
/// Gets the view representing the button for toggling bullet list.
41+
/// </summary>
42+
public ToggleButton BulletListButton { get; private set; }
43+
44+
/// <summary>
45+
/// Gets the view representing the button for toggling number list.
46+
/// </summary>
47+
public ToggleButton NumberListButton { get; private set; }
48+
49+
private void SetupListStyleOptions()
50+
{
51+
this.BulletListButton = this.GetChildView<ToggleButton>(RichEditToolbarBulletListButtonPart);
52+
this.NumberListButton = this.GetChildView<ToggleButton>(RichEditToolbarNumberListButtonPart);
53+
54+
this.UpdateListStyleOptionsVisibility();
55+
56+
if (this.BulletListButton != null)
57+
{
58+
this.BulletListButton.Checked += this.OnBulletListButtonChecked;
59+
this.BulletListButton.Unchecked += this.OnBulletListButtonChecked;
60+
}
61+
62+
if (this.NumberListButton != null)
63+
{
64+
this.NumberListButton.Checked += this.OnNumberListButtonChecked;
65+
this.NumberListButton.Unchecked += this.OnNumberListButtonChecked;
66+
}
67+
}
68+
69+
private void UpdateListStyleOptionsVisibility()
70+
{
71+
this.BulletListButton?.SetVisible(this.ShowListStyleOptions);
72+
this.NumberListButton?.SetVisible(this.ShowListStyleOptions);
73+
}
74+
75+
#if WINDOWS_UWP
76+
private void UpdateActiveListStyleOptions()
77+
{
78+
var activeListStyleOption = this.TargetRichEditBox
79+
.Document
80+
.Selection
81+
.ParagraphFormat
82+
.ListType;
83+
84+
if (activeListStyleOption == MarkerType.Undefined)
85+
{
86+
return;
87+
}
88+
89+
if (this.BulletListButton != null)
90+
{
91+
this.BulletListButton.IsChecked = activeListStyleOption == MarkerType.Bullet;
92+
}
93+
94+
if (this.NumberListButton != null)
95+
{
96+
this.NumberListButton.IsChecked = activeListStyleOption == MarkerType.CircledNumber;
97+
}
98+
99+
this.EmitListStyleChanged();
100+
}
101+
#endif
102+
103+
private void ResetListStyleOptions()
104+
{
105+
if (this.BulletListButton != null)
106+
{
107+
this.BulletListButton.Checked -= this.OnBulletListButtonChecked;
108+
this.BulletListButton.Unchecked -= this.OnBulletListButtonChecked;
109+
}
110+
111+
if (this.NumberListButton != null)
112+
{
113+
this.NumberListButton.Checked -= this.OnNumberListButtonChecked;
114+
this.NumberListButton.Unchecked -= this.OnNumberListButtonChecked;
115+
}
116+
}
117+
118+
private void OnNumberListButtonChecked(object sender, RoutedEventArgs e)
119+
{
120+
if (this.NumberListButton == null
121+
#if WINDOWS_UWP
122+
|| this.TargetRichEditBox == null
123+
#endif
124+
)
125+
{
126+
return;
127+
}
128+
129+
#if WINDOWS_UWP
130+
var isChecked = this.NumberListButton.IsChecked ?? false;
131+
var isBulletListChecked = this.BulletListButton?.IsChecked ?? false;
132+
133+
// Resets the bullet list check option.
134+
if (isChecked && isBulletListChecked && this.BulletListButton != null)
135+
{
136+
this.BulletListButton.Unchecked -= this.OnBulletListButtonChecked;
137+
this.BulletListButton.IsChecked = false;
138+
this.BulletListButton.Unchecked += this.OnBulletListButtonChecked;
139+
}
140+
141+
this.TargetRichEditBox
142+
.Document
143+
.Selection
144+
.ParagraphFormat.ListType =
145+
isChecked ? MarkerType.CircledNumber : MarkerType.None;
146+
147+
this.TargetRichEditBox.Document.Selection.ParagraphFormat.ListStyle = MarkerStyle.Plain;
148+
#endif
149+
150+
this.EmitListStyleChanged();
151+
}
152+
153+
private void OnBulletListButtonChecked(object sender, RoutedEventArgs e)
154+
{
155+
if (this.BulletListButton == null
156+
#if WINDOWS_UWP
157+
|| this.TargetRichEditBox == null
158+
#endif
159+
)
160+
{
161+
return;
162+
}
163+
164+
#if WINDOWS_UWP
165+
var isChecked = this.BulletListButton.IsChecked ?? false;
166+
var isNumberListChecked = this.NumberListButton?.IsChecked ?? false;
167+
168+
// Resets the number list check option.
169+
if (isChecked && isNumberListChecked && this.NumberListButton != null)
170+
{
171+
this.NumberListButton.Unchecked -= this.OnNumberListButtonChecked;
172+
this.NumberListButton.IsChecked = false;
173+
this.NumberListButton.Unchecked += this.OnNumberListButtonChecked;
174+
}
175+
176+
this.TargetRichEditBox
177+
.Document
178+
.Selection
179+
.ParagraphFormat.ListType =
180+
isChecked ? MarkerType.Bullet : MarkerType.None;
181+
#endif
182+
183+
this.EmitListStyleChanged();
184+
}
185+
186+
private void EmitListStyleChanged()
187+
{
188+
if (this.ListStyleChanged == null)
189+
{
190+
return;
191+
}
192+
193+
var numberedList = this.NumberListButton?.IsChecked ?? false;
194+
var bulletedList = this.BulletListButton?.IsChecked ?? false;
195+
196+
this.ListStyleChanged.Invoke(
197+
this,
198+
new RichEditToolbarListStyleChangedEventArgs(bulletedList, numberedList));
199+
}
200+
}
201+
}

src/MADE.UI.Controls.RichEditToolbar/RichEditToolbar.TextColor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ private void SetupTextColorOptions()
108108
this.TextColorButton = this.GetChildView<Button>(RichEditToolbarColorButtonPart);
109109
this.TextColorOptionsPanel = this.GetChildView<Panel>(RichEditToolbarColorOptionsPart);
110110

111+
this.UpdateTextColorOptionsVisibility();
112+
111113
if (this.TextColorOptionsPanel == null)
112114
{
113115
return;

src/MADE.UI.Controls.RichEditToolbar/RichEditToolbar.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ protected override void OnApplyTemplate()
8585
this.ResetFontSizeOptions();
8686
this.ResetFontStyleOptions();
8787
this.ResetTextColorOptions();
88+
this.ResetListStyleOptions();
8889
#if WINDOWS_UWP
8990
this.ResetRichEditBox();
9091
#endif
@@ -96,6 +97,7 @@ protected override void OnApplyTemplate()
9697
this.SetupFontSizeOptions();
9798
this.SetupFontStyleOptions();
9899
this.SetupTextColorOptions();
100+
this.SetupListStyleOptions();
99101

100102
#if WINDOWS_UWP
101103
this.SetupRichEditBox();
@@ -134,7 +136,6 @@ private void ResetRichEditBox()
134136
}
135137
}
136138

137-
138139
private void OnRichEditBoxSelectionChanged(object sender, RoutedEventArgs e)
139140
{
140141
this.UpdateActiveToolbarOptions();
@@ -144,6 +145,7 @@ private void UpdateActiveToolbarOptions()
144145
{
145146
this.UpdateActiveFontStyleOptions();
146147
this.UpdateActiveTextColorOptions();
148+
this.UpdateActiveListStyleOptions();
147149
}
148150
#endif
149151

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// MADE Apps licenses this file to you under the MIT license.
2+
// See the LICENSE file in the project root for more information.
3+
4+
namespace MADE.UI.Controls
5+
{
6+
using Windows.UI.Xaml;
7+
8+
/// <summary>
9+
/// Defines an event argument for when a <see cref="RichEditToolbar"/> list style changed.
10+
/// </summary>
11+
public class RichEditToolbarListStyleChangedEventArgs : RoutedEventArgs
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="RichEditToolbarListStyleChangedEventArgs"/> class with the reference to the clicked item.
15+
/// </summary>
16+
/// <param name="bulletedList">A value indicating whether bulleted list is enabled.</param>
17+
/// <param name="numberedList">A value indicating whether numbered list is enabled.</param>
18+
public RichEditToolbarListStyleChangedEventArgs(bool bulletedList, bool numberedList)
19+
{
20+
this.BulletedList = bulletedList;
21+
this.NumberedList = numberedList;
22+
}
23+
24+
/// <summary>
25+
/// Gets a value indicating whether bulleted list is enabled.
26+
/// </summary>
27+
public bool BulletedList { get; }
28+
29+
/// <summary>
30+
/// Gets a value indicating whether numbered list is enabled.
31+
/// </summary>
32+
public bool NumberedList { get; }
33+
}
34+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// MADE Apps licenses this file to you under the MIT license.
2+
// See the LICENSE file in the project root for more information.
3+
4+
namespace MADE.UI.Controls
5+
{
6+
/// <summary>
7+
/// Defines a delegate for the event which occurs when a <see cref="RichEditToolbar"/> list style changed.
8+
/// </summary>
9+
/// <param name="sender">The <see cref="RichEditToolbar"/>.</param>
10+
/// <param name="args">The event argument.</param>
11+
public delegate void RichEditToolbarListStyleChangedEventHandler(object sender, RichEditToolbarListStyleChangedEventArgs args);
12+
}

0 commit comments

Comments
 (0)