TelegramByLeo/Src/Bottons/Inline.mqh

490 lines
18 KiB
MQL5

//+------------------------------------------------------------------+
//| Inline.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property strict
#ifndef TELEGRAMBYLEO_SRC_BOTTONS_INLINE_MQH
#define TELEGRAMBYLEO_SRC_BOTTONS_INLINE_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Def.mqh"
2026-09-26 16:42:14 -05:00
#include "KeyboardBase.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define TLGBYLEO_TXT_OFF_TEXT_OPEN 0
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_LEN_TEXT_OPEN 9
#define TLGBYLEO_TXT_OFF_STYLE_KEY 9
#define TLGBYLEO_TXT_LEN_STYLE_KEY 10
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_URL_KEY 19
#define TLGBYLEO_TXT_LEN_URL_KEY 8
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_CALLBACK_DATA_KEY 27
#define TLGBYLEO_TXT_LEN_CALLBACK_DATA_KEY 18
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_COPY_TEXT_OPEN 45
#define TLGBYLEO_TXT_LEN_COPY_TEXT_OPEN 22
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_SWITCH_INLINE_QUERY_KEY 67
#define TLGBYLEO_TXT_LEN_SWITCH_INLINE_QUERY_KEY 24
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_SWITCH_INLINE_QUERY_CURR_CHAT_KEY 91
#define TLGBYLEO_TXT_LEN_SWITCH_INLINE_QUERY_CURR_CHAT_KEY 37
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_DISABLED_FIELD 128
#define TLGBYLEO_TXT_LEN_DISABLED_FIELD 14
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_SWITCH_CHOSEN_CHAT_OPEN 142
#define TLGBYLEO_TXT_LEN_SWITCH_CHOSEN_CHAT_OPEN 36
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_QUERY_KEY 178
#define TLGBYLEO_TXT_LEN_QUERY_KEY 9
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_TRUE_LIT 187
#define TLGBYLEO_TXT_LEN_TRUE_LIT 4
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_FALSE_LIT 191
#define TLGBYLEO_TXT_LEN_FALSE_LIT 5
2026-09-26 11:29:53 -05:00
#define TLGBYLEO_TXT_OFF_INLINE_KEYBOARD_OPEN 196
#define TLGBYLEO_TXT_LEN_INLINE_KEYBOARD_OPEN 20
2026-09-26 16:42:14 -05:00
//---
const uchar g_tlginline_keyboard_texts[] =
{
2026-09-26 16:42:14 -05:00
'{', '"', 't', 'e', 'x', 't', '"', ':', '"', // [0..8] TEXT_OPEN: {"text":"
',', '"', 's', 't', 'y', 'l', 'e', '"', ':', '"', // [9..18] STYLE_KEY: ,"style":"
',', '"', 'u', 'r', 'l', '"', ':', '"', // [19..26] URL_KEY: ,"url":"
2026-09-26 11:29:53 -05:00
',', '"', 'c', 'a', 'l', 'l', 'b', 'a', 'c', 'k', '_', 'd', 'a', 't', 'a', '"', ':', '"', // [27..44] CALLBACK_DATA_KEY: ,"callback_data":"
',', '"', 'c', 'o', 'p', 'y', '_', 't', 'e', 'x', 't', '"', ':', '{', '"', 't', 'e', 'x', 't', '"', ':', '"',
2026-09-26 11:29:53 -05:00
// [45..66] COPY_TEXT_OPEN: ,"copy_text":{"text":"
',', '"', 's', 'w', 'i', 't', 'c', 'h', '_', 'i', 'n', 'l', 'i', 'n', 'e', '_', 'q', 'u', 'e', 'r', 'y', '"', ':', '"',
2026-09-26 11:29:53 -05:00
// [67..90] SWITCH_INLINE_QUERY_KEY: ,"switch_inline_query":"
',', '"', 's', 'w', 'i', 't', 'c', 'h', '_', 'i', 'n', 'l', 'i', 'n', 'e', '_', 'q', 'u', 'e', 'r', 'y', '_', 'c', 'u', 'r', 'r',
2026-09-26 11:29:53 -05:00
'e', 'n', 't', '_', 'c', 'h', 'a', 't', '"', ':', '"', // [91..127] SWITCH_INLINE_QUERY_CURR_CHAT_KEY
',', '"', 'd', 'i', 's', 'a', 'b', 'l', 'e', 'd', '"', ':', '{', '}',
2026-09-26 11:29:53 -05:00
// [128..141] DISABLED_FIELD: ,"disabled":{}
',', '"', 's', 'w', 'i', 't', 'c', 'h', '_', 'i', 'n', 'l', 'i', 'n', 'e', '_', 'q', 'u', 'e', 'r', 'y', '_',
2026-09-26 11:29:53 -05:00
'c', 'h', 'o', 's', 'e', 'n', '_', 'c', 'h', 'a', 't', '"', ':', '{', // [142..177] SWITCH_CHOSEN_CHAT_OPEN
'"', 'q', 'u', 'e', 'r', 'y', '"', ':', '"',
2026-09-26 11:29:53 -05:00
// [178..186] QUERY_KEY: "query":"
't', 'r', 'u', 'e', // [187..190] TRUE_LIT
'f', 'a', 'l', 's', 'e', // [191..195] FALSE_LIT
'{', '"', 'i', 'n', 'l', 'i', 'n', 'e', '_', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '"', ':', '[' // [196..215] INLINE_KEYBOARD_OPEN: {"inline_keyboard":[
};
//+------------------------------------------------------------------+
#define TLGBYLEO_BTN_OPEN_TEXT(text_v, text_len_v) \
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_TEXT_OPEN, TLGBYLEO_TXT_LEN_TEXT_OPEN); \
CJsonEscape::Encode(text_v, text_len_v, m_buf, m_pos); \
m_buf[m_pos++] = '"';
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-09-26 16:42:14 -05:00
class CTlgInlineKeyboard : public CTlgKeyboardBase
{
public:
//---
2026-09-25 21:10:24 -05:00
//ulong m_meta[];
//int m_meta_s;
//---
2026-09-25 21:10:24 -05:00
ENUM_TLGBYLEO_INLINEKEYBOARD_STYLE m_style;
private:
2026-09-25 21:10:24 -05:00
// int m_meta_r;
public:
2026-09-26 11:29:53 -05:00
CTlgInlineKeyboard(uint initial_cap = 256);
~CTlgInlineKeyboard(void) {}
//---
2026-09-26 16:42:14 -05:00
__forceinline void Clear() { m_pos = 0; m_in_row = false; m_in_boton = false; }
2026-09-26 11:29:53 -05:00
void Init();
void Finish();
//---
2026-09-26 16:42:14 -05:00
__forceinline CTlgInlineKeyboard* AddRow() { AddRowImpl(); return &this; }
__forceinline CTlgInlineKeyboard* EndRow() { EndRowImpl(); return &this; }
2026-09-26 11:29:53 -05:00
//--- botones
//- normal
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* AddBtn(const string& text);
2026-09-26 11:29:53 -05:00
//-- ext
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* AddBtnUrl(const string& text, const string& url);
CTlgInlineKeyboard* AddBtnCallbackData(const string& text, const string& callback_data);
CTlgInlineKeyboard* AddBtnCallbackData(const string& text, const CStringFixed<MQLA_B(64)>& callback_data);
CTlgInlineKeyboard* AddBtnCopyText(const string& text, const string& copy_text);
// Inline query
CTlgInlineKeyboard* AddBtnSwithInlineQuery(const string& text, const string& switch_inline_query);
CTlgInlineKeyboard* AddBtnSwithInlineQueryCurrChat(const string& text, const string& switch_inline_query_current_chat);
CTlgInlineKeyboard* AddBtnSwithInlineQueryChosenOther(const string& text, const string& query, uchar flags);
// Disabled
CTlgInlineKeyboard* AddBtnDisabled(const string& text, const CStringFixed<MQLA_B(8)>& callback_data_empty);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-09-26 11:29:53 -05:00
CTlgInlineKeyboard::CTlgInlineKeyboard(uint initial_cap = 256)
2026-09-26 16:42:14 -05:00
: CTlgKeyboardBase(initial_cap)
{
}
2026-09-26 11:29:53 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTlgInlineKeyboard::Init(void)
{
//---
m_pos = 0;
m_in_row = false;
m_in_boton = false;
//--- {"inline_keyboard":[
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_TXT_LEN_INLINE_KEYBOARD_OPEN)
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_INLINE_KEYBOARD_OPEN, TLGBYLEO_TXT_LEN_INLINE_KEYBOARD_OPEN);
}
//+------------------------------------------------------------------+
void CTlgInlineKeyboard::Finish(void)
{
TLGBYLEO_KEYBORAD_RESERVE(2)
m_buf[m_pos++] = ']';
m_buf[m_pos++] = '}';
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtn(const string &text)
{
2026-09-25 21:10:24 -05:00
//--- 22 +
const int len_style = (m_style != WRONG_VALUE) ? g_tlgbyleo_inlinekeyboar_style[m_style].len : 0;
const int str_len = StringLen(text);
const int req = (str_len * 6) + (len_style) + (2 + 4 + 2 + 2 + 1 + 1 + 5 + 3 + 2 + 1) + 1;
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- style: unico caso que cambia entre metodos, se queda manual tal cual
if(m_style != WRONG_VALUE)
{
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_STYLE_KEY, TLGBYLEO_TXT_LEN_STYLE_KEY);
2026-09-25 21:10:24 -05:00
m_pos += ArrayCopy(m_buf, g_tlgbyleo_inlinekeyboar_style[m_style].raw, m_pos, 0, len_style);
m_buf[m_pos++] = '"';
}
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnUrl(const string &text, const string &url)
{
2026-09-25 21:10:24 -05:00
//---
const int str_len = StringLen(text);
const int url_len = StringLen(url);
const int req = (str_len * 6) + (url_len * 6) + 32;
TLGBYLEO_KEYBORAD_RESERVE(req)
2026-09-25 21:10:24 -05:00
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
2026-09-25 21:10:24 -05:00
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"url":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_URL_KEY, TLGBYLEO_TXT_LEN_URL_KEY);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(url, url_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
2026-09-25 21:10:24 -05:00
//+------------------------------------------------------------------+
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnCallbackData(const string &text, const string &callback_data)
{
//---
const int str_len = StringLen(text);
const int cb_len = StringLen(callback_data);
const int req = (str_len * 6) + (cb_len * 6) + 40;
TLGBYLEO_KEYBORAD_RESERVE(req)
2026-09-25 21:10:24 -05:00
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
2026-09-25 21:10:24 -05:00
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"callback_data":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_CALLBACK_DATA_KEY, TLGBYLEO_TXT_LEN_CALLBACK_DATA_KEY);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(callback_data, cb_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
2026-09-25 21:10:24 -05:00
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
2026-09-25 21:10:24 -05:00
//---
return &this;
}
2026-09-25 21:10:24 -05:00
//+------------------------------------------------------------------+
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnCallbackData(const string &text, const CStringFixed<MQLA_B(64)> &callback_data)
{
//---
const int str_len = StringLen(text);
const int req = (str_len * 6) + (callback_data.len * 6) + 40;
TLGBYLEO_KEYBORAD_RESERVE(req)
2026-09-25 21:10:24 -05:00
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
2026-09-25 21:10:24 -05:00
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"callback_data":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_CALLBACK_DATA_KEY, TLGBYLEO_TXT_LEN_CALLBACK_DATA_KEY);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(callback_data.raw, callback_data.len, m_buf, m_pos);
m_buf[m_pos++] = '"';
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnCopyText(const string &text, const string &copy_text)
{
//---
2026-09-25 21:10:24 -05:00
const int str_len = StringLen(text);
const int copy_len = StringLen(copy_text);
const int req = (str_len * 6) + (copy_len * 6) + 48;
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"copy_text":{"text":"<escapado>"}
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_COPY_TEXT_OPEN, TLGBYLEO_TXT_LEN_COPY_TEXT_OPEN);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(copy_text, copy_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
m_buf[m_pos++] = '}';
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnSwithInlineQuery(const string &text, const string &switch_inline_query)
{
//---
const int str_len = StringLen(text);
const int q_len = StringLen(switch_inline_query);
const int req = (str_len * 6) + (q_len * 6) + 48;
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"switch_inline_query":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_SWITCH_INLINE_QUERY_KEY, TLGBYLEO_TXT_LEN_SWITCH_INLINE_QUERY_KEY);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(switch_inline_query, q_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
2026-09-25 21:10:24 -05:00
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnSwithInlineQueryCurrChat(const string &text, const string &switch_inline_query_current_chat)
{
//---
const int str_len = StringLen(text);
const int q_len = StringLen(switch_inline_query_current_chat);
const int req = (str_len * 6) + (q_len * 6) + 64;
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
2026-09-25 21:10:24 -05:00
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"switch_inline_query_current_chat":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_SWITCH_INLINE_QUERY_CURR_CHAT_KEY, TLGBYLEO_TXT_LEN_SWITCH_INLINE_QUERY_CURR_CHAT_KEY);
2026-09-25 21:10:24 -05:00
CJsonEscape::Encode(switch_inline_query_current_chat, q_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnSwithInlineQueryChosenOther(const string &text, const string &query, uchar flags)
{
//---
const int str_len = StringLen(text);
const int q_len = StringLen(query);
const int req = (str_len * 6) + (q_len * 6) + 256; // generoso: objeto anidado + hasta 4 bools
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"switch_inline_query_chosen_chat":{
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_SWITCH_CHOSEN_CHAT_OPEN, TLGBYLEO_TXT_LEN_SWITCH_CHOSEN_CHAT_OPEN);
//--- query (opcional, va primero si viene)
bool need_comma_inner = false;
if(q_len > 0)
{
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_QUERY_KEY, TLGBYLEO_TXT_LEN_QUERY_KEY);
CJsonEscape::Encode(query, q_len, m_buf, m_pos);
m_buf[m_pos++] = '"';
need_comma_inner = true;
}
//--- flags: 2 bits por campo, bajo=valor, alto=activo. Recorremos con CTZ (tabla de 8 bits).
while(flags)
{
const uchar low = flags & (~flags + 1); // aisla el bit menos significativo prendido
const uchar bitpos = g_tsntables_table_ctz_i8[low];
const uchar idx = bitpos >> 1; // indice en la tabla
bool value;
//--- detecamos true o false
if((bitpos & 1) == 0) // es par. osea el ctz vale (0, 2, 4, 6).. por loq que el "bajo" esta prendido..
{
// ahora revisamos el que le sigue
if(((1u << (bitpos + 1)) & flags) == 0) // no esta activado.. osea tiene un valor (True) pero no esta activado (malformacion)
{
flags &= (flags - 1); // quitamos este flag
continue;
}
//--
// Si tiene el que le sigue activado entonces quitamos dos de una..
value = true;
flags &= (flags - 1);
flags &= (flags - 1);
}
else
{
value = false;
flags &= (flags - 1);
}
//--- coma entre campos
if(need_comma_inner)
m_buf[m_pos++] = ',';
need_comma_inner = true;
//--- key (con comillas y ":") indexada directo por el enum, sin switch
m_pos += ArrayCopy(m_buf, g_tlgbyleo_switchchat_field_keys[idx].raw, m_pos, 0, g_tlgbyleo_switchchat_field_keys[idx].len);
//--- valor
if(value)
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_TRUE_LIT, TLGBYLEO_TXT_LEN_TRUE_LIT);
else
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_FALSE_LIT, TLGBYLEO_TXT_LEN_FALSE_LIT);
}
//---
m_buf[m_pos++] = '}'; // cierra switch_inline_query_chosen_chat
//---
m_buf[m_pos++] = '}'; // cierra el boton
m_in_boton = true;
//---
return &this;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// 1. empty debe de seer ASCCI puro
CTlgInlineKeyboard* CTlgInlineKeyboard::AddBtnDisabled(const string &text, const CStringFixed<MQLA_B(8)> &callback_data_empty)
{
//---
const int str_len = StringLen(text);
const int req = (str_len * 6) + (callback_data_empty.len) + 48;
TLGBYLEO_KEYBORAD_RESERVE(req)
//--- coma si ya hay un boton antes en esta fila
if(m_in_boton)
m_buf[m_pos++] = ',';
//---
TLGBYLEO_BTN_OPEN_TEXT(text, str_len)
//--- ,"callback_data":"<escapado>"
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_CALLBACK_DATA_KEY, TLGBYLEO_TXT_LEN_CALLBACK_DATA_KEY);
m_pos += ArrayCopy(m_buf, callback_data_empty.raw, m_pos, 0, callback_data_empty.len);
m_buf[m_pos++] = '"';
//--- ,"disabled":{}
m_pos += ArrayCopy(m_buf, g_tlginline_keyboard_texts, m_pos, TLGBYLEO_TXT_OFF_DISABLED_FIELD, TLGBYLEO_TXT_LEN_DISABLED_FIELD);
//---
m_buf[m_pos++] = '}';
m_in_boton = true;
//---
return &this;
}
}
#endif // TELEGRAMBYLEO_SRC_BOTTONS_INLINE_MQH
//+------------------------------------------------------------------+