264 lines
11 KiB
MQL5
264 lines
11 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| ReplyMarkup.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_REPLYMARKUP_MQH
| |||
#define TELEGRAMBYLEO_SRC_BOTTONS_REPLYMARKUP_MQH
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
#include "KeyboardBase.mqh"
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
namespace TSN
| |||
{
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
//----
| |||
#define TLGBYLEO_RK_OFF_IS_PERSISTENT_KEY 0
| |||
#define TLGBYLEO_RK_LEN_IS_PERSISTENT_KEY 16
| |||
#define TLGBYLEO_RK_OFF_RESIZE_KEYBOARD_KEY 16
| |||
#define TLGBYLEO_RK_LEN_RESIZE_KEYBOARD_KEY 18
| |||
#define TLGBYLEO_RK_OFF_ONE_TIME_KEYBOARD_KEY 34
| |||
#define TLGBYLEO_RK_LEN_ONE_TIME_KEYBOARD_KEY 20
| |||
#define TLGBYLEO_RK_OFF_INPUT_FIELD_PLACEHOLDER_KEY 54
| |||
#define TLGBYLEO_RK_LEN_INPUT_FIELD_PLACEHOLDER_KEY 27
| |||
#define TLGBYLEO_RK_OFF_SELECTIVE_KEY 81
| |||
#define TLGBYLEO_RK_LEN_SELECTIVE_KEY 12
| |||
#define TLGBYLEO_RK_OFF_FORCE_REPLY_KEY 93
| |||
#define TLGBYLEO_RK_LEN_FORCE_REPLY_KEY 14
| |||
#define TLGBYLEO_RK_OFF_KEYBOARD_ARR_KEY 107
| |||
#define TLGBYLEO_RK_LEN_KEYBOARD_ARR_KEY 12
| |||
#define TLGBYLEO_RK_OFF_TRUE_LIT 119
| |||
#define TLGBYLEO_RK_LEN_TRUE_LIT 4
| |||
#define TLGBYLEO_RK_OFF_FALSE_LIT 123
| |||
#define TLGBYLEO_RK_LEN_FALSE_LIT 5
| |||
| |||
//----
| |||
const uchar g_tlgreplykeyboard_texts[] =
| |||
{
| |||
'"', 'i', 's', '_', 'p', 'e', 'r', 's', 'i', 's', 't', 'e', 'n', 't', '"', ':', // [0..15] IS_PERSISTENT_KEY: "is_persistent":
| |||
'"', 'r', 'e', 's', 'i', 'z', 'e', '_', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '"', ':', // [16..33] RESIZE_KEYBOARD_KEY: "resize_keyboard":
| |||
'"', 'o', 'n', 'e', '_', 't', 'i', 'm', 'e', '_', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '"', ':', // [34..53] ONE_TIME_KEYBOARD_KEY: "one_time_keyboard":
| |||
'"', 'i', 'n', 'p', 'u', 't', '_', 'f', 'i', 'e', 'l', 'd', '_',
| |||
'p', 'l', 'a', 'c', 'e', 'h', 'o', 'l', 'd', 'e', 'r', '"', ':', '"', // [54..80] INPUT_FIELD_PLACEHOLDER_KEY: "input_field_placeholder":"
| |||
'"', 's', 'e', 'l', 'e', 'c', 't', 'i', 'v', 'e', '"', ':', // [81..92] SELECTIVE_KEY: "selective":
| |||
'"', 'f', 'o', 'r', 'c', 'e', '_', 'r', 'e', 'p', 'l', 'y', '"', ':', // [93..106] FORCE_REPLY_KEY: "force_reply":
| |||
'"', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '"', ':', '[', // [107..118] KEYBOARD_ARR_KEY: "keyboard":[
| |||
't', 'r', 'u', 'e', // [119..122] TRUE_LIT
| |||
'f', 'a', 'l', 's', 'e' // [123..127] FALSE_LIT
| |||
};
| |||
| |||
//---
| |||
const uchar g_tlgreplykeyboard_remove[] =
| |||
{
| |||
//---
| |||
'{', '"', 'r', 'e', 'm', 'o', 'v', 'e', '_', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '"', ':', 't', 'r', 'u', 'e', '}'
| |||
};
| |||
| |||
| |||
//---
| |||
#define TLGBYLEO_RK_BOOL_FIELD(off, len, value) \
| |||
if(m_has_field) \
| |||
m_buf[m_pos++] = ','; \
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, off, len); \
| |||
if(value) \
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, TLGBYLEO_RK_OFF_TRUE_LIT, TLGBYLEO_RK_LEN_TRUE_LIT); \
| |||
else \
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, TLGBYLEO_RK_OFF_FALSE_LIT, TLGBYLEO_RK_LEN_FALSE_LIT); \
| |||
m_has_field = true;
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
class CTlgReplyKeyboard : public CTlgKeyboardBase
| |||
{
| |||
private:
| |||
//---
| |||
bool m_has_field;
| |||
| |||
public:
| |||
CTlgReplyKeyboard(uint initial_cap = 256);
| |||
~CTlgReplyKeyboard(void) {}
| |||
| |||
//---
| |||
__forceinline void Clear() { m_pos = 0; m_in_row = false; m_in_boton = false; m_has_field = false; }
| |||
void Init();
| |||
void InitArr();
| |||
void Finish();
| |||
| |||
//--- config (nivel objeto, antes de InitArr())
| |||
CTlgReplyKeyboard* IsPersistent(bool value);
| |||
CTlgReplyKeyboard* ResizeKeyboard(bool value);
| |||
CTlgReplyKeyboard* OneTimeKeyboard(bool value);
| |||
CTlgReplyKeyboard* InputFieldPlaceholder(const string& text);
| |||
CTlgReplyKeyboard* InputFieldPlaceholder(const CStringFixed<MQLA_B(64)>& text);
| |||
CTlgReplyKeyboard* Selective(bool value);
| |||
CTlgReplyKeyboard* ForceReply(bool value);
| |||
| |||
//--- filas / botones
| |||
__forceinline CTlgReplyKeyboard* AddRow() { AddRowImpl(); return &this; }
| |||
__forceinline CTlgReplyKeyboard* EndRow() { EndRowImpl(); return &this; }
| |||
CTlgReplyKeyboard* AddBtn(const string& text);
| |||
};
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard::CTlgReplyKeyboard(uint initial_cap = 256)
| |||
: CTlgKeyboardBase(initial_cap), m_has_field(false)
| |||
{
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
void CTlgReplyKeyboard::Init(void)
| |||
{
| |||
//---
| |||
m_pos = 0;
| |||
m_in_row = false;
| |||
m_in_boton = false;
| |||
m_has_field = false;
| |||
| |||
//--- {
| |||
TLGBYLEO_KEYBORAD_RESERVE(1)
| |||
m_buf[m_pos++] = '{';
| |||
}
| |||
| |||
| |||
//+------------------------------------------------------------------+
| |||
void CTlgReplyKeyboard::Finish(void)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(2)
| |||
m_buf[m_pos++] = ']';
| |||
m_buf[m_pos++] = '}';
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::IsPersistent(bool value)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_IS_PERSISTENT_KEY + 6)
| |||
TLGBYLEO_RK_BOOL_FIELD(TLGBYLEO_RK_OFF_IS_PERSISTENT_KEY, TLGBYLEO_RK_LEN_IS_PERSISTENT_KEY, value)
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::ResizeKeyboard(bool value)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_RESIZE_KEYBOARD_KEY + 6)
| |||
TLGBYLEO_RK_BOOL_FIELD(TLGBYLEO_RK_OFF_RESIZE_KEYBOARD_KEY, TLGBYLEO_RK_LEN_RESIZE_KEYBOARD_KEY, value)
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::OneTimeKeyboard(bool value)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_ONE_TIME_KEYBOARD_KEY + 6)
| |||
TLGBYLEO_RK_BOOL_FIELD(TLGBYLEO_RK_OFF_ONE_TIME_KEYBOARD_KEY, TLGBYLEO_RK_LEN_ONE_TIME_KEYBOARD_KEY, value)
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::Selective(bool value)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_SELECTIVE_KEY + 6)
| |||
TLGBYLEO_RK_BOOL_FIELD(TLGBYLEO_RK_OFF_SELECTIVE_KEY, TLGBYLEO_RK_LEN_SELECTIVE_KEY, value)
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::ForceReply(bool value)
| |||
{
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_FORCE_REPLY_KEY + 6)
| |||
TLGBYLEO_RK_BOOL_FIELD(TLGBYLEO_RK_OFF_FORCE_REPLY_KEY, TLGBYLEO_RK_LEN_FORCE_REPLY_KEY, value)
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::InputFieldPlaceholder(const string &text)
| |||
{
| |||
//---
| |||
const int len = StringLen(text);
| |||
const int req = (len * 6) + TLGBYLEO_RK_LEN_INPUT_FIELD_PLACEHOLDER_KEY + 2;
| |||
TLGBYLEO_KEYBORAD_RESERVE(req)
| |||
| |||
//---
| |||
if(m_has_field)
| |||
m_buf[m_pos++] = ',';
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, TLGBYLEO_RK_OFF_INPUT_FIELD_PLACEHOLDER_KEY, TLGBYLEO_RK_LEN_INPUT_FIELD_PLACEHOLDER_KEY);
| |||
CJsonEscape::Encode(text, len, m_buf, m_pos);
| |||
m_buf[m_pos++] = '"';
| |||
m_has_field = true;
| |||
| |||
//---
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::InputFieldPlaceholder(const CStringFixed<MQLA_B(64)> &text)
| |||
{
| |||
//---
| |||
const int req = TLGBYLEO_RK_LEN_INPUT_FIELD_PLACEHOLDER_KEY + text.len + 2;
| |||
TLGBYLEO_KEYBORAD_RESERVE(req)
| |||
| |||
//---
| |||
if(m_has_field)
| |||
m_buf[m_pos++] = ',';
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, TLGBYLEO_RK_OFF_INPUT_FIELD_PLACEHOLDER_KEY, TLGBYLEO_RK_LEN_INPUT_FIELD_PLACEHOLDER_KEY);
| |||
m_pos += ArrayCopy(m_buf, text.raw, m_pos, 0, text.len);
| |||
m_buf[m_pos++] = '"';
| |||
m_has_field = true;
| |||
| |||
//---
| |||
return &this;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
void CTlgReplyKeyboard::InitArr(void)
| |||
{
| |||
//--- ,"keyboard":[ (coma solo si ya se escribio algun campo antes)
| |||
TLGBYLEO_KEYBORAD_RESERVE(TLGBYLEO_RK_LEN_KEYBOARD_ARR_KEY + 1)
| |||
if(m_has_field)
| |||
m_buf[m_pos++] = ',';
| |||
m_pos += ArrayCopy(m_buf, g_tlgreplykeyboard_texts, m_pos, TLGBYLEO_RK_OFF_KEYBOARD_ARR_KEY, TLGBYLEO_RK_LEN_KEYBOARD_ARR_KEY);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
CTlgReplyKeyboard* CTlgReplyKeyboard::AddBtn(const string &text)
| |||
{
| |||
//---
| |||
const int len = StringLen(text);
| |||
const int req = (len * 6) + 4;
| |||
TLGBYLEO_KEYBORAD_RESERVE(req)
| |||
| |||
//--- coma si ya hay un boton antes en esta fila
| |||
if(m_in_boton)
| |||
m_buf[m_pos++] = ',';
| |||
| |||
//---
| |||
m_buf[m_pos++] = '"';
| |||
CJsonEscape::Encode(text, len, m_buf, m_pos);
| |||
m_buf[m_pos++] = '"';
| |||
m_in_boton = true;
| |||
| |||
//---
| |||
return &this;
| |||
}
| |||
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
#endif // TELEGRAMBYLEO_SRC_BOTTONS_REPLYMARKUP_MQH
|