GrapichsByLeo/PartInf/ParteInf.mqh
951 行
66 KiB
MQL5
Nique_372
2025-10-13 07:15:19 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| ParteInf.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372/news |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372/news"
#property strict
Nique_372
2025-10-13 12:26:22 -05:00
#ifndef HISTOGRAM_PARTE_INFORMATIVA_MAIN_BY_LEO_MQH
#define HISTOGRAM_PARTE_INFORMATIVA_MAIN_BY_LEO_MQH
#include "..\\General\\Canvas.mqh"
Nique_372
2025-10-13 07:15:19 -05:00
#include <Utils\\Funciones Array.mqh>
#include "..\\General\\ARGBGenerator.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*
Por defecto para los "objetos (texot, lengenda)"
que requierna texto los parametros font y fontsize seran invalidos, si no se espcifica un font o fontsize (como esta)
se usara el font y fontsize de canva, esto es util si se quiere agregar textos con el mismo fonty fontsize sin tener que llamar a textsetfont...
para eso se debera de llamar a la fucion TextSetFont que setea el font global y tambien guarda dichos valores dentro de canvas
que luego seran consultados
*/
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
enum ENUM_HISTOGRAM_PARTE_INFORMATIVA_POSICION
{
HISTOGRAM_PARTE_INF_DERECHA,
HISTOGRAM_PARTE_INF_IZQUIERDA
};
struct HistogramPartInfLineSep
{
int x1;
int y1;
int x2;
int y2;
int gap_init;
int gap_end;
uint clr;
uint style;
};
struct HistogramPartInfText
{
string text;
int x;
int y;
uint clr;
int fontsize;
string font;
};
struct HistogramPartInfLegend
{
HistogramPartInfText text;
int x1;
int y1;
int x2;
int y2;
int x1_borde;
int x2_borde;
int y1_borde;
int y2_borde;
uint clr_fondo;
uint clr_borde;
//---
void CalcCordinatesBorde() // Funcion qeu calcula las cordenas de los bordes
{
x1_borde = x1 - 1;
y1_borde = y1 - 1;
x2_borde = x2 + 1;
Nique_372
2025-10-13 07:15:19 -05:00
y2_borde = y2 + 1;
}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CHistogramParteInfo
{
private:
//--- Puntero a canvas (lo da la clase principal CHIsotgramn)
CCanvasCustom* m_canvas;
bool m_init;
int m_espacio_x1;
int m_espacio_y1;
int m_espacio_x2;
int m_espacio_y2;
int m_espacio_width;
int m_espacio_height;
//--- Data
HistogramPartInfLegend m_lengendas[]; // Legendas (y texto)
int m_lengedas_size;
HistogramPartInfLineSep m_lines_sep[]; // Line H speradora
int m_lines_sep_size;
HistogramPartInfText m_texts[]; // Textos;
int m_texts_size;
//--- Cordenadas actulzes de escritura
int m_curr_x;
int m_curr_y;
//---
static uint m_text_alingement;
//---
void RedrawPixels();
void ChangeY(int delta_y, int min_y);
public:
CHistogramParteInfo(void);
//--- Inicilizacion
void Init(CCanvasCustom* c, int x1, int y1, int x2, int y2, int gap_x_inicial, int gap_y_inicial);
//--- Cambio de cordenadas
// Cuando se cambia los tama<EFBFBD>o se reajuista las lineas separadoras
// Los altos y anchos de los textos NO SE RE REDUCEN precaucion, puede ocurrir bugs
void ChangeSizes(int new_width, int new_height);
// Cuando se cambia de cordenas se recalculta todo
void ChangeCordinates(int x1, int y1, int x2, int y2);
//
void ChangeCordinatesOne(int x1, int y1);
//--- A<EFBFBD>adir data
int AddLineSeparadora(int gap_init, int gap_end, uint clr, int y_avanzar, ENUM_LINE_STYLE style, bool update = false);
int AddText(const string &new_text, uint clr, int y_a_avanzar, int x_a_avanzar, string font = NULL, int font_size = 0, bool update = false);
int AddLegend(const string &new_text, uint clr_text, uint clr_rect, uint clr_rect_borde, int xgap, int rect_width, int rect_height, int y_a_avanzar, int x_a_avanzar,
string font = NULL, int font_size = 0, bool update = false);
//--- Obtener tama<EFBFBD>os
__forceinline int SizeLegendas() const { return m_lengedas_size; }
__forceinline int SizeTextos() const { return m_texts_size; }
__forceinline int SizeLineasSep() const { return m_lines_sep_size; }
//--- Eliminar
void Clean(uint clr_clean);
void CleanEspacio(uint clr_clean);
void RemoveLineSep(const int index, uint clr_clean, bool move_cordinates, bool redraw = false);
void RemoveText(const int index, uint clr_clean, bool move_cordinates, bool redraw = false);
void RemoveLegenda(const int index, uint clr_clean, bool move_cordinates, bool redraw = false);
//--- Modificar data existente u Obtener data existente
// Use el de la clase que lo tiene no este
//__forceinline void TextFontSet(int fontsize, string font); // Setea la fuente para proximos textos
//- Colores de la legenda
void LegendaSetNewsColors(const int index, uint new_clr_fondo, uint new_clr_borde, bool update = false);
__forceinline uint LegendaColorFondo(const int index) const { return m_lengendas[index].clr_fondo; }
__forceinline uint LegendaColorBorde(const int index) const { return m_lengendas[index].clr_borde; }
//- Texto de la legenda
void LegendaTextoValue(const int index, const string& new_value, uint clr_clean, string font = NULL, int font_size = 0, bool update = false);
__forceinline string LegendaTextoValue(const int index) const { return m_lengendas[index].text.text; }
void LegendaTextoColor(const int index, uint new_text_clr, bool update = false);
__forceinline uint LegendaTextoColor(const int index) const { return m_lengendas[index].text.clr; }
__forceinline HistogramPartInfText LegendaTexto(const int index) const { return m_lengendas[index].text; }
//- Texto
void TextoValue(const int index, const string& new_value, uint clr_clean, bool redraw = false);
__forceinline string TextoValue(const int index) const { return m_texts[index].text; }
void TextoColor(const int index, uint new_clr, bool redraw = false);
__forceinline uint TextoColor(const int index) const { return m_texts[index].clr; }
//- Linea separadora
void LineaSeparadoraStyle(const int index, uint new_style, bool redraw = false);
__forceinline uint LineaSeparadoraStyle(const int index) const { return m_lines_sep[index].style; }
void LineaSeparadoraColor(const int index, uint new_clr, bool redraw = false);
__forceinline uint LineaSeparadoraColor(const int index) const { return m_lines_sep[index].clr; }
//--- Cordenas de escritura
// X
__forceinline int CurrX() const { return m_curr_x; }
inline void CurrX(const int new_value) { m_curr_x = new_value; }
inline void CurrXAument(int value_add = 1) { m_curr_x += value_add; }
inline void CurrXReduce(int rest_value = 1) { m_curr_x -= rest_value; }
// y
__forceinline int CurrY() const { return m_curr_y; }
inline void CurrY(const int new_value) { m_curr_y = new_value; }
inline void CurrYAument(int value_add = 1) { m_curr_y += value_add; }
inline void CurrYReduce(int rest_value = 1) { m_curr_y -= rest_value; }
//--- Cordenadas
__forceinline int X1() const { return m_espacio_x1; }
__forceinline int X2() const { return m_espacio_x2; }
__forceinline int Y1() const { return m_espacio_y1; }
__forceinline int Y2() const { return m_espacio_y2; }
__forceinline int Width() const { return m_espacio_width; }
__forceinline int Height() const { return m_espacio_height; }
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
uint CHistogramParteInfo::m_text_alingement = TA_TOP | TA_LEFT;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CHistogramParteInfo::CHistogramParteInfo(void)
{
//--- General
m_canvas = NULL;
m_init = false;
m_espacio_x1 = 0;
m_espacio_y1 = 0;
m_espacio_x2 = 0;
m_espacio_y2 = 0;
m_espacio_width = 0;
m_espacio_height = 0;
//--- Data
ArrayResize(m_lengendas, 0); // Legendas (y texto)
m_lengedas_size = 0;
ArrayResize(m_lines_sep, 0); // Line H speradora
m_lines_sep_size = 0;
ArrayResize(m_texts, 0); // Textos;
m_texts_size = 0;
//--- Cordenadas actulzes de escritura
m_curr_x = 0;
m_curr_y = 0;
}
//+------------------------------------------------------------------+
//| Elimina un texto |
//+------------------------------------------------------------------+
void CHistogramParteInfo::RemoveText(const int index, uint clr_clean,
bool move_cordinates, bool redraw = false)
{
//--- Limpiar visualmente el texto
::TextSetFont(m_texts[index].font, m_texts[index].fontsize);
m_canvas.TextOuTF(m_texts[index].x,
m_texts[index].y,
m_texts[index].text,
clr_clean,
m_text_alingement);
//--- Mover elementos posteriores si se solicita
if(move_cordinates)
{
// Calcular altura del texto eliminado
uint w, h;
::TextGetSize(m_texts[index].text, w, h);
// Retroceder elementos posteriores
const int y_retroceso = (int)h;
ChangeY(-y_retroceso, m_texts[index].y);
}
//--- Eliminar del array
for(int i = index; i < m_texts_size - 1; i++)
m_texts[i] = m_texts[i + 1];
m_texts_size--;
ArrayResize(m_texts, m_texts_size);
//--- Redraw si se solicita
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| Elimina una leyenda |
//+------------------------------------------------------------------+
void CHistogramParteInfo::RemoveLegenda(const int index, uint clr_clean,
bool move_cordinates, bool redraw = false)
{
//--- Limpiamos pixeles
// Texto
::TextSetFont(m_lengendas[index].text.font, m_lengendas[index].text.fontsize);
m_canvas.TextOuTF(m_lengendas[index].text.x,
m_lengendas[index].text.y,
m_lengendas[index].text.text,
clr_clean,
m_text_alingement);
// Rectangulo
m_canvas.FillRectangle(m_lengendas[index].x1_borde,
m_lengendas[index].y1_borde,
m_lengendas[index].x2_borde,
m_lengendas[index].y2_borde,
clr_clean);
//--- Movemos cordenadas
if(move_cordinates)
{
//--- Cargamos el font y fontsize
::TextSetFont(m_lengendas[index].text.font,
m_lengendas[index].text.fontsize);
//--- Calculo del y ocupado por el texto
uint text_w, text_h;
::TextGetSize(m_lengendas[index].text.text, text_w, text_h);
//--- Calcula el "y" maximo
int rect_height = m_lengendas[index].y2 - m_lengendas[index].y1;
int y_retroceso = (int)text_h > rect_height ? (int)text_h : rect_height;
//--- Mover
ChangeY(-y_retroceso, m_lengendas[index].text.y);
}
//---
for(int i = index; i < m_lengedas_size - 1; i++)
m_lengendas[i] = m_lengendas[i + 1];
//---
m_lengedas_size--;
ArrayResize(m_lengendas, m_lengedas_size);
//---
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Funcion que se ejeuycta cuando se elimina uyn elemento y deja un "deltay"
void CHistogramParteInfo::ChangeY(int delta_y, int min_y)
{
//--- Texto
for(int i = 0; i < m_texts_size; i++)
{
if(m_texts[i].y < min_y)
continue; // Si el y es menor continua
m_texts[i].y += delta_y;
}
//--- Legenda
for(int i = 0; i < m_lengedas_size; i++)
{
if(m_lengendas[i].text.y < min_y)
continue; // Si el y es menor continua
m_lengendas[i].text.y += delta_y;
m_lengendas[i].y1 += delta_y;
m_lengendas[i].y2 += delta_y;
m_lengendas[i].CalcCordinatesBorde();
}
//--- Linea separadora
for(int i = 0; i < m_lines_sep_size; i++)
{
if(m_lines_sep[i].y1 < min_y)
continue; // Si el y es menor continua
m_lines_sep[i].y1 += delta_y;
m_lines_sep[i].y2 += delta_y;
}
//---
RedrawPixels();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::RemoveLineSep(const int index, uint clr_clean, bool move_cordinates, bool redraw = false)
{
//---
m_canvas.LineAA(m_lines_sep[index].x1,
m_lines_sep[index].y1,
m_lines_sep[index].x2,
m_lines_sep[index].y1,
clr_clean,
m_lines_sep[index].style);
//---
if(move_cordinates)
{
const int y_retroceso = fabs(m_lines_sep[index].y1 - m_lines_sep[index].y2);
ChangeY(-y_retroceso, m_lines_sep[index].y1);
Nique_372
2025-10-13 12:26:22 -05:00
}
//---
Nique_372
2025-10-13 07:15:19 -05:00
for(int i = index; i < m_lines_sep_size - 1; i++)
Nique_372
2025-10-13 12:26:22 -05:00
m_lines_sep[i] = m_lines_sep[i + 1];
Nique_372
2025-10-13 07:15:19 -05:00
//---
m_lines_sep_size--;
ArrayResize(m_lines_sep, m_lines_sep_size);
//---
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::RedrawPixels(void)
{
//--- Texto
for(int i = 0; i < m_texts_size; i++)
{
::TextSetFont(m_texts[i].font, m_texts[i].fontsize);
m_canvas.TextOuTF(m_texts[i].x, m_texts[i].y, m_texts[i].text, m_texts[i].clr, m_text_alingement);
}
//--- Legenda
for(int i = 0; i < m_lengedas_size; i++)
{
::TextSetFont(m_lengendas[i].text.font, m_lengendas[i].text.fontsize);
m_canvas.TextOuTF(m_lengendas[i].text.x, m_lengendas[i].text.y, m_lengendas[i].text.text, m_lengendas[i].text.clr, m_text_alingement);
//---
m_canvas.Rectangle(m_lengendas[i].x1_borde,
m_lengendas[i].y1_borde,
m_lengendas[i].x2_borde,
m_lengendas[i].y2_borde,
m_lengendas[i].clr_borde);
//---
m_canvas.FillRectangle(m_lengendas[i].x1,
m_lengendas[i].y1,
m_lengendas[i].x2,
m_lengendas[i].y2,
m_lengendas[i].clr_fondo);
}
//--- Linea separadora
for(int i = 0; i < m_lines_sep_size; i++)
{
m_canvas.LineAA(m_lines_sep[i].x1,
m_lines_sep[i].y1,
m_lines_sep[i].x2,
Nique_372
2025-10-13 12:26:22 -05:00
m_lines_sep[i].y2,
m_lines_sep[i].clr,
m_lines_sep[i].style);
Nique_372
2025-10-13 07:15:19 -05:00
}
}
//+------------------------------------------------------------------+
//| Mueve solo el origen (x1, y1) manteniendo el tama<EFBFBD>o |
//+------------------------------------------------------------------+
void CHistogramParteInfo::ChangeCordinatesOne(int x1, int y1)
{
//--- Calcular cu<EFBFBD>nto se movi<EFBFBD>
int delta_x = x1 - m_espacio_x1;
int delta_y = y1 - m_espacio_y1;
//--- Actualizar coordenadas manteniendo el tama<EFBFBD>o
m_espacio_x1 = x1;
m_espacio_y1 = y1;
m_espacio_x2 = x1 + m_espacio_width;
m_espacio_y2 = y1 + m_espacio_height;
//--- Texto
Nique_372
2025-10-13 07:15:19 -05:00
for(int i = 0; i < m_texts_size; i++)
{