diff --git a/README.md b/README.md index ea0cee1..a81b53a 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ Thanks ! * [CheckedButtonList](#checked-button-list) + * [MultiToggleButton](#multi-toggle-button) + - [Groups](#groups) * [SplitterForm](#splitter-form) @@ -814,6 +816,8 @@ await this.NavigateTo(cd); ### Checked Button List +### Multi Toggle Button + ## Groups diff --git a/TelegramBotBase/Controls/Inline/MultiToggleButton.cs b/TelegramBotBase/Controls/Inline/MultiToggleButton.cs new file mode 100644 index 0000000..d5f44f3 --- /dev/null +++ b/TelegramBotBase/Controls/Inline/MultiToggleButton.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Base; +using TelegramBotBase.Form; + +namespace TelegramBotBase.Controls.Inline +{ + public class MultiToggleButton : ControlBase + { + + //public String UncheckedIcon { get; set; } = Localizations.Default.Language["ToggleButton_OffIcon"]; + + public String CheckedIcon { get; set; } = "✅"; + + public String ChangedString { get; set; } = Localizations.Default.Language["ToggleButton_Changed"]; + + public String Title { get; set; } = Localizations.Default.Language["ToggleButton_Title"]; + + public int? MessageId { get; set; } + + private bool RenderNecessary = true; + + private static readonly object __evToggled = new object(); + + private readonly EventHandlerList Events = new EventHandlerList(); + + public List Options { get; set; } + + + public MultiToggleButton() + { + Options = new List(); + } + + public event EventHandler Toggled + { + add + { + this.Events.AddHandler(__evToggled, value); + } + remove + { + this.Events.RemoveHandler(__evToggled, value); + } + } + + public void OnToggled(EventArgs e) + { + (this.Events[__evToggled] as EventHandler)?.Invoke(this, e); + } + + public override async Task Action(MessageResult result, String value = null) + { + if (result.Handled) + return; + + await result.ConfirmAction(this.ChangedString); + + switch (value ?? "unknown") + { + default: + + var s = value.Split('$'); + + if (s[0] == "check" && s.Length > 1) + { + int index = 0; + if (!int.TryParse(s[1], out index)) + { + return; + } + + if(SelectedOption== null || SelectedOption != this.Options[index]) + { + this.SelectedOption = this.Options[index]; + OnToggled(new EventArgs()); + } + else + { + this.SelectedOption = null; + OnToggled(new EventArgs()); + } + + RenderNecessary = true; + + return; + } + + + RenderNecessary = false; + + break; + + } + + result.Handled = true; + + } + + public override async Task Render(MessageResult result) + { + if (!RenderNecessary) + return; + + var bf = new ButtonForm(this); + + var lst = new List(); + foreach (var o in this.Options) + { + var index = this.Options.IndexOf(o); + if (o == this.SelectedOption) + { + lst.Add(new ButtonBase(CheckedIcon + " " + o.Text, "check$" + index)); + continue; + } + + lst.Add(new ButtonBase(o.Text, "check$" + index)); + } + + bf.AddButtonRow(lst); + + if (this.MessageId != null) + { + var m = await this.Device.Edit(this.MessageId.Value, this.Title, bf); + } + else + { + var m = await this.Device.Send(this.Title, bf, disableNotification: true); + if (m != null) + { + this.MessageId = m.MessageId; + } + } + + this.RenderNecessary = false; + + + } + + public ButtonBase SelectedOption + { + get; set; + } + + } +} diff --git a/TelegramBotBaseTest/Tests/Controls/MultiToggleButtons.cs b/TelegramBotBaseTest/Tests/Controls/MultiToggleButtons.cs new file mode 100644 index 0000000..54fddca --- /dev/null +++ b/TelegramBotBaseTest/Tests/Controls/MultiToggleButtons.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TelegramBotBase.Args; +using TelegramBotBase.Controls; +using TelegramBotBase.Controls.Inline; +using TelegramBotBase.Form; + +namespace TelegramBotBaseTest.Tests.Controls +{ + public class MultiToggleButtons : AutoCleanForm + { + public MultiToggleButtons() + { + this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm; + + this.Init += ToggleButtons_Init; + } + + private async Task ToggleButtons_Init(object sender, InitEventArgs e) + { + + var mtb = new MultiToggleButton(); + + mtb.Options = new List() { new ButtonBase("Option 1", "1"), new ButtonBase("Option 2", "2"), new ButtonBase("Option 3", "3") }; + mtb.SelectedOption = mtb.Options.FirstOrDefault(); + mtb.Toggled += Tb_Toggled; + this.AddControl(mtb); + + mtb = new MultiToggleButton(); + + mtb.Options = new List() { new ButtonBase("Option 4", "4"), new ButtonBase("Option 5", "5"), new ButtonBase("Option 6", "6") }; + mtb.SelectedOption = mtb.Options.FirstOrDefault(); + mtb.Toggled += Tb_Toggled; + this.AddControl(mtb); + } + + private void Tb_Toggled(object sender, EventArgs e) + { + var tb = sender as MultiToggleButton; + Console.WriteLine(tb.ID.ToString() + " was pressed, and toggled to " + tb.SelectedOption.Value); + } + } +} diff --git a/TelegramBotBaseTest/Tests/Menu.cs b/TelegramBotBaseTest/Tests/Menu.cs index d72d04f..57cf9fb 100644 --- a/TelegramBotBaseTest/Tests/Menu.cs +++ b/TelegramBotBaseTest/Tests/Menu.cs @@ -140,6 +140,17 @@ namespace TelegramBotBaseTest.Tests await this.NavigateTo(tb); break; + + case "multitogglebuttons": + + message.Handled = true; + + var mtb = new Controls.MultiToggleButtons(); + + await this.NavigateTo(mtb); + + break; + case "buttongrid": message.Handled = true; @@ -217,6 +228,8 @@ namespace TelegramBotBaseTest.Tests btn.AddButtonRow(new ButtonBase("#11 ToggleButtons", new CallbackData("a", "togglebuttons").Serialize())); + btn.AddButtonRow(new ButtonBase("#11.2 MultiToggleButtons", new CallbackData("a", "multitogglebuttons").Serialize())); + btn.AddButtonRow(new ButtonBase("#12 ButtonGrid", new CallbackData("a", "buttongrid").Serialize())); btn.AddButtonRow(new ButtonBase("#13 ButtonGrid Paging & Filter", new CallbackData("a", "buttongridfilter").Serialize())); diff --git a/images/multitogglebutton.gif b/images/multitogglebutton.gif new file mode 100644 index 0000000..b399eae Binary files /dev/null and b/images/multitogglebutton.gif differ