905 Zeilen
76 KiB
MQL5
905 Zeilen
76 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Slider.mqh |
|
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\Element.mqh"
|
|
#include "TextEdit.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для создания слайдера с полем ввода |
|
|
//+------------------------------------------------------------------+
|
|
class CSlider : public CElement
|
|
{
|
|
private:
|
|
//--- Объекты для создания элемента
|
|
CTextEdit m_left_edit;
|
|
CTextEdit m_right_edit;
|
|
//--- (1) Координата и (2) размер области индикатора
|
|
int m_slot_y;
|
|
int m_slot_y_size;
|
|
//--- Цвета индикатора в разных состояниях
|
|
color m_slot_line_dark_color;
|
|
color m_slot_line_light_color;
|
|
color m_slot_indicator_color;
|
|
color m_slot_indicator_color_locked;
|
|
//--- Текущая позиция ползунка слайдера: (1) значение, (2) координаты XY
|
|
double m_thumb_x_pos_left;
|
|
double m_thumb_x_pos_right;
|
|
double m_thumb_x_left;
|
|
double m_thumb_x_right;
|
|
int m_thumb_y;
|
|
//--- Размеры ползунка слайдера
|
|
int m_thumb_x_size;
|
|
int m_thumb_y_size;
|
|
//--- Цвета ползунка слайдера
|
|
color m_thumb_color;
|
|
color m_thumb_color_hover;
|
|
color m_thumb_color_locked;
|
|
color m_thumb_color_pressed;
|
|
//--- (1) Фокус на ползунке и (2) момент его пересечения границ
|
|
bool m_thumb_focus_left;
|
|
bool m_thumb_focus_right;
|
|
bool m_is_crossing_left_thumb_border;
|
|
bool m_is_crossing_right_thumb_border;
|
|
//--- Количество пикселей в рабочей области
|
|
int m_pixels_total;
|
|
//--- Количество шагов в диапазоне значений рабочей области
|
|
int m_value_steps_total;
|
|
//--- Размер шага относительно ширины рабочей области
|
|
double m_position_step;
|
|
//--- Состояние кнопки мыши (нажата/отжата)
|
|
ENUM_MOUSE_STATE m_clamping_left_thumb;
|
|
ENUM_MOUSE_STATE m_clamping_right_thumb;
|
|
//--- Для определения режима перемещения ползунка слайдера
|
|
bool m_slider_thumb_state;
|
|
//--- Переменные связанные с перемещением ползунка
|
|
int m_slider_size_fixing;
|
|
int m_slider_point_fixing;
|
|
//--- Режим двойного слайдера
|
|
bool m_dual_slider_mode;
|
|
//---
|
|
public:
|
|
CSlider(void);
|
|
~CSlider(void);
|
|
//--- Методы для создания элемента
|
|
bool CreateSlider(const string text,const int x_gap,const int y_gap);
|
|
//---
|
|
private:
|
|
void InitializeProperties(const string text,const int x_gap,const int y_gap);
|
|
bool CreateCanvas(void);
|
|
bool CreateLeftTextEdit(void);
|
|
bool CreateRightTextEdit(void);
|
|
//---
|
|
public:
|
|
//--- Возвращает указатели на элементы
|
|
CTextEdit *GetLeftEditPointer(void) { return(::GetPointer(m_left_edit)); }
|
|
CTextEdit *GetRightEditPointer(void) { return(::GetPointer(m_right_edit)); }
|
|
//--- Цвета индикатора слайдера в разных состояниях
|
|
void SlotLineDarkColor(const color clr) { m_slot_line_dark_color=clr; }
|
|
void SlotLineLightColor(const color clr) { m_slot_line_light_color=clr; }
|
|
void SlotIndicatorColor(const color clr) { m_slot_indicator_color=clr; }
|
|
void SlotIndicatorColorLocked(const color clr) { m_slot_indicator_color_locked=clr; }
|
|
//--- Режим двойного слайдера
|
|
void DualSliderMode(const bool state) { m_dual_slider_mode=state; }
|
|
bool DualSliderMode(void) const { return(m_dual_slider_mode); }
|
|
bool State(void) const { return(m_slider_thumb_state); }
|
|
//--- Размеры ползунка слайдера
|
|
void ThumbXSize(const int x_size) { m_thumb_x_size=x_size; }
|
|
void ThumbYSize(const int y_size) { m_thumb_y_size=y_size; }
|
|
//--- Цвета ползунка слайдера
|
|
void ThumbColor(const color clr) { m_thumb_color=clr; }
|
|
void ThumbColorHover(const color clr) { m_thumb_color_hover=clr; }
|
|
void ThumbColorLocked(const color clr) { m_thumb_color_locked=clr; }
|
|
void ThumbColorPressed(const color clr) { m_thumb_color_pressed=clr; }
|
|
//---
|
|
public:
|
|
//--- Обработчик событий графика
|
|
virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
|
//--- Рисует элемент
|
|
virtual void Draw(void);
|
|
//---
|
|
private:
|
|
//--- Обработка ввода значения в поле ввода
|
|
bool OnEndEditLeftThumb(const int id,const int index);
|
|
bool OnEndEditRightThumb(const int id,const int index);
|
|
//--- Процесс перемещения ползунка слайдера
|
|
void OnDragLeftThumb(void);
|
|
void OnDragRightThumb(void);
|
|
//--- Обновление положения ползунка слайдера
|
|
void UpdateLeftThumb(const int new_x_point);
|
|
void UpdateRightThumb(const int new_x_point);
|
|
|
|
//--- Проверка фокуса над ползунком
|
|
bool CheckLeftThumbFocus(void);
|
|
bool CheckRightThumbFocus(void);
|
|
//--- Проверяет состояние кнопки мыши
|
|
void CheckMouseOnLeftThumb(void);
|
|
void CheckMouseOnRightThumb(void);
|
|
//--- Обнуление переменных связанных с перемещением ползунка слайдера
|
|
void ZeroLeftThumbVariables(void);
|
|
void ZeroRightThumbVariables(void);
|
|
//--- Расчёт значений (шаги и коэффициенты)
|
|
bool CalculateCoefficients(void);
|
|
//--- Расчёт координаты X ползунка слайдера
|
|
void CalculateLeftThumbX(void);
|
|
void CalculateRightThumbX(void);
|
|
//--- Изменяет позицию ползунка слайдера относительно текущего значения
|
|
void CalculateLeftThumbPos(void);
|
|
void CalculateRightThumbPos(void);
|
|
//--- Текущий цвет ползунка
|
|
uint ThumbColorCurrent(const bool thumb_focus,const ENUM_MOUSE_STATE thumb_clamping);
|
|
|
|
//--- Рисует границы для индикатора
|
|
void DrawSlot(void);
|
|
//--- Рисует индикатор
|
|
void DrawIndicator(void);
|
|
//--- Рисует ползунок слайдера
|
|
void DrawLeftThumb(void);
|
|
void DrawRightThumb(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CSlider::CSlider(void) : m_dual_slider_mode(false),
|
|
m_slider_size_fixing(0),
|
|
m_slider_point_fixing(0),
|
|
m_slot_y(30),
|
|
m_slot_y_size(4),
|
|
m_slot_line_dark_color(clrSilver),
|
|
m_slot_line_light_color(clrWhite),
|
|
m_slot_indicator_color(C'85,170,255'),
|
|
m_slot_indicator_color_locked(clrLightGray),
|
|
m_thumb_x_pos_left(WRONG_VALUE),
|
|
m_thumb_x_pos_right(WRONG_VALUE),
|
|
m_thumb_x_left(0),
|
|
m_thumb_x_right(0),
|
|
m_thumb_y(0),
|
|
m_thumb_x_size(6),
|
|
m_thumb_y_size(14),
|
|
m_thumb_color(C'205,205,205'),
|
|
m_thumb_color_hover(C'166,166,166'),
|
|
m_thumb_color_locked(clrLightGray),
|
|
m_thumb_color_pressed(C'96,96,96'),
|
|
m_thumb_focus_left(false),
|
|
m_thumb_focus_right(false),
|
|
m_is_crossing_left_thumb_border(false),
|
|
m_is_crossing_right_thumb_border(false)
|
|
{
|
|
//--- Сохраним имя класса элемента в базовом классе
|
|
CElementBase::ClassName(CLASS_NAME);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CSlider::~CSlider(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработчик события графика |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
|
{
|
|
//--- Обработка события перемещения курсора
|
|
if(id==CHARTEVENT_MOUSE_MOVE)
|
|
{
|
|
//--- Проверим и запомним состояние кнопки мыши
|
|
CheckMouseOnRightThumb();
|
|
//--- Изменим цвет ползунка слайдера
|
|
CheckRightThumbFocus();
|
|
//--- Если управление передано полосе слайдера, определим её положение
|
|
if(m_clamping_right_thumb==PRESSED_INSIDE)
|
|
{
|
|
//--- Перемещение ползунка слайдера
|
|
OnDragRightThumb();
|
|
//--- Расчёт позиции ползунка слайдера в диапазоне значений
|
|
CalculateRightThumbPos();
|
|
//--- Установка нового значения в поле ввода
|
|
m_right_edit.SetValue(::DoubleToString(m_thumb_x_pos_right,m_right_edit.GetDigits()),false);
|
|
//--- Обновить элемент
|
|
Update(true);
|
|
m_right_edit.GetTextBoxPointer().Update(true);
|
|
return;
|
|
}
|
|
//--- Выйти, если это не двойной слайдер
|
|
if(!m_dual_slider_mode)
|
|
return;
|
|
//--- Проверим и запомним состояние кнопки мыши
|
|
CheckMouseOnLeftThumb();
|
|
//--- Изменим цвет ползунка слайдера
|
|
CheckLeftThumbFocus();
|
|
//--- Если управление передано полосе слайдера, определим её положение
|
|
if(m_clamping_left_thumb==PRESSED_INSIDE)
|
|
{
|
|
//--- Перемещение ползунка слайдера
|
|
OnDragLeftThumb();
|
|
//--- Расчёт позиции ползунка слайдера в диапазоне значений
|
|
CalculateLeftThumbPos();
|
|
//--- Установка нового значения в поле ввода
|
|
m_left_edit.SetValue(::DoubleToString(m_thumb_x_pos_left,m_left_edit.GetDigits()),false);
|
|
//--- Обновить элемент
|
|
Update(true);
|
|
m_left_edit.GetTextBoxPointer().Update(true);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
//--- Обработка события изменения значения в поле ввода
|
|
if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
|
|
{
|
|
//--- Обработка ввода значения
|
|
if(OnEndEditLeftThumb((int)lparam,(int)dparam))
|
|
return;
|
|
//--- Обработка ввода значения
|
|
if(OnEndEditRightThumb((int)lparam,(int)dparam))
|
|
return;
|
|
//---
|
|
return;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт слайдер с полем ввода |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CreateSlider(const string text,const int x_gap,const int y_gap)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return(false);
|
|
//--- Инициализация свойств
|
|
InitializeProperties(text,x_gap,y_gap);
|
|
//--- Создание элемента
|
|
if(!CreateCanvas())
|
|
return(false);
|
|
if(!CreateRightTextEdit())
|
|
return(false);
|
|
if(!CreateLeftTextEdit())
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация свойств |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::InitializeProperties(const string text,const int x_gap,const int y_gap)
|
|
{
|
|
m_x =CElement::CalculateX(x_gap);
|
|
m_y =CElement::CalculateY(y_gap);
|
|
m_label_text =text;
|
|
m_back_color =(m_back_color!=clrNONE)? m_back_color : m_main.BackColor();
|
|
m_border_color=(m_border_color!=clrNONE)? m_border_color : clrBlack;
|
|
//--- Отступы от крайней точки
|
|
CElementBase::XGap(x_gap);
|
|
CElementBase::YGap(y_gap);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт объект для рисования |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CreateCanvas(void)
|
|
{
|
|
//--- Формирование имени объекта
|
|
string name=CElementBase::ElementName("slider");
|
|
//--- Создание объекта
|
|
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт поле ввода |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CreateRightTextEdit(void)
|
|
{
|
|
//--- Сохраним указатель на главный элемент
|
|
m_right_edit.MainPointer(this);
|
|
//--- Координаты
|
|
int x=0,y=0;
|
|
//--- Свойства
|
|
m_right_edit.Index(0);
|
|
m_right_edit.YSize(20);
|
|
m_right_edit.LabelXGap(0);
|
|
m_right_edit.MaxValue((m_right_edit.MaxValue()==DBL_MAX)? 1000 : m_right_edit.MaxValue());
|
|
m_right_edit.MinValue((m_right_edit.MinValue()==DBL_MIN)? -1000 : m_right_edit.MinValue());
|
|
m_right_edit.StepValue(m_right_edit.StepValue());
|
|
m_right_edit.SetDigits(m_right_edit.GetDigits());
|
|
//--- Значение в поле ввода
|
|
int digits=m_right_edit.GetDigits();
|
|
string value=(m_right_edit.GetValue()=="")? ::DoubleToString(0,digits) : m_right_edit.GetValue();
|
|
m_right_edit.SetValue(value);
|
|
//--- Размер
|
|
int xsize=m_right_edit.GetTextBoxPointer().XSize();
|
|
m_right_edit.GetTextBoxPointer().XSize((xsize>0)? xsize : 60);
|
|
//---
|
|
m_right_edit.AutoXResizeMode(true);
|
|
m_right_edit.IsDropdown(CElementBase::IsDropdown());
|
|
m_right_edit.GetTextBoxPointer().AnchorRightWindowSide(true);
|
|
//--- Создадим элемент управления
|
|
if(!m_right_edit.CreateTextEdit(m_label_text,x,y))
|
|
return(false);
|
|
//--- Добавить элемент в массив
|
|
CElement::AddToArray(m_right_edit);
|
|
//--- Расчёт значений вспомогательных переменных
|
|
CalculateCoefficients();
|
|
//--- Расчёт координаты X ползунка относительно текущего значения в поле ввода
|
|
CalculateRightThumbX();
|
|
//--- Расчёт координаты Y ползунка
|
|
m_thumb_y=m_slot_y-((m_thumb_y_size-m_slot_y_size)/2);
|
|
//--- Расчёт позиции ползунка слайдера в диапазоне значений
|
|
CalculateRightThumbPos();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт поле ввода |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CreateLeftTextEdit(void)
|
|
{
|
|
if(!m_dual_slider_mode)
|
|
return(true);
|
|
//--- Сохраним указатель на родителя
|
|
m_left_edit.MainPointer(this);
|
|
//--- Размеры
|
|
int x_size=m_right_edit.GetTextBoxPointer().XSize();
|
|
//--- Координаты
|
|
int x=x_size*2+2;
|
|
int y=0;
|
|
//--- Свойства
|
|
m_left_edit.Index(1);
|
|
m_left_edit.XSize(x_size+1);
|
|
m_left_edit.YSize(20);
|
|
m_left_edit.LabelXGap(0);
|
|
m_left_edit.MaxValue(m_right_edit.MaxValue());
|
|
m_left_edit.MinValue(m_right_edit.MinValue());
|
|
m_left_edit.StepValue(m_right_edit.StepValue());
|
|
m_left_edit.SetDigits(m_right_edit.GetDigits());
|
|
//--- Значение в поле ввода
|
|
int digits=m_right_edit.GetDigits();
|
|
string value=(m_left_edit.GetValue()=="")? ::DoubleToString(0,digits) : m_left_edit.GetValue();
|
|
m_left_edit.SetValue((string)value);
|
|
m_left_edit.AnchorRightWindowSide(true);
|
|
m_left_edit.IsDropdown(CElementBase::IsDropdown());
|
|
m_left_edit.GetTextBoxPointer().XSize(x_size);
|
|
m_left_edit.GetTextBoxPointer().AnchorRightWindowSide(true);
|
|
//--- Создадим элемент управления
|
|
if(!m_left_edit.CreateTextEdit("",x,y))
|
|
return(false);
|
|
//--- Добавить элемент в массив
|
|
CElement::AddToArray(m_left_edit);
|
|
//--- Расчёт координаты X ползунка относительно текущего значения в поле ввода
|
|
CalculateLeftThumbX();
|
|
//--- Расчёт позиции ползунка слайдера в диапазоне значений
|
|
CalculateLeftThumbPos();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка ввода значения в поле ввода |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::OnEndEditLeftThumb(const int id,const int index)
|
|
{
|
|
//--- Выйдем, если идентификаторы и индексы не совпадают
|
|
if(id!=m_left_edit.Id() || index!=m_left_edit.Index())
|
|
return(false);
|
|
//--- Получим только что введённое значение
|
|
double entered_value=::StringToDouble(m_left_edit.GetValue());
|
|
//--- Рассчитаем координату X ползунка
|
|
CalculateLeftThumbX();
|
|
//--- Обновление положения ползунка слайдера
|
|
UpdateLeftThumb((int)m_thumb_x_left);
|
|
//--- Рассчитаем позицию в диапазоне значений
|
|
CalculateLeftThumbPos();
|
|
//--- Установка нового значения в поле ввода
|
|
m_left_edit.SetValue(::DoubleToString(m_thumb_x_pos_left,m_left_edit.GetDigits()));
|
|
//--- Обновить элемент
|
|
Update(true);
|
|
m_left_edit.GetTextBoxPointer().Update(true);
|
|
//--- Отправим сообщение об этом
|
|
//::EventChartCustom(m_chart_id,ON_END_EDIT,CElementBase::Id(),index,m_label_text);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка ввода значения в поле ввода |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::OnEndEditRightThumb(const int id,const int index)
|
|
{
|
|
//--- Выйдем, если идентификаторы и индексы не совпадают
|
|
if(id!=m_right_edit.Id() || index!=m_right_edit.Index())
|
|
return(false);
|
|
//--- Получим только что введённое значение
|
|
double entered_value=::StringToDouble(m_right_edit.GetValue());
|
|
//--- Рассчитаем координату X ползунка
|
|
CalculateRightThumbX();
|
|
//--- Обновление положения ползунка слайдера
|
|
UpdateRightThumb((int)m_thumb_x_right);
|
|
//--- Рассчитаем позицию в диапазоне значений
|
|
CalculateRightThumbPos();
|
|
//--- Установка нового значения в поле ввода
|
|
m_right_edit.SetValue(::DoubleToString(m_thumb_x_pos_right,m_right_edit.GetDigits()));
|
|
//--- Обновить элемент
|
|
Update(true);
|
|
m_right_edit.GetTextBoxPointer().Update(true);
|
|
//--- Отправим сообщение об этом
|
|
//::EventChartCustom(m_chart_id,ON_END_EDIT,CElementBase::Id(),index,m_label_text);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Процесс перемещения ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::OnDragLeftThumb(void)
|
|
{
|
|
int x=m_mouse.RelativeX(m_canvas);
|
|
//--- Для определения новой X координаты
|
|
int new_x_point=0;
|
|
//--- Если ползунок слайдера неактивен, ...
|
|
if(!m_slider_thumb_state)
|
|
{
|
|
//--- ...обнулим вспомогательные переменные для перемещения ползунка
|
|
m_slider_point_fixing =0;
|
|
m_slider_size_fixing =0;
|
|
return;
|
|
}
|
|
//--- Если точка фиксации нулевая, то запомним текущую координату курсора
|
|
if(m_slider_point_fixing==0)
|
|
m_slider_point_fixing=x;
|
|
//--- Если значение расстояния от крайней точки ползунка до текущей координаты курсора нулевое, рассчитаем его
|
|
if(m_slider_size_fixing==0)
|
|
m_slider_size_fixing=(int)m_thumb_x_left-x;
|
|
//--- Если в нажатом состоянии прошли порог вправо
|
|
if(x-m_slider_point_fixing>0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x+m_slider_size_fixing;
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateLeftThumb(new_x_point);
|
|
return;
|
|
}
|
|
//--- Если в нажатом состоянии прошли порог влево
|
|
if(x-m_slider_point_fixing<0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x-::fabs(m_slider_size_fixing);
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateLeftThumb(new_x_point);
|
|
return;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Процесс перемещения ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::OnDragRightThumb(void)
|
|
{
|
|
int x=m_mouse.RelativeX(m_canvas);
|
|
//--- Для определения новой X координаты
|
|
int new_x_point=0;
|
|
//--- Если ползунок слайдера неактивен, ...
|
|
if(!m_slider_thumb_state)
|
|
{
|
|
//--- ...обнулим вспомогательные переменные для перемещения ползунка
|
|
m_slider_point_fixing =0;
|
|
m_slider_size_fixing =0;
|
|
return;
|
|
}
|
|
//--- Если точка фиксации нулевая, то запомним текущую координату курсора
|
|
if(m_slider_point_fixing==0)
|
|
m_slider_point_fixing=x;
|
|
//--- Если значение расстояния от крайней точки ползунка до текущей координаты курсора нулевое, рассчитаем его
|
|
if(m_slider_size_fixing==0)
|
|
m_slider_size_fixing=(int)m_thumb_x_right-x;
|
|
//--- Если в нажатом состоянии прошли порог вправо
|
|
if(x-m_slider_point_fixing>0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x+m_slider_size_fixing;
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateRightThumb(new_x_point);
|
|
return;
|
|
}
|
|
//--- Если в нажатом состоянии прошли порог влево
|
|
if(x-m_slider_point_fixing<0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x-::fabs(m_slider_size_fixing);
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateRightThumb(new_x_point);
|
|
return;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обновление положения ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::UpdateLeftThumb(const int new_x_point)
|
|
{
|
|
int x=new_x_point;
|
|
//--- Обнуление точки фиксации
|
|
m_slider_point_fixing=0;
|
|
//--- Правая граница
|
|
int right_limit=(!m_dual_slider_mode)? m_x_size-m_thumb_x_size :(int)m_thumb_x_right-m_thumb_x_size;
|
|
//--- Проверка на выход из рабочей области
|
|
if(x>right_limit)
|
|
x=right_limit;
|
|
if(x<=0)
|
|
x=0;
|
|
//--- Сохранить координату
|
|
m_thumb_x_left=x;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обновление положения ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::UpdateRightThumb(const int new_x_point)
|
|
{
|
|
int x=new_x_point;
|
|
//--- Обнуление точки фиксации
|
|
m_slider_point_fixing=0;
|
|
//--- Правая граница
|
|
int right_limit=m_x_size-m_thumb_x_size;
|
|
//--- Левая граница
|
|
int left_limit=(!m_dual_slider_mode)? 0 :(int)m_thumb_x_left+m_thumb_x_size;
|
|
//--- Проверка на выход из рабочей области
|
|
if(x>right_limit)
|
|
x=right_limit;
|
|
if(x<=left_limit)
|
|
x=left_limit;
|
|
//--- Сохранить координату
|
|
m_thumb_x_right=x;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Текущий цвет ползунка |
|
|
//+------------------------------------------------------------------+
|
|
uint CSlider::ThumbColorCurrent(const bool thumb_focus,const ENUM_MOUSE_STATE thumb_clamping)
|
|
{
|
|
//--- Определим цвет ползунка
|
|
color clr=(thumb_clamping==PRESSED_INSIDE)? m_thumb_color_pressed : m_thumb_color;
|
|
//--- Если курсор мыши в зоне ползунка
|
|
if(thumb_focus)
|
|
{
|
|
//--- Если левая кнопка мыши отжата
|
|
if(thumb_clamping==NOT_PRESSED)
|
|
clr=m_thumb_color_hover;
|
|
//--- Левая кнопка мыши нажата на ползунке
|
|
else if(thumb_clamping==PRESSED_INSIDE)
|
|
clr=m_thumb_color_pressed;
|
|
}
|
|
//--- Если курсор вне зоны ползунка
|
|
else
|
|
{
|
|
//--- Левая кнопка мыши отжата
|
|
if(thumb_clamping==NOT_PRESSED)
|
|
clr=(m_is_locked)? m_thumb_color_locked : m_thumb_color;
|
|
}
|
|
//---
|
|
return(::ColorToARGB(clr));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка фокуса над ползунком |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CheckLeftThumbFocus(void)
|
|
{
|
|
//--- Выйти, если невалидный указатель
|
|
if(::CheckPointer(m_mouse)==POINTER_INVALID)
|
|
return(false);
|
|
//--- Проверка фокуса над ползунком
|
|
int x =m_mouse.RelativeX(m_canvas);
|
|
int y =m_mouse.RelativeY(m_canvas);
|
|
//--- Проверка фокуса
|
|
m_thumb_focus_left=(x>m_thumb_x_left && x<m_thumb_x_left+m_thumb_x_size &&
|
|
y>m_thumb_y && y<m_thumb_y+m_thumb_y_size);
|
|
//--- Если это момент пересечения границ элемента
|
|
if((m_thumb_focus_left && !m_is_crossing_left_thumb_border) ||
|
|
(!m_thumb_focus_left && m_is_crossing_left_thumb_border))
|
|
{
|
|
m_is_crossing_left_thumb_border=m_thumb_focus_left;
|
|
//--- Нарисовать прямоугольник с заливкой
|
|
DrawLeftThumb();
|
|
m_canvas.Update();
|
|
return(true);
|
|
}
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка фокуса над ползунком |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CheckRightThumbFocus(void)
|
|
{
|
|
//--- Выйти, если невалидный указатель
|
|
if(::CheckPointer(m_mouse)==POINTER_INVALID)
|
|
return(false);
|
|
//--- Проверка фокуса над ползунком
|
|
int x =m_mouse.RelativeX(m_canvas);
|
|
int y =m_mouse.RelativeY(m_canvas);
|
|
//--- Проверка фокуса
|
|
m_thumb_focus_right=(x>m_thumb_x_right && x<m_thumb_x_right+m_thumb_x_size &&
|
|
y>m_thumb_y && y<m_thumb_y+m_thumb_y_size);
|
|
//--- Если это момент пересечения границ элемента
|
|
if((m_thumb_focus_right && !m_is_crossing_right_thumb_border) ||
|
|
(!m_thumb_focus_right && m_is_crossing_right_thumb_border))
|
|
{
|
|
m_is_crossing_right_thumb_border=m_thumb_focus_right;
|
|
//--- Нарисовать прямоугольник с заливкой
|
|
DrawRightThumb();
|
|
m_canvas.Update();
|
|
return(true);
|
|
}
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверяет состояние кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CheckMouseOnLeftThumb(void)
|
|
{
|
|
//--- Выйти, если это не двойной слайдер
|
|
if(!m_dual_slider_mode)
|
|
return;
|
|
//--- Если левая кнопка мыши отжата
|
|
if(!m_mouse.LeftButtonState())
|
|
{
|
|
//--- Обнулим переменные
|
|
ZeroLeftThumbVariables();
|
|
return;
|
|
}
|
|
//--- Если левая кнопка мыши нажата
|
|
else
|
|
{
|
|
//--- Выйдем, если кнопка уже нажата в какой-либо области
|
|
if(m_clamping_left_thumb!=NOT_PRESSED)
|
|
return;
|
|
//--- Вне области ползунка слайдера
|
|
if(!m_thumb_focus_left)
|
|
m_clamping_left_thumb=PRESSED_OUTSIDE;
|
|
//--- В области ползунка слайдера
|
|
else
|
|
{
|
|
m_slider_thumb_state =true;
|
|
m_clamping_left_thumb =PRESSED_INSIDE;
|
|
//--- Перерисовать ползунок
|
|
DrawLeftThumb();
|
|
m_canvas.Update();
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),0,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверяет состояние кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CheckMouseOnRightThumb(void)
|
|
{
|
|
//--- Если левая кнопка мыши отжата
|
|
if(!m_mouse.LeftButtonState())
|
|
{
|
|
//--- Обнулим переменные
|
|
ZeroRightThumbVariables();
|
|
return;
|
|
}
|
|
//--- Если левая кнопка мыши нажата
|
|
else
|
|
{
|
|
//--- Выйдем, если кнопка уже нажата в какой-либо области
|
|
if(m_clamping_right_thumb!=NOT_PRESSED)
|
|
return;
|
|
//--- Вне области ползунка слайдера
|
|
if(!m_thumb_focus_right)
|
|
m_clamping_right_thumb=PRESSED_OUTSIDE;
|
|
//--- В области ползунка слайдера
|
|
else
|
|
{
|
|
m_slider_thumb_state=true;
|
|
m_clamping_right_thumb=PRESSED_INSIDE;
|
|
//--- Перерисовать ползунок
|
|
DrawRightThumb();
|
|
m_canvas.Update();
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),0,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обнуление переменных связанных с перемещением ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::ZeroLeftThumbVariables(void)
|
|
{
|
|
//--- Выйти, если это не двойной слайдер
|
|
if(!m_dual_slider_mode)
|
|
return;
|
|
//--- Если зашли сюда, то это значит, что левая кнопка мыши отжата.
|
|
// Если до этого зажатие левой кнопки мыши было осуществлено над ползунком слайдера...
|
|
if(m_clamping_left_thumb==PRESSED_INSIDE)
|
|
{
|
|
//--- ... отправим сообщение, что изменение значения в поле ввода посредством ползунка завершена
|
|
::EventChartCustom(m_chart_id,ON_END_EDIT,CElementBase::Id(),CElementBase::Index(),"");
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),1,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
//--- Обнулить переменные
|
|
if(m_clamping_left_thumb!=NOT_PRESSED)
|
|
{
|
|
m_slider_thumb_state =false;
|
|
m_slider_size_fixing =0;
|
|
m_clamping_left_thumb =NOT_PRESSED;
|
|
//--- Перерисовать ползунок
|
|
DrawLeftThumb();
|
|
m_canvas.Update();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обнуление переменных связанных с перемещением ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::ZeroRightThumbVariables(void)
|
|
{
|
|
//--- Если зашли сюда, то это значит, что левая кнопка мыши отжата.
|
|
// Если до этого зажатие левой кнопки мыши было осуществлено над ползунком слайдера...
|
|
if(m_clamping_right_thumb==PRESSED_INSIDE)
|
|
{
|
|
//--- ... отправим сообщение, что изменение значения в поле ввода посредством ползунка завершена
|
|
::EventChartCustom(m_chart_id,ON_END_EDIT,CElementBase::Id(),CElementBase::Index(),"");
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),1,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
//--- Обнулить переменные
|
|
if(m_clamping_right_thumb!=NOT_PRESSED)
|
|
{
|
|
m_slider_thumb_state =false;
|
|
m_slider_size_fixing =0;
|
|
m_clamping_right_thumb =NOT_PRESSED;
|
|
//--- Перерисовать ползунок
|
|
DrawRightThumb();
|
|
m_canvas.Update();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт значений (шаги и коэффициенты) |
|
|
//+------------------------------------------------------------------+
|
|
bool CSlider::CalculateCoefficients(void)
|
|
{
|
|
//--- Выйти, если ширина элемента меньше, чем ширина ползунка слайдера
|
|
if(CElementBase::XSize()<m_thumb_x_size)
|
|
return(false);
|
|
//--- Количество пикселей в рабочей области
|
|
m_pixels_total=CElementBase::XSize()-m_thumb_x_size;
|
|
//--- Количество шагов в диапазоне значений рабочей области
|
|
m_value_steps_total=int((m_right_edit.MaxValue()-m_right_edit.MinValue())/m_right_edit.StepValue());
|
|
//--- Размер шага относительно ширины рабочей области
|
|
m_position_step=m_right_edit.StepValue()*(double(m_value_steps_total)/double(m_pixels_total));
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт координаты X ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CalculateLeftThumbX(void)
|
|
{
|
|
//--- Корректировка с учётом того, что минимальное значение может быть отрицательным
|
|
double neg_range=(m_left_edit.MinValue()<0)? ::fabs(m_left_edit.MinValue()/m_position_step) : 0;
|
|
//--- Рассчитаем координату X для ползунка слайдера
|
|
m_thumb_x_left=((double)m_left_edit.GetValue()/m_position_step)+neg_range;
|
|
//--- Если выходим за пределы рабочей области влево
|
|
if(m_thumb_x_left<0)
|
|
m_thumb_x_left=0;
|
|
//--- Если выходим за пределы рабочей области вправо
|
|
if(m_thumb_x_left+m_thumb_x_size>m_thumb_x_right)
|
|
m_thumb_x_left=m_thumb_x_right-m_thumb_x_size;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт координаты X ползунка слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CalculateRightThumbX(void)
|
|
{
|
|
//--- Корректировка с учётом того, что минимальное значение может быть отрицательным
|
|
double neg_range=(m_right_edit.MinValue()<0)? ::fabs(m_right_edit.MinValue()/m_position_step) : 0;
|
|
//--- Рассчитаем координату X для ползунка слайдера
|
|
m_thumb_x_right=((double)m_right_edit.GetValue()/m_position_step)+neg_range;
|
|
//--- Если выходим за пределы рабочей области влево
|
|
if(m_thumb_x_right<0)
|
|
m_thumb_x_right=0;
|
|
//--- Если выходим за пределы рабочей области вправо
|
|
if(m_thumb_x_right+m_thumb_x_size>m_x_size)
|
|
m_thumb_x_right=m_x_size-m_thumb_x_size;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт позиции ползунка слайдера в диапазоне значений |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CalculateLeftThumbPos(void)
|
|
{
|
|
//--- Получим номер позиции ползунка слайдера
|
|
m_thumb_x_pos_left=m_thumb_x_left*m_position_step;
|
|
//--- Корректировка с учётом того, что минимальное значение может быть отрицательным
|
|
if(m_left_edit.MinValue()<0 && m_thumb_x_left!=WRONG_VALUE)
|
|
m_thumb_x_pos_left+=int(m_left_edit.MinValue());
|
|
//--- Проверка на выход из рабочей области влево
|
|
if(m_thumb_x_left<=0)
|
|
m_thumb_x_pos_left=int(m_left_edit.MinValue());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт позиции ползунка слайдера в диапазоне значений |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::CalculateRightThumbPos(void)
|
|
{
|
|
//--- Получим номер позиции ползунка слайдера
|
|
m_thumb_x_pos_right=m_thumb_x_right*m_position_step;
|
|
//--- Корректировка с учётом того, что минимальное значение может быть отрицательным
|
|
if(m_right_edit.MinValue()<0 && m_thumb_x_right!=WRONG_VALUE)
|
|
m_thumb_x_pos_right+=int(m_right_edit.MinValue());
|
|
//--- Проверка на выход из рабочей области вправо/влево
|
|
if(m_thumb_x_right+m_thumb_x_size>m_x_size)
|
|
m_thumb_x_pos_right=int(m_right_edit.MaxValue());
|
|
if(m_thumb_x_right<=0)
|
|
m_thumb_x_pos_right=int(m_right_edit.MinValue());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует элемент |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::Draw(void)
|
|
{
|
|
//--- Нарисовать фон
|
|
CElement::DrawBackground();
|
|
//--- Нарисовать границы индикатора
|
|
DrawSlot();
|
|
//--- Нарисовать индикатор
|
|
DrawIndicator();
|
|
//--- Нарисовать ползунок слайдера
|
|
DrawLeftThumb();
|
|
//--- Нарисовать ползунок слайдера
|
|
DrawRightThumb();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует границы для индикатора |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::DrawSlot(void)
|
|
{
|
|
//--- Верхняя граница
|
|
int x1=0,x2=m_x_size;
|
|
int y1=m_slot_y,y2=y1;
|
|
m_canvas.Line(x1,y1,x2,y2,::ColorToARGB(m_slot_line_dark_color));
|
|
//--- Нижняя граница
|
|
y1+=m_slot_y_size; y2=y1;
|
|
m_canvas.Line(x1,y1,x2,y2,::ColorToARGB(m_slot_line_light_color));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует индикатор |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::DrawIndicator(void)
|
|
{
|
|
//--- Координаты
|
|
int x1 =(int)m_thumb_x_left;
|
|
int x2 =(int)m_thumb_x_right;
|
|
int y1 =m_slot_y+1;
|
|
int y2 =m_slot_y+m_slot_y_size-1;
|
|
//--- Цвет
|
|
color clr=(m_is_locked)? m_slot_indicator_color_locked : m_slot_indicator_color;
|
|
//--- Рисуем индикатор
|
|
m_canvas.FillRectangle(x1,y1,x2,y2,::ColorToARGB(clr));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует ползунок слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::DrawLeftThumb(void)
|
|
{
|
|
//--- Выйти, если это не двойной слайдер
|
|
if(!m_dual_slider_mode)
|
|
return;
|
|
//--- Координаты
|
|
int x1 =(int)m_thumb_x_left;
|
|
int x2 =(int)m_thumb_x_left+m_thumb_x_size;
|
|
int y1 =m_thumb_y;
|
|
int y2 =y1+m_thumb_y_size;
|
|
//--- Рисуем ползунок
|
|
m_canvas.FillRectangle(x1,y1,x2,y2,ThumbColorCurrent(m_thumb_focus_left,m_clamping_left_thumb));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует ползунок слайдера |
|
|
//+------------------------------------------------------------------+
|
|
void CSlider::DrawRightThumb(void)
|
|
{
|
|
//--- Координаты
|
|
int x1 =(int)m_thumb_x_right;
|
|
int x2 =(int)m_thumb_x_right+m_thumb_x_size;
|
|
int y1 =m_thumb_y;
|
|
int y2 =y1+m_thumb_y_size;
|
|
//--- Рисуем ползунок
|
|
m_canvas.FillRectangle(x1,y1,x2,y2,ThumbColorCurrent(m_thumb_focus_right,m_clamping_right_thumb));
|
|
}
|
|
//+------------------------------------------------------------------+
|