KeyboardBuilderBase
using PRTelegramBot.Extensions;
namespace PRTelegramBot.Builders.Keyboard
{
/// <summary>
/// Базовый класс для построения клавиатур.
/// </summary>
/// <typeparam name="TButton">Тип кнопки.</typeparam>
/// <typeparam name="TKeyboard">Тип клавиатуры.</typeparam>
/// <typeparam name="TSelf">Тип билдера.</typeparam>
public abstract class KeyboardBuilderBase<TButton, TKeyboard, TSelf>
where TSelf : KeyboardBuilderBase<TButton, TKeyboard, TSelf>
{
#region Константы
/// <summary>
/// Название пустой кнопки по умолчанию.
/// </summary>
public const string KEY_EMPTY_BUTTON_NAME = "%EMPTY_BUTTON%";
#endregion
#region Поля и свойства
/// <summary>
/// Кнопки клавиатуры.
/// </summary>
protected List<List<TButton>> buttons = new();
/// <summary>
/// Имя кнопки для пустой ячейки. Используется, если нужно визуально указать, что место занято,
/// но кнопка не выполняет действий.
/// По умолчанию стоит простой символ "·".
/// </summary>
protected string emptyButtonName = " ";
#endregion
#region Методы
/// <summary>
/// Устанавливает текст, который будет использоваться
/// для "пустых" кнопок — декоративных или заполняющих элементов.
/// </summary>
/// <param name="buttonName">Текст для пустой кнопки.</param>
/// <returns>Текущий экземпляр билдера.</returns>
public TSelf SetEmptyButtonsName(string buttonName)
{
this.emptyButtonName = buttonName;
return (TSelf)this;
}
/// <summary>
/// Добавить кнопку.
/// </summary>
/// <param name="button">Кнопка.</param>
/// <param name="newRow">Если true — каждая кнопка будет добавляться на новую строку.</param>
public TSelf AddButton(TButton button, bool newRow = false)
{
if (buttons.Count == 0)
buttons.Add(new List<TButton>());
var lastRow = buttons[^1];
if (newRow)
this.AddRow();
lastRow = buttons[^1];
lastRow.Add(button);
return (TSelf)this;
}
/// <summary>
/// Добавить кнопки.
/// </summary>
/// <param name="buttons">Коллекция кнопок.</param>
public TSelf AddButton(params TButton[] buttons)
{
foreach (var button in buttons)
this.AddButton(button);
return (TSelf)this;
}
/// <summary>
/// Добавить новую строку.
/// </summary>
public TSelf AddRow()
{
var lastRow = buttons[^1];
if (lastRow.Any())
buttons.Add(new List<TButton>());
return (TSelf)this;
}
/// <summary>
/// Добавить новую строку с кнопкой.
/// </summary>
/// <param name="button">Кнопка.</param>
public TSelf AddRowWithButton(TButton button)
{
this.AddRow();
this.AddButton(button);
return (TSelf)this;
}
/// <summary>
/// Добавить новую строку с кнопками.
/// </summary>
/// <param name="buttons">Кнопки.</param>
public TSelf AddRowWithButtons(params TButton[] buttons)
{
this.AddRow();
this.AddButton(buttons);
return (TSelf)this;
}
/// <summary>
/// Очистить клавиатуру.
/// </summary>
public void Clear()
{
buttons.Clear();
}
/// <summary>
/// Генерирует кнопки из коллекции с фильтром.
/// </summary>
public TSelf GenerateButtons<T>(IEnumerable<T> items, Func<T, TButton> generator, Predicate<T>? filter = null, bool addNewRow = false)
{
foreach (var item in items)
{
if (filter == null || filter(item))
this.AddButton(generator(item), addNewRow);
}
return (TSelf)this;
}
/// <summary>
/// Генерирует строку кнопок из коллекции.
/// </summary>
/// <typeparam name="T">Тип.</typeparam>
/// <param name="items">Объекты.</param>
/// <param name="generator">Генератор.</param>
/// <returns></returns>
public TSelf GenerateRow<T>(IEnumerable<T> items, Func<T, TButton> generator)
{
this.AddRow();
foreach (var item in items)
this.AddButton(generator(item));
return (TSelf)this;
}
/// <summary>
/// Получает коллекцию кнопок в формате строк и столбцов (таблицы/грида).
/// </summary>
/// <returns>Коллекция кнопок.</returns>
public IEnumerable<IEnumerable<TButton>> GetButtonGrid()
{
return buttons.ToList();
}
/// <summary>
/// Возвращает все кнопки как одну плоскую последовательность.
/// </summary>
/// <returns>Коллекция кнопок.</returns>
public IEnumerable<TButton> GetAllButtons()
{
return buttons.SelectMany(row => row ?? Enumerable.Empty<TButton>());
}
/// <summary>
/// Возвращает общее количество кнопок.
/// </summary>
public long GetAllButtonsCount()
{
return GetAllButtons().Count();
}
/// <summary>
/// Получить коллекцию кнопок из строки.
/// </summary>
/// <param name="rowIndex">Индекс строки.</param>
/// <returns>Коллекция кнопок из строки.</returns>
public IEnumerable<TButton> GetRow(int rowIndex)
{
return buttons.GetRow(rowIndex);
}
/// <summary>
/// Получить текущее количество строк.
/// </summary>
/// <returns>Количество строк.</returns>
public long GetRowCount()
{
return buttons.GetRowCount();
}
/// <summary>
/// Получить коллекцию кнопок из столбца.
/// </summary>
/// <param name="columnIndex">Индекс столбца.</param>
/// <returns>Коллекция кнопок из столбца.</returns>
public IEnumerable<TButton> GetColumn(int columnIndex)
{
return buttons.GetColumn(columnIndex);
}
/// <summary>
/// Получить количество столбцов.
/// </summary>
/// <returns>Количество столбцов.</returns>
public long GetColumnCount()
{
return buttons.GetColumnCount();
}
/// <summary>
///
/// </summary>
protected abstract void ReplaceEmptyButtons();
/// <summary>
/// Создать клавиатуру.
/// </summary>
/// <returns>Клавиатура.</returns>
public abstract TKeyboard Build();
#endregion
}
}
Last updated