MAJOR CHANGE: Refactoring namespace for controls
Chaning namespace for controls depending on their use area to: Controls.Hybrid Controls.Inline Controls.Reply Updating example project as well.
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
using static TelegramBotBase.Tools.Arrays;
|
||||
using static TelegramBotBase.Tools.Time;
|
||||
|
||||
namespace TelegramBotBase.Controls.Inline
|
||||
{
|
||||
public class CalendarPicker : Base.ControlBase
|
||||
{
|
||||
|
||||
public DateTime SelectedDate { get; set; }
|
||||
|
||||
public DateTime VisibleMonth { get; set; }
|
||||
|
||||
public DayOfWeek FirstDayOfWeek { get; set; }
|
||||
|
||||
public CultureInfo Culture { get; set; }
|
||||
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String Title { get; set; } = Localizations.Default.Language["CalendarPicker_Title"];
|
||||
|
||||
public eMonthPickerMode PickerMode { get; set; }
|
||||
|
||||
public bool EnableDayView { get; set; } = true;
|
||||
|
||||
public bool EnableMonthView { get; set; } = true;
|
||||
|
||||
public bool EnableYearView { get; set; } = true;
|
||||
|
||||
public CalendarPicker()
|
||||
{
|
||||
this.SelectedDate = DateTime.Today;
|
||||
this.VisibleMonth = DateTime.Today;
|
||||
this.FirstDayOfWeek = DayOfWeek.Monday;
|
||||
this.Culture = new CultureInfo("de-de");
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
switch (result.RawData)
|
||||
{
|
||||
case "$next$":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(10);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case "$prev$":
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
this.VisibleMonth = this.VisibleMonth.AddMonths(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-1);
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
this.VisibleMonth = this.VisibleMonth.AddYears(-10);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "$monthtitle$":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "$yeartitle$":
|
||||
|
||||
if (this.EnableYearView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.year;
|
||||
}
|
||||
|
||||
break;
|
||||
case "$yearstitle$":
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
int day = 0;
|
||||
if (result.RawData.StartsWith("d-") && int.TryParse(result.RawData.Split('-')[1], out day))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, this.VisibleMonth.Month, day);
|
||||
}
|
||||
|
||||
int month = 0;
|
||||
if (result.RawData.StartsWith("m-") && int.TryParse(result.RawData.Split('-')[1], out month))
|
||||
{
|
||||
this.SelectedDate = new DateTime(this.VisibleMonth.Year, month, 1);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableDayView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.day;
|
||||
}
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
if (result.RawData.StartsWith("y-") && int.TryParse(result.RawData.Split('-')[1], out year))
|
||||
{
|
||||
this.SelectedDate = new DateTime(year, SelectedDate.Month, SelectedDate.Day);
|
||||
this.VisibleMonth = this.SelectedDate;
|
||||
|
||||
if (this.EnableMonthView)
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
|
||||
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
switch (this.PickerMode)
|
||||
{
|
||||
case eMonthPickerMode.day:
|
||||
|
||||
var month = this.VisibleMonth;
|
||||
|
||||
string[] dayNamesNormal = this.Culture.DateTimeFormat.ShortestDayNames;
|
||||
string[] dayNamesShifted = Shift(dayNamesNormal, (int)this.FirstDayOfWeek);
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(Localizations.Default.Language["CalendarPicker_PreviousPage"], "$prev$"), new ButtonBase(this.Culture.DateTimeFormat.MonthNames[month.Month - 1] + " " + month.Year.ToString(), "$monthtitle$"), new ButtonBase(Localizations.Default.Language["CalendarPicker_NextPage"], "$next$"));
|
||||
|
||||
bf.AddButtonRow(dayNamesShifted.Select(a => new ButtonBase(a, a)).ToList());
|
||||
|
||||
//First Day of month
|
||||
var firstDay = new DateTime(month.Year, month.Month, 1);
|
||||
|
||||
//Last Day of month
|
||||
var lastDay = firstDay.LastDayOfMonth();
|
||||
|
||||
//Start of Week where first day of month is (left border)
|
||||
var start = firstDay.StartOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
//End of week where last day of month is (right border)
|
||||
var end = lastDay.EndOfWeek(this.FirstDayOfWeek);
|
||||
|
||||
for (int i = 0; i <= ((end - start).Days / 7); i++)
|
||||
{
|
||||
var lst = new List<ButtonBase>();
|
||||
for (int id = 0; id < 7; id++)
|
||||
{
|
||||
var d = start.AddDays((i * 7) + id);
|
||||
if (d < firstDay | d > lastDay)
|
||||
{
|
||||
lst.Add(new ButtonBase("-", "m-" + d.Day.ToString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
var day = d.Day.ToString();
|
||||
|
||||
if (d == DateTime.Today)
|
||||
{
|
||||
day = "(" + day + ")";
|
||||
}
|
||||
|
||||
lst.Add(new ButtonBase((this.SelectedDate == d ? "[" + day + "]" : day), "d-" + d.Day.ToString()));
|
||||
}
|
||||
bf.AddButtonRow(lst);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.month:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(Localizations.Default.Language["CalendarPicker_PreviousPage"], "$prev$"), new ButtonBase(this.VisibleMonth.Year.ToString("0000"), "$yeartitle$"), new ButtonBase(Localizations.Default.Language["CalendarPicker_NextPage"], "$next$"));
|
||||
|
||||
var months = this.Culture.DateTimeFormat.MonthNames;
|
||||
|
||||
var buttons = months.Select((a, b) => new ButtonBase((b == this.SelectedDate.Month - 1 && this.SelectedDate.Year == this.VisibleMonth.Year ? "[ " + a + " ]" : a), "m-" + (b + 1).ToString()));
|
||||
|
||||
bf.AddSplitted(buttons, 2);
|
||||
|
||||
break;
|
||||
|
||||
case eMonthPickerMode.year:
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(Localizations.Default.Language["CalendarPicker_PreviousPage"], "$prev$"), new ButtonBase("Year", "$yearstitle$"), new ButtonBase(Localizations.Default.Language["CalendarPicker_NextPage"], "$next$"));
|
||||
|
||||
var starti = Math.Floor(this.VisibleMonth.Year / 10f) * 10;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var m = starti + (i * 2);
|
||||
bf.AddButtonRow(new ButtonBase((this.SelectedDate.Year == m ? "[ " + m.ToString() + " ]" : m.ToString()), "y-" + m.ToString()), new ButtonBase((this.SelectedDate.Year == (m + 1) ? "[ " + (m + 1).ToString() + " ]" : (m + 1).ToString()), "y-" + (m + 1).ToString()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override async Task Cleanup()
|
||||
{
|
||||
|
||||
if (this.MessageId != null)
|
||||
{
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Enums;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls.Inline
|
||||
{
|
||||
public class MonthPicker : CalendarPicker
|
||||
{
|
||||
|
||||
|
||||
|
||||
public MonthPicker()
|
||||
{
|
||||
this.PickerMode = eMonthPickerMode.month;
|
||||
this.EnableDayView = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
|
||||
namespace TelegramBotBase.Controls.Inline
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple control for show and managing progress.
|
||||
/// </summary>
|
||||
public class ProgressBar : Base.ControlBase
|
||||
{
|
||||
public enum eProgressStyle
|
||||
{
|
||||
standard = 0,
|
||||
squares = 1,
|
||||
circles = 2,
|
||||
lines = 3,
|
||||
squaredLines = 4,
|
||||
custom = 10
|
||||
}
|
||||
|
||||
public eProgressStyle ProgressStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_eStyle;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_eStyle = value;
|
||||
LoadStyle();
|
||||
}
|
||||
}
|
||||
|
||||
private eProgressStyle m_eStyle = eProgressStyle.standard;
|
||||
|
||||
|
||||
public int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_iValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value > this.Max)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.m_iValue != value)
|
||||
{
|
||||
this.RenderNecessary = true;
|
||||
}
|
||||
this.m_iValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int m_iValue = 0;
|
||||
|
||||
public int Max
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_iMax;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.m_iMax != value)
|
||||
{
|
||||
this.RenderNecessary = true;
|
||||
}
|
||||
this.m_iMax = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int m_iMax = 100;
|
||||
|
||||
public int? MessageId { get; set; }
|
||||
|
||||
private bool RenderNecessary { get; set; } = false;
|
||||
|
||||
public int Steps
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (this.ProgressStyle)
|
||||
{
|
||||
case eProgressStyle.standard:
|
||||
|
||||
return 1;
|
||||
|
||||
case eProgressStyle.squares:
|
||||
|
||||
return 10;
|
||||
|
||||
case eProgressStyle.circles:
|
||||
|
||||
return 10;
|
||||
|
||||
case eProgressStyle.lines:
|
||||
|
||||
return 5;
|
||||
|
||||
case eProgressStyle.squaredLines:
|
||||
|
||||
return 5;
|
||||
|
||||
default:
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filled block (reached percentage)
|
||||
/// </summary>
|
||||
public String BlockChar
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unfilled block (not reached yet)
|
||||
/// </summary>
|
||||
public String EmptyBlockChar
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String at the beginning of the progress bar
|
||||
/// </summary>
|
||||
public String StartChar
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String at the end of the progress bar
|
||||
/// </summary>
|
||||
public String EndChar
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ProgressBar()
|
||||
{
|
||||
this.ProgressStyle = eProgressStyle.standard;
|
||||
|
||||
this.Value = 0;
|
||||
this.Max = 100;
|
||||
|
||||
this.RenderNecessary = true;
|
||||
}
|
||||
|
||||
public ProgressBar(int Value, int Max, eProgressStyle Style)
|
||||
{
|
||||
this.Value = Value;
|
||||
this.Max = Max;
|
||||
this.ProgressStyle = Style;
|
||||
|
||||
this.RenderNecessary = true;
|
||||
}
|
||||
|
||||
public override async Task Cleanup()
|
||||
{
|
||||
if (this.MessageId == null || this.MessageId == -1)
|
||||
return;
|
||||
|
||||
|
||||
await this.Device.DeleteMessage(this.MessageId.Value);
|
||||
}
|
||||
|
||||
public void LoadStyle()
|
||||
{
|
||||
this.StartChar = "";
|
||||
this.EndChar = "";
|
||||
|
||||
switch (this.ProgressStyle)
|
||||
{
|
||||
case eProgressStyle.circles:
|
||||
|
||||
this.BlockChar = "⚫️ ";
|
||||
this.EmptyBlockChar = "⚪️ ";
|
||||
|
||||
break;
|
||||
case eProgressStyle.squares:
|
||||
|
||||
this.BlockChar = "⬛️ ";
|
||||
this.EmptyBlockChar = "⬜️ ";
|
||||
|
||||
break;
|
||||
case eProgressStyle.lines:
|
||||
|
||||
this.BlockChar = "█";
|
||||
this.EmptyBlockChar = "▁";
|
||||
|
||||
break;
|
||||
case eProgressStyle.squaredLines:
|
||||
|
||||
this.BlockChar = "▇";
|
||||
this.EmptyBlockChar = "—";
|
||||
|
||||
this.StartChar = "[";
|
||||
this.EndChar = "]";
|
||||
|
||||
break;
|
||||
case eProgressStyle.standard:
|
||||
case eProgressStyle.custom:
|
||||
|
||||
this.BlockChar = "";
|
||||
this.EmptyBlockChar = "";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async override Task Render(MessageResult result)
|
||||
{
|
||||
if (!this.RenderNecessary)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.Device == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String message = "";
|
||||
int blocks = 0;
|
||||
int maxBlocks = 0;
|
||||
|
||||
switch (this.ProgressStyle)
|
||||
{
|
||||
case eProgressStyle.standard:
|
||||
|
||||
message = this.Value.ToString("0") + "%";
|
||||
|
||||
break;
|
||||
|
||||
case eProgressStyle.squares:
|
||||
case eProgressStyle.circles:
|
||||
case eProgressStyle.lines:
|
||||
case eProgressStyle.squaredLines:
|
||||
case eProgressStyle.custom:
|
||||
|
||||
blocks = (int)Math.Floor((decimal)this.Value / this.Steps);
|
||||
|
||||
maxBlocks = (this.Max / this.Steps);
|
||||
|
||||
message += this.StartChar;
|
||||
|
||||
for (int i = 0; i < blocks; i++)
|
||||
{
|
||||
message += this.BlockChar;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (maxBlocks - blocks); i++)
|
||||
{
|
||||
message += this.EmptyBlockChar;
|
||||
}
|
||||
|
||||
message += this.EndChar;
|
||||
|
||||
message += " " + this.Value.ToString("0") + "%";
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.MessageId == null)
|
||||
{
|
||||
var m = await this.Device.Send(message);
|
||||
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
else
|
||||
{
|
||||
await this.Device.Edit(this.MessageId.Value, message);
|
||||
}
|
||||
|
||||
this.RenderNecessary = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
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 ToggleButton : ControlBase
|
||||
{
|
||||
|
||||
public String UncheckedIcon { get; set; } = Localizations.Default.Language["ToggleButton_OffIcon"];
|
||||
|
||||
public String CheckedIcon { get; set; } = Localizations.Default.Language["ToggleButton_OnIcon"];
|
||||
|
||||
public String CheckedString { get; set; } = Localizations.Default.Language["ToggleButton_On"];
|
||||
|
||||
public String UncheckedString { get; set; } = Localizations.Default.Language["ToggleButton_Off"];
|
||||
|
||||
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; }
|
||||
|
||||
public bool Checked { get; set; }
|
||||
|
||||
private bool RenderNecessary = true;
|
||||
|
||||
private static readonly object __evToggled = new object();
|
||||
|
||||
private readonly EventHandlerList Events = new EventHandlerList();
|
||||
|
||||
|
||||
public ToggleButton()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ToggleButton(String CheckedString, String UncheckedString)
|
||||
{
|
||||
this.CheckedString = CheckedString;
|
||||
this.UncheckedString = UncheckedString;
|
||||
}
|
||||
|
||||
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")
|
||||
{
|
||||
case "on":
|
||||
|
||||
if (this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = true;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
case "off":
|
||||
|
||||
if (!this.Checked)
|
||||
return;
|
||||
|
||||
RenderNecessary = true;
|
||||
|
||||
this.Checked = false;
|
||||
|
||||
OnToggled(new EventArgs());
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
RenderNecessary = false;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
if (!RenderNecessary)
|
||||
return;
|
||||
|
||||
var bf = new ButtonForm(this);
|
||||
|
||||
ButtonBase bOn = new ButtonBase((this.Checked ? CheckedIcon : UncheckedIcon) + " " + CheckedString, "on");
|
||||
|
||||
ButtonBase bOff = new ButtonBase((!this.Checked ? CheckedIcon : UncheckedIcon) + " " + UncheckedString, "off");
|
||||
|
||||
bf.AddButtonRow(bOn, bOff);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
namespace TelegramBotBase.Controls.Inline
|
||||
{
|
||||
public class TreeView : ControlBase
|
||||
{
|
||||
public List<TreeViewNode> Nodes { get; set; }
|
||||
|
||||
public TreeViewNode SelectedNode { get; set; }
|
||||
|
||||
public TreeViewNode VisibleNode { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
|
||||
private int? MessageId { get; set; }
|
||||
|
||||
public String MoveUpIcon { get; set; } = Localizations.Default.Language["TreeView_LevelUp"];
|
||||
|
||||
public TreeView()
|
||||
{
|
||||
this.Nodes = new List<TreeViewNode>();
|
||||
this.Title = Localizations.Default.Language["TreeView_Title"];
|
||||
}
|
||||
|
||||
|
||||
public override async Task Action(MessageResult result, String value = null)
|
||||
{
|
||||
await result.ConfirmAction();
|
||||
|
||||
if (result.Handled)
|
||||
return;
|
||||
|
||||
var val = result.RawData;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case "up":
|
||||
case "parent":
|
||||
|
||||
this.VisibleNode = (this.VisibleNode?.ParentNode);
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
var n = (this.VisibleNode != null ? this.VisibleNode.FindNodeByValue(val) : this.Nodes.FirstOrDefault(a => a.Value == val));
|
||||
|
||||
if (n == null)
|
||||
return;
|
||||
|
||||
|
||||
if (n.ChildNodes.Count > 0)
|
||||
{
|
||||
this.VisibleNode = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SelectedNode = (this.SelectedNode != n ? n : null);
|
||||
}
|
||||
|
||||
result.Handled = true;
|
||||
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override async Task Render(MessageResult result)
|
||||
{
|
||||
var startnode = this.VisibleNode;
|
||||
|
||||
var nodes = (startnode?.ChildNodes ?? this.Nodes);
|
||||
|
||||
ButtonForm bf = new ButtonForm();
|
||||
|
||||
if (startnode != null)
|
||||
{
|
||||
bf.AddButtonRow(new ButtonBase(this.MoveUpIcon, "up"), new ButtonBase(startnode.Text, "parent"));
|
||||
}
|
||||
|
||||
foreach (var n in nodes)
|
||||
{
|
||||
var s = n.Text;
|
||||
if (this.SelectedNode == n)
|
||||
{
|
||||
s = "[ " + s + " ]";
|
||||
}
|
||||
|
||||
bf.AddButtonRow(new ButtonBase(s, n.Value, n.Url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
this.MessageId = m.MessageId;
|
||||
}
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
return (this.VisibleNode?.GetPath() ?? "\\");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TelegramBotBase.Controls.Inline
|
||||
{
|
||||
public class TreeViewNode
|
||||
{
|
||||
public String Text { get; set; }
|
||||
|
||||
public String Value { get; set; }
|
||||
|
||||
public String Url { get; set; }
|
||||
|
||||
public List<TreeViewNode> ChildNodes { get; set; } = new List<TreeViewNode>();
|
||||
|
||||
public TreeViewNode ParentNode { get; set; }
|
||||
|
||||
public TreeViewNode(String Text, String Value)
|
||||
{
|
||||
this.Text = Text;
|
||||
this.Value = Value;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, String Url) : this(Text, Value)
|
||||
{
|
||||
this.Url = Url;
|
||||
}
|
||||
|
||||
public TreeViewNode(String Text, String Value, params TreeViewNode[] childnodes) : this(Text, Value)
|
||||
{
|
||||
foreach(var c in childnodes)
|
||||
{
|
||||
AddNode(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddNode(TreeViewNode node)
|
||||
{
|
||||
node.ParentNode = this;
|
||||
ChildNodes.Add(node);
|
||||
}
|
||||
|
||||
public TreeViewNode FindNodeByValue(String Value)
|
||||
{
|
||||
return this.ChildNodes.FirstOrDefault(a => a.Value == Value);
|
||||
}
|
||||
|
||||
public String GetPath()
|
||||
{
|
||||
String s = "\\" + this.Value;
|
||||
var p = this;
|
||||
while (p.ParentNode != null)
|
||||
{
|
||||
s = "\\" + p.ParentNode.Value + s;
|
||||
p = p.ParentNode;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user