GrapichsByLeo/PartInf/ParteInf.mqh

950 lines
66 KiB
MQL5

//+------------------------------------------------------------------+
//| 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
#ifndef HISTOGRAM_PARTE_INFORMATIVA_MAIN_BY_LEO_MQH
#define HISTOGRAM_PARTE_INFORMATIVA_MAIN_BY_LEO_MQH
#include "..\\General\\Canvas.mqh"
#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;
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ñ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ñ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ñ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);
}
//---
for(int i = index; i < m_lines_sep_size - 1; i++)
m_lines_sep[i] = m_lines_sep[i + 1];
//---
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,
m_lines_sep[i].y2,
m_lines_sep[i].clr,
m_lines_sep[i].style);
}
}
//+------------------------------------------------------------------+
//| Mueve solo el origen (x1, y1) manteniendo el tamaño |
//+------------------------------------------------------------------+
void CHistogramParteInfo::ChangeCordinatesOne(int x1, int y1)
{
//--- Calcular cuánto se movió
int delta_x = x1 - m_espacio_x1;
int delta_y = y1 - m_espacio_y1;
//--- Actualizar coordenadas manteniendo el tamaño
m_espacio_x1 = x1;
m_espacio_y1 = y1;
m_espacio_x2 = x1 + m_espacio_width;
m_espacio_y2 = y1 + m_espacio_height;
//--- Texto
for(int i = 0; i < m_texts_size; i++)
{
m_texts[i].x += delta_x;
m_texts[i].y += delta_y;
}
//--- Legenda
for(int i = 0; i < m_lengedas_size; i++)
{
m_lengendas[i].text.x += delta_x;
m_lengendas[i].text.y += delta_y;
m_lengendas[i].x1 += delta_x;
m_lengendas[i].x2 += delta_x;
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++)
{
m_lines_sep[i].x1 += delta_x;
m_lines_sep[i].x2 += delta_x;
m_lines_sep[i].y1 += delta_y;
m_lines_sep[i].y2 += delta_y;
}
//---
RedrawPixels();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::ChangeSizes(int new_width, int new_height)
{
// Actualizar dimensiones
m_espacio_width = new_width;
m_espacio_height = new_height;
m_espacio_x2 = m_espacio_x1 + new_width;
m_espacio_y2 = m_espacio_y1 + new_height;
// Solo las líneas separadoras necesitan recalcularse
// (porque dependen del ancho x2)
for(int i = 0; i < m_lines_sep_size; i++)
{
m_lines_sep[i].x2 = m_espacio_x2 - m_lines_sep[i].gap_end;
m_canvas.LineAA(m_lines_sep[i].x1, m_lines_sep[i].y1, m_lines_sep[i].x2, m_lines_sep[i].y2, m_lines_sep[i].clr, m_lines_sep[i].style);
}
// Textos y leyendas NO cambian (mantienen su posición absoluta)
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::ChangeCordinates(int x1, int y1, int x2, int y2)
{
const int cambio_x = x1 - m_espacio_x1;
const int cambio_y = y1 - m_espacio_y1;
//---
m_espacio_x1 = x1;
m_espacio_x2 = x2;
m_espacio_y1 = y1;
m_espacio_y2 = y2;
m_espacio_width = fabs(x2 - x1);
m_espacio_height = fabs(y2 - y1);
//--- Texto
for(int i = 0; i < m_texts_size; i++)
{
// Movemos las cordenadas del texto
m_texts[i].x += cambio_x;
m_texts[i].y += cambio_y;
}
//--- Legendas
for(int i = 0; i < m_lengedas_size; i++)
{
// Mover texto
m_lengendas[i].text.x += cambio_x;
m_lengendas[i].text.y += cambio_y;
// Mover rectángulo
m_lengendas[i].x1 += cambio_x;
m_lengendas[i].x2 += cambio_x;
m_lengendas[i].y1 += cambio_y;
m_lengendas[i].y2 += cambio_y;
// Recalcular bordes
m_lengendas[i].CalcCordinatesBorde();
}
//--- Linea separadora
for(int i = 0; i < m_lines_sep_size; i++)
{
// Mover en Y con delta
m_lines_sep[i].y1 += cambio_y;
m_lines_sep[i].y2 += cambio_y;
// Recalcular x1 y x2 basado en el nuevo ancho y los gaps
m_lines_sep[i].x1 = m_espacio_x1 + m_lines_sep[i].gap_init;
m_lines_sep[i].x2 = m_espacio_x2 - m_lines_sep[i].gap_end;
}
//---
RedrawPixels();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::LineaSeparadoraStyle(const int index, uint new_style, bool redraw = false)
{
m_lines_sep[index].style = new_style;
m_canvas.LineStyleSet(new_style);
m_canvas.LineAA(m_lines_sep[index].x1,
m_lines_sep[index].y1,
m_lines_sep[index].x2,
m_lines_sep[index].y2,
m_lines_sep[index].clr,
m_lines_sep[index].style);
//--- Actualizar canvas si se solicita
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::LineaSeparadoraColor(const int index, uint new_clr, bool redraw = false)
{
m_lines_sep[index].clr = new_clr;
m_canvas.LineAA(m_lines_sep[index].x1,
m_lines_sep[index].y1,
m_lines_sep[index].x2,
m_lines_sep[index].y2,
m_lines_sep[index].clr,
m_lines_sep[index].style);
//--- Actualizar canvas si se solicita
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::TextoColor(const int index, uint new_clr, bool redraw = false)
{
//--- Forzamos la fuente
::TextSetFont(m_texts[index].font, m_texts[index].fontsize);
//--- Nuevo valor
m_texts[index].clr = new_clr;
m_canvas.TextOuTF(m_texts[index].x, m_texts[index].y, m_texts[index].text, m_texts[index].clr, m_text_alingement);
//--- Actualizar canvas si se solicita
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::TextoValue(const int index, const string &new_value, uint clr_clean, bool redraw = false)
{
//--- Foramzamos la fuente
::TextSetFont(m_texts[index].font, m_texts[index].fontsize);
//--- Limpiamos
m_canvas.TextOuTF(m_texts[index].x, m_texts[index].y, m_texts[index].text, clr_clean, m_text_alingement);
//--- Nuevo valor
m_texts[index].text = new_value;
m_canvas.TextOuTF(m_texts[index].x, m_texts[index].y, m_texts[index].text, m_texts[index].clr, m_text_alingement);
//--- Actualizar canvas si se solicita
if(redraw)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::LegendaSetNewsColors(const int index, uint new_clr_fondo, uint new_clr_borde, bool update = false)
{
//--- Actualizar colores en el struct
m_lengendas[index].clr_borde = new_clr_borde;
m_lengendas[index].clr_fondo = new_clr_fondo;
//--- Redibujar usando las coordenadas de borde ya calculadas
m_canvas.Rectangle(m_lengendas[index].x1_borde,
m_lengendas[index].y1_borde,
m_lengendas[index].x2_borde,
m_lengendas[index].y2_borde,
new_clr_borde);
//--- Luego el fondo interior
m_canvas.FillRectangle(m_lengendas[index].x1,
m_lengendas[index].y1,
m_lengendas[index].x2,
m_lengendas[index].y2,
new_clr_fondo);
//--- Actualizar canvas si se solicita
if(update)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::LegendaTextoValue(const int index, const string &new_value, uint clr_clean, string font = NULL, int font_size = 0, bool update = false)
{
//--- Limpiamos el anterior
::TextSetFont(m_lengendas[index].text.font, m_lengendas[index].text.fontsize); // Cambiamos la fuente a la del texto
m_canvas.TextOuTF(m_lengendas[index].text.x, m_lengendas[index].text.y, m_lengendas[index].text.text, clr_clean, m_text_alingement); // Limpaimos
//--- Nueva valor
m_lengendas[index].text.text = new_value;
m_canvas.TextOuTF(m_lengendas[index].text.x, m_lengendas[index].text.y, m_lengendas[index].text.text, m_lengendas[index].text.clr, m_text_alingement);
//--- Actualizar canvas si se solicita
if(update)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::LegendaTextoColor(const int index, uint new_text_clr, bool update = false)
{
//--- Forzamos la fuente
::TextSetFont(m_lengendas[index].text.font, m_lengendas[index].text.fontsize); // Cambiamos la fuente a la del texto
//--- Cambiamos
m_lengendas[index].text.clr = new_text_clr;
m_canvas.TextOuTF(m_lengendas[index].text.x, m_lengendas[index].text.y, m_lengendas[index].text.text, m_lengendas[index].text.clr, m_text_alingement);
//--- Actualizar canvas si se solicita
if(update)
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Limpia todo por loq eu se debera volver a llamar a init
void CHistogramParteInfo::Clean(uint clr_clean)
{
CleanEspacio(clr_clean);
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;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::CleanEspacio(uint clr_clean)
{
//--- Si se ha inicaod entonces limpiamos canvas
if(m_init)
{
m_canvas.FillRectangle(m_espacio_x1, m_espacio_y1, m_espacio_x2, m_espacio_y2, clr_clean);
} // SDi no se inciio solo limpamos data
//--- 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;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CHistogramParteInfo::Init(CCanvasCustom* c, int x1, int y1, int x2, int y2, int gap_x_inicial, int gap_y_inicial)
{
if(m_init)
return;
//--- Seteo general
m_canvas = c;
m_espacio_x1 = x1;
m_espacio_x2 = x2;
m_espacio_y1 = y1;
m_espacio_y2 = y2;
m_espacio_width = fabs(x2 - x1);
m_espacio_height = fabs(y2 - y1);
m_init = true;
//--- Cordenadas iniciales
m_curr_x = m_espacio_x1 + gap_x_inicial;
m_curr_y = m_espacio_y1 + gap_y_inicial;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CHistogramParteInfo::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)
{
//--- Damos la opcion de poder hacer el texto custom
if(font != NULL && font_size > 0)
{
::TextSetFont(font, font_size);
}
else
{
// Por precuaciuon anulamos globalemnte, esto para eliminar la inclinacion y flags, que en este caso no existen
::TextSetFont(m_canvas.FontNameGet(), m_canvas.FontSizeGet());
}
//--- Texto
HistogramPartInfText new_txt;
new_txt.text = new_text;
new_txt.x = m_curr_x;
new_txt.y = m_curr_y;
new_txt.clr = clr_text;
// Seteamos la fuente y fontsize utilizados para el texto (si se uso externamente el fontset puede haber bugs, asi que lo ideal es usar)
// TextFontSet de la clase para prevenir posibles bugs
new_txt.font = m_canvas.FontNameGet();
new_txt.fontsize = m_canvas.FontSizeGet();
m_canvas.TextOuTF(m_curr_x, m_curr_y, new_text, clr_text, m_text_alingement);
//--- Rectrangulo de legenda
uint w, h;
::TextGetSize(new_text, w, h);
HistogramPartInfLegend new_legend;
new_legend.x1 = m_curr_x + (int)w + xgap; // X1 del rectanuglo
new_legend.x2 = new_legend.x1 + rect_width;
new_legend.y1 = m_curr_y;
new_legend.y2 = m_curr_y + rect_height;
new_legend.clr_fondo = clr_rect;
new_legend.clr_borde = clr_rect_borde;
new_legend.CalcCordinatesBorde(); // Caluclo de las cordenadas del borde
// Dibujamos
m_canvas.Rectangle(new_legend.x1_borde, new_legend.y1_borde, new_legend.x2_borde, new_legend.y2_borde, clr_rect_borde); // Borde
m_canvas.FillRectangle(new_legend.x1, new_legend.y1, new_legend.x2, new_legend.y2, clr_rect); // Interno
// Asiganmso texto
new_legend.text = new_txt;
//---
const int prev_size = m_lengedas_size;
ArrayResize(m_lengendas, m_lengedas_size + 1);
m_lengendas[m_lengedas_size] = new_legend;
m_lengedas_size++;
//--- Movemos cordenadas con los gaps especificados
m_curr_x += x_a_avanzar;
m_curr_y += y_a_avanzar;
//---
if(update)
m_canvas.Update();
//---
return prev_size;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CHistogramParteInfo::AddLineSeparadora(int gap_init, int gap_end, uint clr, int y_avanzar, ENUM_LINE_STYLE style, bool update = false)
{
//---
const int x1 = m_espacio_x1 + gap_init;
const int x2 = m_espacio_x2 - gap_end;
//---
m_canvas.LineAA(x1, m_curr_y, x2, m_curr_y, clr, style);
//---
HistogramPartInfLineSep new_line_sep;
new_line_sep.x1 = x1;
new_line_sep.x2 = x2;
new_line_sep.y1 = m_curr_y;
new_line_sep.y2 = m_curr_y;
new_line_sep.clr = clr;
new_line_sep.style = style;
new_line_sep.gap_end = gap_end;
new_line_sep.gap_init = gap_init;
//---
const int prev_size = m_lines_sep_size;
ArrayResize(m_lines_sep, m_lines_sep_size + 1);
m_lines_sep[m_lines_sep_size] = new_line_sep;
m_lines_sep_size++;
//---
m_curr_y += y_avanzar;
//---
if(update)
m_canvas.Update();
//---
return m_lines_sep_size;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CHistogramParteInfo::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)
{
//--- Damos la opcion de poder hacer el texto custom
if(font != NULL && font_size > 0)
{
::TextSetFont(font, font_size);
}
else
{
// Por precuaciuon anulamos globalemnte, esto para eliminar la inclinacion y flags, que en este caso no existen
::TextSetFont(m_canvas.FontNameGet(), m_canvas.FontSizeGet());
}
//--- Text out
m_canvas.TextOuTF(m_curr_x, m_curr_y, new_text, clr, m_text_alingement);
//---
HistogramPartInfText new_txt;
new_txt.text = new_text;
new_txt.x = m_curr_x;
new_txt.y = m_curr_y;
new_txt.clr = clr;
// Seteamos la fuente y fontsize utilizados para el texto (si se uso externamente el fontset puede haber bugs, asi que lo ideal es usar)
// TextFontSet de la clase para prevenir posibles bugs
new_txt.font = m_canvas.FontNameGet();
new_txt.fontsize = m_canvas.FontSizeGet();
//---
const int prev_size = m_texts_size;
ArrayResize(m_texts, m_texts_size + 1);
m_texts[m_texts_size] = new_txt;
m_texts_size++;
//--- Movemos cordenadas con los gaps especificados
m_curr_x += x_a_avanzar;
m_curr_y += y_a_avanzar;
//---
if(update)
m_canvas.Update();
//---
return prev_size;
}
//+------------------------------------------------------------------+
#endif
//+------------------------------------------------------------------+