Article-17457-MQL5-Optimiza.../Table.mqh
2026-03-24 15:23:43 +07:00

650 lines
67 KiB
MQL5

//+------------------------------------------------------------------+
//| Table.mqh |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#include <Arrays\ArrayObj.mqh>
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Класс ячейки таблицы |
//+------------------------------------------------------------------+
class CTableCell : public CObject
{
private:
int m_row; // Строка
int m_col; // Столбец
int m_x; // Координата X
int m_y; // Координата Y
int m_w; // Ширина
int m_h; // Высота
string m_text; // Текст в ячейке
color m_fore_color; // Цвет текста в ячейке
public:
//--- Методы установки значений
void SetRow(const uint row) { this.m_row=(int)row; }
void SetColumn(const uint col) { this.m_col=(int)col; }
void SetX(const uint x) { this.m_x=(int)x; }
void SetY(const uint y) { this.m_y=(int)y; }
void SetXY(const uint x,const uint y)
{
this.m_x=(int)x;
this.m_y=(int)y;
}
void SetWidth(const uint w) { this.m_w=(int)w; }
void SetHeight(const uint h) { this.m_h=(int)h; }
void SetSize(const uint w,const uint h)
{
this.m_w=(int)w;
this.m_h=(int)h;
}
void SetText(const string text) { this.m_text=text; }
//--- Методы получения значений
int Row(void) const { return this.m_row; }
int Column(void) const { return this.m_col; }
int X(void) const { return this.m_x; }
int Y(void) const { return this.m_y; }
int Width(void) const { return this.m_w; }
int Height(void) const { return this.m_h; }
string Text(void) const { return this.m_text; }
//--- Выводит текст, записанный в свойствах ячейки на канвас, указатель на который передан в метод
void TextOut(CCanvas *canvas, const int x_shift, const int y_shift, const color bg_color=clrNONE, const uint flags=0, const uint alignment=0)
{
if(canvas==NULL)
return;
//--- Запомним текущие флаги шрифта
uint flags_prev=canvas.FontFlagsGet();
//--- Установим цвет фона
uint clr=(bg_color==clrNONE ? 0x00FFFFFF : ::ColorToARGB(bg_color));
//--- Зальём установленным цветом фона ячейку (сотрём прошлую надпись)
canvas.FillRectangle(this.m_x+1, this.m_y+1, this.m_x+this.m_w-1, this.m_y+this.m_h-1, clr);
//--- Установим флаги шрифта
canvas.FontFlagsSet(flags);
//--- Выведем текст в ячейку
canvas.TextOut(this.m_x+x_shift, this.m_y+y_shift, this.m_text, ::ColorToARGB(this.m_fore_color), alignment);
//--- Возвращаем ранее запомненные флаги шрифта и обновляем канвас
canvas.FontFlagsSet(flags_prev);
canvas.Update(false);
}
//--- Виртуальный метод сравнения двух объектов
virtual int Compare(const CObject *node,const int mode=0) const
{
const CTableCell *compared=node;
return(this.Column()>compared.Column() ? 1 : this.Column()<compared.Column() ? -1 : 0);
}
//--- Конструктор/деструктор
CTableCell(const int row,const int column) : m_row(row),m_col(column){}
~CTableCell(void){}
};
//+------------------------------------------------------------------+
//| Класс строк таблиц |
//+------------------------------------------------------------------+
class CTableRow : public CObject
{
private:
CArrayObj m_list_cell; // Список ячеек
int m_row; // Номер строки
int m_y; // Координата Y
public:
//--- Возвращает список ячеек таблицы в строке
CArrayObj *GetListCell(void) { return &this.m_list_cell; }
//--- Возвращает (1) количество ячеек таблицы в строке (2) индекс строки в таблице
int CellsTotal(void) const { return this.m_list_cell.Total(); }
int Row(void) const { return this.m_row; }
//--- (1) Устанавливает, (2) возвращает координату Y строки
void SetY(const int y) { this.m_y=y; }
int Y(void) const { return this.m_y; }
//--- Добавляет новую ячейку таблицы в строку
bool AddCell(CTableCell *cell)
{
this.m_list_cell.Sort();
if(this.m_list_cell.Search(cell)!=WRONG_VALUE)
{
::PrintFormat("%s: Table cell with index %lu is already in the list",__FUNCTION__,cell.Column());
return false;
}
if(!this.m_list_cell.InsertSort(cell))
{
::PrintFormat("%s: Failed to add table cell with index %lu to list",__FUNCTION__,cell.Column());
return false;
}
return true;
}
//--- Возвращает указатель на указанную ячейку в строке
CTableCell *GetCell(const int column)
{
const CTableCell *obj=new CTableCell(this.m_row,column);
int index=this.m_list_cell.Search(obj);
delete obj;
return this.m_list_cell.At(index);
}
//--- Виртуальный метод сравнения двух объектов
virtual int Compare(const CObject *node,const int mode=0) const
{
const CTableRow *compared=node;
return(this.Row()>compared.Row() ? 1 : this.Row()<compared.Row() ? -1 : 0);
}
//--- Конструктор/деструктор
CTableRow(const int row) : m_row(row) { this.m_list_cell.Clear(); }
~CTableRow(void) { this.m_list_cell.Clear(); }
};
//+------------------------------------------------------------------+
//| Класс данных таблиц |
//+------------------------------------------------------------------+
class CTableData : public CObject
{
private:
CArrayObj m_list_rows; // Список строк
int m_id; // Идентификатор таблицы
int m_x1; // Координата X1
int m_y1; // Координата Y1
int m_x2; // Координата X2
int m_y2; // Координата Y2
int m_w; // Ширина
int m_h; // Высота
string m_name; // Наименование таблицы
public:
//--- Устанавливает (1) идентификатор, (2) наименование таблицы
void SetID(const int id) { this.m_id=id; }
void SetName(const string name) { this.m_name=name; }
//--- Возвращает (1) идентификатор, (2) наименование таблицы
int ID(void) const { return this.m_id; }
string Name(void) const { return this.m_name; }
//--- Устанавливает координату (1) X1, (2) X2
void SetX1(const int x1) { this.m_x1=x1; }
void SetX2(const int x2) { this.m_x2=x2; }
//--- Устанавливает координату (1) Y1, (2) Y2
void SetY1(const int y1) { this.m_y1=y1; }
void SetY2(const int y2) { this.m_y2=y2; }
//--- Устанавливает координаты таблицы
void SetCoords(const int x1,const int y1,const int x2,const int y2)
{
this.SetX1(x1);
this.SetY1(y1);
this.SetX2(x2);
this.SetY2(y2);
}
//--- Возвращает координату (1) X1, (2) X2
int X1(void) const { return this.m_x1; }
int X2(void) const { return this.m_x2; }
//--- Возвращает координату (1) Y1, (2) Y2
int Y1(void) const { return this.m_y1; }
int Y2(void) const { return this.m_y2; }
//--- Возвращает (1) ширину, (2) высоту
int Width(void) const { return this.m_x2-this.m_x1+1; }
int Height(void) const { return this.m_y2-this.m_y1+1; }
//--- Возвращает список строк таблицы
CArrayObj *GetListRows(void) { return &this.m_list_rows; }
//--- Добавляет новую строку в таблицу
bool AddRow(CTableRow *row)
{
//--- Устанавливаем флаг сортированного списка
this.m_list_rows.Sort();
//--- Если такой объект уже есть в списке (поиск вернул индекс объекта, а не -1),
//--- сообщаем об этом в журнал и возвращаем false
if(this.m_list_rows.Search(row)!=WRONG_VALUE)
{
::PrintFormat("%s: Table row with index %lu is already in the list",__FUNCTION__,row.Row());
return false;
}
//--- Если не удалось добавить указатель в сортированный список - сообщаем об этом в журнал и возвращаем false
if(!this.m_list_rows.InsertSort(row))
{
::PrintFormat("%s: Failed to add table cell with index %lu to list",__FUNCTION__,row.Row());
return false;
}
//--- Успешно - возвращаем true
return true;
}
//--- Возвращает указатель на (1) указанную строку, (2) указанную ячейку в указанной строке таблицы
CTableRow *GetRow(const int index) { return this.m_list_rows.At(index);}
CTableCell *GetCell(const int row,const int column)
{
//--- Получаем указатель на объект-строку в списке строк
CTableRow *row_obj=this.GetRow(row);
//--- Если объект получить не удалось - возвращаем NULL
if(row_obj==NULL)
return NULL;
//--- Получаем указатель на объект-ячейку в строке по номеру столбца и
CTableCell *cell=row_obj.GetCell(column);
//--- возвращаем результат (указатель на объект, либо NULL)
return cell;
}
//--- Записывает в переданные в метод переменные координаты X и Y указанной ячейки таблицы
void CellXY(const uint row,const uint column, int &x, int &y)
{
x=WRONG_VALUE;
y=WRONG_VALUE;
CTableCell *cell=this.GetCell(row,column);
if(cell==NULL)
return;
x=cell.X();
y=cell.Y();
}
//--- Возвращает координату X указанной ячейки таблицы
int CellX(const uint row,const uint column)
{
CTableCell *cell=this.GetCell(row,column);
return(cell!=NULL ? cell.X() : WRONG_VALUE);
}
//--- Возвращает координату Y указанной ячейки таблицы
int CellY(const uint row,const uint column)
{
CTableCell *cell=this.GetCell(row,column);
return(cell!=NULL ? cell.Y() : WRONG_VALUE);
}
//--- Возвращает количество (1) строк, (2) столбцов в указанной строке
int RowsTotal(void) { return this.m_list_rows.Total(); }
int ColumnsInRow(const int row_index)
{
//--- Если в списке нет ни одной строки - возвращаем 0
if(this.RowsTotal()==0)
return 0;
//--- Получаем указатель на указанную строку и возвращаем количество ячеек в ней
CTableRow *row=this.GetRow(row_index);
return(row!=NULL ? row.CellsTotal() : 0);
}
//--- Возвращает общее количество ячеек таблицы
int CellsTotal(void)
{
//--- Если в списке нет ни одной строки - возвращаем 0
if(this.RowsTotal()==0)
return 0;
//---
int num=0;
int total=this.RowsTotal();
for(int i=0;i<total;i++)
num+=this.ColumnsInRow(i);
return num;
}
//--- Очищает списки строк и ячеек таблицы
void Clear(void)
{
//--- В цикле по количеству строк в списке строк таблицы
for(int i=0;i<this.m_list_rows.Total();i++)
{
//--- получаем указатель на очередную строку
CTableRow *row=this.m_list_rows.At(i);
if(row==NULL)
continue;
//--- из полученного объекта-строки получаем список ячеек,
CArrayObj *list_cell=row.GetListCell();
//--- очищаем список ячеек
if(list_cell!=NULL)
list_cell.Clear();
}
//--- Очищаем список строк
this.m_list_rows.Clear();
}
//--- Распечатывает в журнал данные ячеек таблицы
void Print(const uint tabulation=0)
{
//--- Печатаем в журнал заголовок
::PrintFormat("Table %lu: Rows: %lu, Columns: %lu",this.m_id,this.RowsTotal(),this.CellsTotal()/(this.RowsTotal()!=0 ? this.RowsTotal() : 1));
//--- В цикле по строкам таблицы
for(int r=0;r<this.RowsTotal();r++)
//--- в цикле по ячейкам очередной строки
for(int c=0;c<this.ColumnsInRow(r);c++)
{
//--- получаем указатель на очередную ячейку и выводим в журнал её данные
CTableCell *cell=this.GetCell(r,c);
if(cell!=NULL)
::PrintFormat("%*s%-5s %-4lu %-8s %-6lu %-8s %-6lu %-8s %-4lu",tabulation,"","Row",r,"Column",c,"Cell X:",cell.X(),"Cell Y:",cell.Y());
}
}
//--- Виртуальный метод сравнения двух объектов
virtual int Compare(const CObject *node,const int mode=0) const
{
const CTableData *compared=node;
if(mode==0)
return(this.ID()>compared.ID() ? 1 : this.ID()<compared.ID() ? -1 : 0);
else
return(this.Name()==compared.Name() ? 0 : this.Name()>compared.Name() ? 1 : -1);
}
//--- Конструктор/деструктор
CTableData(void) : m_id(-1) { this.m_list_rows.Clear(); this.m_name=""; }
CTableData(const uint id) : m_id((int)id) { this.m_list_rows.Clear(); this.m_name=""; }
~CTableData(void) { this.m_list_rows.Clear(); }
};
//+------------------------------------------------------------------+
//| Класс управления таблицами |
//+------------------------------------------------------------------+
class CTableDataControl : public CTableData
{
protected:
uchar m_alpha;
color m_fore_color;
//--- Преобразует RGB в color
color RGBToColor(const double r,const double g,const double b) const;
//--- Записывает в переменные значения компонентов RGB
void ColorToRGB(const color clr,double &r,double &g,double &b);
//--- Возвращает составляющую цвета (1) Red, (2) Green, (3) Blue
double GetR(const color clr) { return clr&0xff ; }
double GetG(const color clr) { return(clr>>8)&0xff; }
double GetB(const color clr) { return(clr>>16)&0xff; }
//--- Возвращает новый цвет
color NewColor(color base_color, int shift_red, int shift_green, int shift_blue);
public:
//--- Возвращает указатель на себя
CTableDataControl*Get(void) { return &this; }
//--- (1) Устанавливает, (2) возвращает прозрачность
void SetAlpha(const uchar alpha) { this.m_alpha=alpha; }
uchar Alpha(void) const { return this.m_alpha; }
//--- Рисует (1) фоновую сетку, (2) с автоматическим размером ячеек
void DrawGrid(CCanvas *canvas,const int x,const int y,const uint header_h,const uint rows,const uint columns,const uint row_size,const uint col_size,
const color line_color=clrNONE,bool alternating_color=true);
void DrawGridAutoFill(CCanvas *canvas,const uint border,const uint header_h,const uint rows,const uint columns,const color line_color=clrNONE,bool alternating_color=true);
//--- Выводит (1) текстовое сообщение, (2) закрашенный прямоугольник в указанные координаты
void DrawText(CCanvas *canvas,const string text,const int x,const int y,const color clr=clrNONE,const uint align=0,const int width=WRONG_VALUE,const int height=WRONG_VALUE);
void DrawRectangleFill(CCanvas *canvas,const int x,const int y,const int width,const int height,const color clr,const uchar alpha);
//--- Конструкторы/Деструктор
CTableDataControl (const uint id) : CTableData(id), m_fore_color(clrDimGray), m_alpha(255) {}
CTableDataControl (void) : m_alpha(255) {}
~CTableDataControl (void) {}
};
//+------------------------------------------------------------------+
//| Рисует фоновую сетку |
//+------------------------------------------------------------------+
void CTableDataControl::DrawGrid(CCanvas *canvas,const int x,const int y,const uint header_h,const uint rows,const uint columns,const uint row_size,const uint col_size,
const color line_color=clrNONE,bool alternating_color=true)
{
//--- Очищаем все списки объекта табличных данных (удаляем ячейки из строк и все строки)
this.Clear();
//--- Высота строки не может быть меньше 2
int row_h=int(row_size<2 ? 2 : row_size);
//--- Ширина столбца не может быть меньше 2
int col_w=int(col_size<2 ? 2 : col_size);
//--- Левая координата (X1) таблицы
int x1=x;
//--- Рассчитываем координату X2 (справа) в зависимости от количества столбцов и их ширины
int x2=x1+col_w*int(columns>0 ? columns : 1);
//--- Координата Y1 находится под областью заголовка панели
int y1=(int)header_h+y;
//--- Рассчитываем координату Y2 (снизу) в зависимости от количества строк и их высоты
int y2=y1+row_h*int(rows>0 ? rows : 1);
//--- Устанавливаем координаты таблицы
this.SetCoords(x1,y1-header_h,x2,y2-header_h);
//--- Получаем цвет линий сетки таблицы, либо по умолчанию, либо переданный в метод
color clr=(line_color==clrNONE ? C'200,200,200' : line_color);
//--- Рисуем рамку таблицы
canvas.Rectangle(x1,y1,x2,y2,::ColorToARGB(clr,this.m_alpha));
//--- В цикле по строкам таблицы
for(int i=0;i<(int)rows;i++)
{
//--- рассчитываем координату Y очередной горизонтальной линии сетки (координата Y очередной строки таблицы)
int row_y=y1+row_h*i;
//--- если передан флаг "чередующихся" цветов строк и строка чётная
if(alternating_color && i%2==0)
{
//--- осветляем цвет фона таблицы и рисуем фоновый прямоугольник
color new_color=this.NewColor(clr,45,45,45);
canvas.FillRectangle(x1+1,row_y+1,x2-1,row_y+row_h-1,::ColorToARGB(new_color,this.m_alpha));
}
//--- Рисуем горизонтальную линию сетки таблицы
canvas.Line(x1,row_y,x2,row_y,::ColorToARGB(clr,this.m_alpha));
//--- Создаём новый объект строки таблицы
CTableRow *row_obj=new CTableRow(i);
if(row_obj==NULL)
{
::PrintFormat("%s: Failed to create table row object at index %lu",(string)__FUNCTION__,i);
continue;
}
//--- Добавляем его в список строк объекта табличных данных
//--- (если добавить объект не удалось - удаляем созданный объект)
if(!this.AddRow(row_obj))
delete row_obj;
//--- Устанавливаем в созданном объекте-строке его координату Y с учётом смещения от заголовка панели
row_obj.SetY(row_y-header_h);
}
//--- В цикле по столбцам таблицы
for(int i=0;i<(int)columns;i++)
{
//--- рассчитываем координату X очередной вертикальной линии сетки (координата X очередного столбца таблицы)
int col_x=x1+col_w*i;
//--- Если линия сетки вышла за пределы панели - прерываем цикл
if(x1==1 && col_x>=x1+canvas.Width()-2)
break;
//--- Рисуем вертикальную линию сетки таблицы
canvas.Line(col_x,y1,col_x,y2,::ColorToARGB(clr,this.m_alpha));
//--- Получаем из объекта табличных данных количество созданных строк
int total=this.RowsTotal();
//--- В цикле по строкам таблицы
for(int j=0;j<total;j++)
{
//--- получаем очередную строку
CTableRow *row=this.GetRow(j);
if(row==NULL)
continue;
//--- Создаём новую ячейку таблицы
CTableCell *cell=new CTableCell(row.Row(),i);
if(cell==NULL)
{
::PrintFormat("%s: Failed to create table cell object at index %lu",(string)__FUNCTION__,i);
continue;
}
//--- Добавляем созданную ячейку в строку
//--- (если добавить объект не удалось - удаляем созданный объект)
if(!row.AddCell(cell))
{
delete cell;
continue;
}
//--- Устанавливаем в созданном объекте-ячейке его координату X и координату Y из объекта-строки
cell.SetXY(col_x,row.Y());
cell.SetSize(col_w, row_h);
}
}
//--- Обновляем канвас без перерисовки графика
canvas.Update(false);
}
//+------------------------------------------------------------------+
//| Рисует фоновую сетку с автоматическим размером ячеек |
//+------------------------------------------------------------------+
void CTableDataControl::DrawGridAutoFill(CCanvas *canvas,const uint border,const uint header_h,const uint rows,const uint columns,const color line_color=clrNONE,bool alternating_color=true)
{
//--- Координата X1 (левая) таблицы
int x1=(int)border;
//--- Координата X2 (правая) таблицы
int x2=canvas.Width()-(int)border-1;
//--- Координата Y1 (верхняя) таблицы
int y1=int(header_h+border-1);
//--- Координата Y2 (нижняя) таблицы
int y2=canvas.Height()-(int)border-1;
//--- Устанавливаем координаты таблицы
this.SetCoords(x1,y1,x2,y2);
//--- Получаем цвет линий сетки таблицы, либо по умолчанию, либо переданный в метод
color clr=(line_color==clrNONE ? C'200,200,200' : line_color);
//--- Если отступ от края панели больше нуля - рисуем рамку таблицы
//--- иначе - рамкой таблицы выступает рамка панели
if(border>0)
canvas.Rectangle(x1,y1,x2,y2,::ColorToARGB(clr,this.m_alpha));
//--- Высота всей сетки таблицы
int greed_h=y2-y1;
//--- Рассчитываем высоту строки в зависимости от высоты таблицы и количества строк
int row_h=(int)::round((double)greed_h/(double)rows);
//--- В цикле по количеству строк
for(int i=0;i<(int)rows;i++)
{
//--- рассчитываем координату Y очередной горизонтальной линии сетки (координата Y очередной строки таблицы)
int row_y=y1+row_h*i;
//--- если передан флаг "чередующихся" цветов строк и строка чётная
if(alternating_color && i%2==0)
{
//--- осветляем цвет фона таблицы и рисуем фоновый прямоугольник
color new_color=this.NewColor(clr,45,45,45);
canvas.FillRectangle(x1+1,row_y+1,x2-1,row_y+row_h-1,::ColorToARGB(new_color,this.m_alpha));
}
//--- Рисуем горизонтальную линию сетки таблицы
canvas.Line(x1,row_y,x2,row_y,::ColorToARGB(clr,this.m_alpha));
//--- Создаём новый объект строки таблицы
CTableRow *row_obj=new CTableRow(i);
if(row_obj==NULL)
{
::PrintFormat("%s: Failed to create table row object at index %lu",(string)__FUNCTION__,i);
continue;
}
//--- Добавляем его в список строк объекта табличных данных
//--- (если добавить объект не удалось - удаляем созданный объект)
if(!this.AddRow(row_obj))
delete row_obj;
//--- Устанавливаем в созданном объекте-строке его координату Y с учётом смещения от заголовка панели
row_obj.SetY(row_y-header_h);
}
//--- Ширина сетки таблицы
int greed_w=x2-x1;
//--- Рассчитываем ширину столбца в зависимости от ширины таблицы и количества столбцов
int col_w=(int)::round((double)greed_w/(double)columns);
//--- В цикле по столбцам таблицы
for(int i=0;i<(int)columns;i++)
{
//--- рассчитываем координату X очередной вертикальной линии сетки (координата X очередного столбца таблицы)
int col_x=x1+col_w*i;
//--- Если это не самая первая вертикальная линия - рисуем её
//--- (первой вертикальной линией выступает либо рамка таблицы, либо рамка панели)
if(i>0)
canvas.Line(col_x,y1,col_x,y2,::ColorToARGB(clr,this.m_alpha));
//--- Получаем из объекта табличных данных количество созданных строк
int total=this.RowsTotal();
//--- В цикле по строкам таблицы
for(int j=0;j<total;j++)
{
//--- получаем очередную строку
CTableRow *row=this.GetRow(j);
if(row==NULL)
continue;
//--- Создаём новую ячейку таблицы
CTableCell *cell=new CTableCell(row.Row(),i);
if(cell==NULL)
{
::PrintFormat("%s: Failed to create table cell object at index %lu",(string)__FUNCTION__,i);
continue;
}
//--- Добавляем созданную ячейку в строку
//--- (если добавить объект не удалось - удаляем созданный объект)
if(!row.AddCell(cell))
{
delete cell;
continue;
}
//--- Устанавливаем в созданном объекте-ячейке его координату X и координату Y из объекта-строки
cell.SetXY(col_x,row.Y());
cell.SetSize(col_w, row_h);
}
}
//--- Обновляем канвас без перерисовки графика
canvas.Update(false);
}
//+------------------------------------------------------------------+
//| Возвращает цвет с новой цветовой составляющей |
//+------------------------------------------------------------------+
color CTableDataControl::NewColor(color base_color, int shift_red, int shift_green, int shift_blue)
{
double clR=0, clG=0, clB=0;
this.ColorToRGB(base_color,clR,clG,clB);
double clRn=(clR+shift_red < 0 ? 0 : clR+shift_red > 255 ? 255 : clR+shift_red);
double clGn=(clG+shift_green< 0 ? 0 : clG+shift_green> 255 ? 255 : clG+shift_green);
double clBn=(clB+shift_blue < 0 ? 0 : clB+shift_blue > 255 ? 255 : clB+shift_blue);
return this.RGBToColor(clRn,clGn,clBn);
}
//+------------------------------------------------------------------+
//| Преобразует RGB в color |
//+------------------------------------------------------------------+
color CTableDataControl::RGBToColor(const double r,const double g,const double b) const
{
int int_r=(int)::round(r);
int int_g=(int)::round(g);
int int_b=(int)::round(b);
int clr=0;
clr=int_b;
clr<<=8;
clr|=int_g;
clr<<=8;
clr|=int_r;
//---
return (color)clr;
}
//+------------------------------------------------------------------+
//| Получение значений компонентов RGB |
//+------------------------------------------------------------------+
void CTableDataControl::ColorToRGB(const color clr,double &r,double &g,double &b)
{
r=GetR(clr);
g=GetG(clr);
b=GetB(clr);
}
//+------------------------------------------------------------------+
//| Выводит текстовое сообщение в указанные координаты |
//+------------------------------------------------------------------+
void CTableDataControl::DrawText(CCanvas *canvas,const string text,const int x,const int y,const color clr=clrNONE,const uint align=0,const int width=WRONG_VALUE,const int height=WRONG_VALUE)
{
//--- Объявим переменные для записи в них ширины и высоты текста
int w=width;
int h=height;
//--- Если ширина и высота текста, переданные в метод, имеют нулевые значения,
//--- то полностью очищается всё пространство канваса прозрачным цветом
if(width==0 && height==0)
canvas.Erase(0x00FFFFFF);
//--- Иначе
else
{
//--- Если переданные ширина и высота имеют значения по умолчанию (-1) - получаем из текста его ширину и высоту
if(width==WRONG_VALUE && height==WRONG_VALUE)
canvas.TextSize(text,w,h);
//--- иначе,
else
{
//--- если ширина, переданная в метод, имеет значение по умолчанию (-1) - получаем ширину из текста, либо
//--- если ширина, переданная в метод, имеет значение больше нуля - используем переданную в метод ширину, либо
//--- если ширина, переданная в метод, имеет нулевое значение, используем значение 1 для ширины
w=(width ==WRONG_VALUE ? canvas.TextWidth(text) : width>0 ? width : 1);
//--- если высота, переданная в метод, имеет значение по умолчанию (-1) - получаем высоту из текста, либо
//--- если высота, переданная в метод, имеет значение больше нуля - используем переданную в метод высоту, либо
//--- если высота, переданная в метод, имеет нулевое значение, используем значение 1 для высоты
h=(height==WRONG_VALUE ? canvas.TextHeight(text) : height>0 ? height : 1);
}
//--- Заполняем пространство по указанным координатам и полученной шириной и высотой прозрачным цветом (стираем прошлую запись)
canvas.FillRectangle(x,y,x+w,y+h,0x00FFFFFF);
}
//--- Выводим текст на очищенное от прошлого текста место и обновляем рабочую область без перерисовки экрана
canvas.TextOut(x,y,text,::ColorToARGB(clr==clrNONE ? this.m_fore_color : clr),align);
canvas.Update(false);
}
//+------------------------------------------------------------------+
//| Выводит закрашенный прямоугольник в указанные координаты |
//+------------------------------------------------------------------+
void CTableDataControl::DrawRectangleFill(CCanvas *canvas,const int x,const int y,const int width,const int height,const color clr,const uchar alpha)
{
canvas.FillRectangle(x,y,x+width,y+height,::ColorToARGB(clr,alpha));
canvas.Update();
}
//+------------------------------------------------------------------+