1166 linhas
97 KiB
MQL5
1166 linhas
97 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Scrolls.mqh |
|
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include "..\Element.mqh"
|
|
#include "Button.mqh"
|
|
//--- Список классов в файле для быстрого перехода (Alt+G)
|
|
class CScroll;
|
|
class CScrollV;
|
|
class CScrollH;
|
|
//+------------------------------------------------------------------+
|
|
//| Базовый класс для создания полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
class CScroll : public CElement
|
|
{
|
|
protected:
|
|
//--- Объекты для создания полосы прокрутки
|
|
CButton m_button_inc;
|
|
CButton m_button_dec;
|
|
//--- Свойства общей площади полосы прокрутки
|
|
int m_area_width;
|
|
int m_area_length;
|
|
//--- Картинки для кнопок
|
|
string m_inc_file;
|
|
string m_inc_file_locked;
|
|
string m_inc_file_pressed;
|
|
string m_dec_file;
|
|
string m_dec_file_locked;
|
|
string m_dec_file_pressed;
|
|
//--- (1) Фокус на ползунке и (2) момент его пересечения границ
|
|
bool m_thumb_focus;
|
|
bool m_is_crossing_thumb_border;
|
|
//--- Цвета ползунка в разных состояниях
|
|
color m_thumb_color;
|
|
color m_thumb_color_hover;
|
|
color m_thumb_color_pressed;
|
|
//--- (1) Общее количество пунктов и (2) видимое
|
|
int m_items_total;
|
|
int m_visible_items_total;
|
|
//--- Координаты ползунка
|
|
int m_thumb_x;
|
|
int m_thumb_y;
|
|
//--- (1) Ширина ползунка, (2) длина ползунка и (3) его минимальная длина
|
|
int m_thumb_width;
|
|
int m_thumb_length;
|
|
int m_thumb_min_length;
|
|
//--- (1) Размер шага ползунка и (2) кол-во шагов
|
|
double m_thumb_step_size;
|
|
double m_thumb_steps_total;
|
|
//--- Переменные связанные с перемещением ползунка
|
|
bool m_scroll_state;
|
|
int m_thumb_size_fixing;
|
|
int m_thumb_point_fixing;
|
|
//--- Текущая позиция ползунка
|
|
int m_current_pos;
|
|
//--- Для определения области зажатия левой кнопки мыши
|
|
ENUM_MOUSE_STATE m_clamping_area_mouse;
|
|
//---
|
|
public:
|
|
CScroll(void);
|
|
~CScroll(void);
|
|
//--- Методы для создания полосы прокрутки
|
|
bool CreateScroll(const int x_gap,const int y_gap,
|
|
const int items_total,const int visible_items_total);
|
|
//---
|
|
private:
|
|
void InitializeProperties(const int x_gap,const int y_gap,
|
|
const int items_total,const int visible_items_total);
|
|
bool CreateCanvas(void);
|
|
bool CreateScrollButton(CButton &button_obj,const int index);
|
|
//---
|
|
public:
|
|
//--- Возвращает указатели на кнопки полосы прокрутки
|
|
CButton *GetIncButtonPointer(void) { return(::GetPointer(m_button_inc)); }
|
|
CButton *GetDecButtonPointer(void) { return(::GetPointer(m_button_dec)); }
|
|
//--- Ширина полосы прокрутки
|
|
void ScrollWidth(const int width) { m_area_width=width; }
|
|
int ScrollWidth(void) const { return(m_area_width); }
|
|
//--- Установка картинок для кнопок
|
|
void IncFile(const string file_path) { m_inc_file=file_path; }
|
|
void IncFileLocked(const string file_path) { m_inc_file_locked=file_path; }
|
|
void IncFilePressed(const string file_path) { m_inc_file_pressed=file_path; }
|
|
void DecFile(const string file_path) { m_dec_file=file_path; }
|
|
void DecFileLocked(const string file_path) { m_dec_file_locked=file_path; }
|
|
void DecFilePressed(const string file_path) { m_dec_file_pressed=file_path; }
|
|
//--- (1) Цвета ползунка и (2) рамки ползунка
|
|
void ThumbColor(const color clr) { m_thumb_color=clr; }
|
|
void ThumbColorHover(const color clr) { m_thumb_color_hover=clr; }
|
|
void ThumbColorPressed(const color clr) { m_thumb_color_pressed=clr; }
|
|
//--- Состояние кнопок
|
|
bool ScrollIncState(void) const { return(m_button_inc.IsPressed()); }
|
|
bool ScrollDecState(void) const { return(m_button_dec.IsPressed()); }
|
|
//--- Состояние полосы прокрутки (свободно/в режиме перемещения ползунка)
|
|
void State(const bool scroll_state) { m_scroll_state=scroll_state; }
|
|
bool State(void) const { return(m_scroll_state); }
|
|
//--- Текущая позиция ползунка
|
|
void CurrentPos(const int pos) { m_current_pos=pos; }
|
|
int CurrentPos(void) const { return(m_current_pos); }
|
|
//--- Инициализация новыми значениями
|
|
void Reinit(const int items_total,const int visible_items_total);
|
|
//--- Изменение размера ползунка по новым условиям
|
|
void ChangeThumbSize(const int items_total,const int visible_items_total);
|
|
//--- Необходимость показа полосы прокрутки
|
|
bool IsScroll(void) const { return(m_items_total>m_visible_items_total); }
|
|
//---
|
|
protected:
|
|
//--- Текущий цвет ползунка
|
|
uint ThumbColorCurrent(void);
|
|
//--- Проверка фокуса над ползунком
|
|
bool CheckThumbFocus(const int x,const int y);
|
|
//--- Определяет область зажатия левой кнопки мыши
|
|
void CheckMouseButtonState(void);
|
|
//--- Обнуление переменных
|
|
void ZeroThumbVariables(void);
|
|
//--- Расчёт длины ползунка полосы прокрутки
|
|
bool CalculateThumbSize(void);
|
|
//--- Расчёт границ ползунка полосы прокрутки
|
|
void CalculateThumbBoundaries(int &x1,int &y1,int &x2,int &y2);
|
|
//---
|
|
public:
|
|
//--- Управление
|
|
virtual void Show(void);
|
|
virtual void Hide(void);
|
|
virtual void Delete(void);
|
|
//--- Рисует элемент
|
|
virtual void Draw(void);
|
|
//---
|
|
private:
|
|
//--- Рисует фон
|
|
virtual void DrawThumb(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CScroll::CScroll(void) : m_current_pos(0),
|
|
m_area_width(15),
|
|
m_area_length(0),
|
|
m_inc_file(""),
|
|
m_inc_file_locked(""),
|
|
m_inc_file_pressed(""),
|
|
m_dec_file(""),
|
|
m_dec_file_locked(""),
|
|
m_dec_file_pressed(""),
|
|
m_thumb_focus(false),
|
|
m_is_crossing_thumb_border(false),
|
|
m_thumb_x(0),
|
|
m_thumb_y(0),
|
|
m_thumb_width(0),
|
|
m_thumb_length(0),
|
|
m_thumb_min_length(15),
|
|
m_thumb_size_fixing(0),
|
|
m_thumb_point_fixing(0),
|
|
m_thumb_color(C'205,205,205'),
|
|
m_thumb_color_hover(C'166,166,166'),
|
|
m_thumb_color_pressed(C'96,96,96')
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CScroll::~CScroll(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт полосу прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
bool CScroll::CreateScroll(const int x_gap,const int y_gap,const int items_total,const int visible_items_total)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return(false);
|
|
//--- Выйти, если производится попытка использовать базовый класс полосы прокрутки
|
|
if(CElementBase::ClassName()=="")
|
|
{
|
|
::Print(__FUNCTION__," > Используйте производные классы полосы прокрутки (CScrollV или CScrollH).");
|
|
return(false);
|
|
}
|
|
//--- Инициализация свойств
|
|
InitializeProperties(x_gap,y_gap,items_total,visible_items_total);
|
|
//--- Создание элемента
|
|
if(!CreateCanvas())
|
|
return(false);
|
|
if(!CreateScrollButton(m_button_inc,0))
|
|
return(false);
|
|
if(!CreateScrollButton(m_button_dec,1))
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация свойств |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::InitializeProperties(const int x_gap,const int y_gap,
|
|
const int items_total,const int visible_items_total)
|
|
{
|
|
m_x =CElement::CalculateX(x_gap);
|
|
m_y =CElement::CalculateY(y_gap);
|
|
m_area_width =(CElementBase::ClassName()=="CScrollV")? CElementBase::XSize() : CElementBase::YSize();
|
|
m_area_length =(CElementBase::ClassName()=="CScrollV")? CElementBase::YSize() : CElementBase::XSize();
|
|
m_items_total =(items_total<1)? 1 : items_total;
|
|
m_visible_items_total =(visible_items_total>0)? visible_items_total : 1;
|
|
m_thumb_width =m_area_width;
|
|
m_thumb_steps_total =(IsScroll())? m_items_total-m_visible_items_total : 1;
|
|
m_back_color =(m_back_color!=clrNONE)? m_back_color : C'240,240,240';
|
|
//--- Отступы от крайней точки
|
|
CElementBase::XGap(x_gap);
|
|
CElementBase::YGap(y_gap);
|
|
//--- Рассчитаем размер полосы прокрутки
|
|
CalculateThumbSize();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт объект для рисования |
|
|
//+------------------------------------------------------------------+
|
|
bool CScroll::CreateCanvas(void)
|
|
{
|
|
//--- Формирование имени объекта
|
|
string name=CElementBase::ElementName((CElementBase::ClassName()=="CScrollV")? "scrollv" : "scrollh");
|
|
//--- Создание объекта
|
|
if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size))
|
|
return(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Создаёт переключатель скролла вверх или влево |
|
|
//+------------------------------------------------------------------+
|
|
bool CScroll::CreateScrollButton(CButton &button_obj,const int index)
|
|
{
|
|
//--- Сохраним указатель на главный элемент
|
|
button_obj.MainPointer(this);
|
|
//--- Координаты
|
|
int x=0,y=0;
|
|
//--- Файлы
|
|
string file="",file_locked="",file_pressed="";
|
|
//--- Кнопка вверх или влево
|
|
if(index==0)
|
|
{
|
|
//--- Установка свойств с учётом типа скролла
|
|
if(CElementBase::ClassName()=="CScrollV")
|
|
{
|
|
file=(m_inc_file=="")? (string)RESOURCE_SCROLL_UP_BLACK : m_inc_file;
|
|
file_locked=(m_inc_file_locked=="")? (string)RESOURCE_SCROLL_UP_BLACK : m_inc_file_locked;
|
|
file_pressed=(m_inc_file_pressed=="")? (string)RESOURCE_SCROLL_UP_WHITE : m_inc_file_pressed;
|
|
}
|
|
else
|
|
{
|
|
file=(m_inc_file=="")? (string)RESOURCE_SCROLL_LEFT_BLACK : m_inc_file;
|
|
file_locked=(m_inc_file_locked=="")? (string)RESOURCE_SCROLL_LEFT_BLACK : m_inc_file_locked;
|
|
file_pressed=(m_inc_file_pressed=="")? (string)RESOURCE_SCROLL_LEFT_WHITE : m_inc_file_pressed;
|
|
}
|
|
//--- Индекс элемента
|
|
button_obj.Index(m_index*2);
|
|
}
|
|
//--- Кнопка вниз или вправо
|
|
else
|
|
{
|
|
//--- Установка свойств с учётом типа скролла
|
|
if(CElementBase::ClassName()=="CScrollV")
|
|
{
|
|
x=0; y=m_thumb_width;
|
|
file=(m_dec_file=="")? (string)RESOURCE_SCROLL_DOWN_BLACK : m_dec_file;
|
|
file_locked=(m_dec_file_locked=="")? (string)RESOURCE_SCROLL_DOWN_BLACK : m_dec_file_locked;
|
|
file_pressed=(m_dec_file_pressed=="")? (string)RESOURCE_SCROLL_DOWN_WHITE : m_dec_file_pressed;
|
|
button_obj.AnchorBottomWindowSide(true);
|
|
}
|
|
else
|
|
{
|
|
x=m_thumb_width; y=0;
|
|
file=(m_dec_file=="")? (string)RESOURCE_SCROLL_RIGHT_BLACK : m_dec_file;
|
|
file_locked=(m_dec_file_locked=="")? (string)RESOURCE_SCROLL_RIGHT_BLACK : m_dec_file_locked;
|
|
file_pressed=(m_dec_file_pressed=="")? (string)RESOURCE_SCROLL_RIGHT_WHITE : m_dec_file_pressed;
|
|
button_obj.AnchorRightWindowSide(true);
|
|
}
|
|
//--- Индекс элемента
|
|
button_obj.Index(m_index*2+1);
|
|
}
|
|
//--- Свойства
|
|
button_obj.NamePart("scroll_button");
|
|
button_obj.Alpha(m_alpha);
|
|
button_obj.XSize(15);
|
|
button_obj.YSize(15);
|
|
button_obj.IconXGap(0);
|
|
button_obj.IconYGap(0);
|
|
button_obj.TwoState(true);
|
|
button_obj.BackColor(m_back_color);
|
|
button_obj.BackColorHover(C'218,218,218');
|
|
button_obj.BackColorLocked(clrLightGray);
|
|
button_obj.BackColorPressed(m_thumb_color_pressed);
|
|
button_obj.BorderColor(m_back_color);
|
|
button_obj.BorderColorHover(C'218,218,218');
|
|
button_obj.BorderColorLocked(clrLightGray);
|
|
button_obj.BorderColorPressed(m_thumb_color_pressed);
|
|
button_obj.IconFile((uint)file);
|
|
button_obj.IconFileLocked((uint)file_locked);
|
|
button_obj.CElement::IconFilePressed((uint)file_pressed);
|
|
button_obj.CElement::IconFilePressedLocked((uint)file_locked);
|
|
button_obj.IsDropdown(CElementBase::IsDropdown());
|
|
//--- Создадим элемент управления
|
|
if(!button_obj.CreateButton("",x,y))
|
|
return(false);
|
|
//--- Добавить элемент в массив
|
|
CElement::AddToArray(button_obj);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Текущий цвет ползунка |
|
|
//+------------------------------------------------------------------+
|
|
uint CScroll::ThumbColorCurrent(void)
|
|
{
|
|
//--- Определим цвет ползунка
|
|
color clr=(m_scroll_state)? m_thumb_color_pressed : m_thumb_color;
|
|
//--- Если курсор мыши в зоне ползунка полосы прокрутки
|
|
if(m_thumb_focus)
|
|
{
|
|
//--- Если левая кнопка мыши отжата
|
|
if(m_clamping_area_mouse==NOT_PRESSED)
|
|
clr=m_thumb_color_hover;
|
|
//--- Левая кнопка мыши нажата на ползунке
|
|
else if(m_clamping_area_mouse==PRESSED_INSIDE)
|
|
clr=m_thumb_color_pressed;
|
|
}
|
|
//--- Если курсор вне зоны полосы прокрутки
|
|
else
|
|
{
|
|
//--- Левая кнопка мыши отжата
|
|
if(m_clamping_area_mouse==NOT_PRESSED)
|
|
clr=m_thumb_color;
|
|
}
|
|
//---
|
|
return(::ColorToARGB(clr,m_alpha));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка фокуса над ползунком |
|
|
//+------------------------------------------------------------------+
|
|
bool CScroll::CheckThumbFocus(const int x,const int y)
|
|
{
|
|
//--- Проверка фокуса над ползунком
|
|
if(CElementBase::ClassName()=="CScrollV")
|
|
{
|
|
m_thumb_focus=(x>m_thumb_x && x<m_thumb_x+m_thumb_width &&
|
|
y>m_thumb_y && y<m_thumb_y+m_thumb_length);
|
|
}
|
|
else
|
|
{
|
|
m_thumb_focus=(x>m_thumb_x && x<m_thumb_x+m_thumb_length &&
|
|
y>m_thumb_y && y<m_thumb_y+m_thumb_width);
|
|
}
|
|
//--- Если это момент пересечения границ элемента
|
|
if((m_thumb_focus && !m_is_crossing_thumb_border) || (!m_thumb_focus && m_is_crossing_thumb_border))
|
|
{
|
|
m_is_crossing_thumb_border=m_thumb_focus;
|
|
//---
|
|
if(!CScroll::State())
|
|
{
|
|
int x1=0,y1=0,x2=0,y2=0;
|
|
CalculateThumbBoundaries(x1,y1,x2,y2);
|
|
//--- Нарисовать прямоугольник с заливкой
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,ThumbColorCurrent());
|
|
m_canvas.Update();
|
|
}
|
|
return(true);
|
|
}
|
|
//---
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Определяет область зажатия левой кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::CheckMouseButtonState(void)
|
|
{
|
|
//--- Если левая кнопки мыши отжата
|
|
if(!m_mouse.LeftButtonState())
|
|
{
|
|
//--- Обнулим переменные
|
|
ZeroThumbVariables();
|
|
return;
|
|
}
|
|
//--- Если кнопка нажата
|
|
else
|
|
{
|
|
//--- Выйдем, если кнопка уже нажата в какой-либо области
|
|
if(m_clamping_area_mouse!=NOT_PRESSED)
|
|
return;
|
|
//--- Вне области ползунка полосы прокрутки
|
|
if(!m_thumb_focus)
|
|
m_clamping_area_mouse=PRESSED_OUTSIDE;
|
|
//--- В области ползунка полосы прокрутки
|
|
else
|
|
{
|
|
m_scroll_state =true;
|
|
m_clamping_area_mouse =PRESSED_INSIDE;
|
|
//--- Перерисовать элемент
|
|
Update(true);
|
|
//--- Если элемент не выпадающий
|
|
if(!CElementBase::IsDropdown())
|
|
{
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),0,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обнуление переменных связанных с перемещением ползунка |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::ZeroThumbVariables(void)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return;
|
|
//--- Выйти, если кнопка уже отжата
|
|
if(m_clamping_area_mouse==NOT_PRESSED)
|
|
return;
|
|
//--- Если элемент не выпадающий
|
|
if(!CElementBase::IsDropdown() && m_clamping_area_mouse==PRESSED_INSIDE)
|
|
{
|
|
//--- Отправим сообщение на определение доступных элементов
|
|
::EventChartCustom(m_chart_id,ON_SET_AVAILABLE,CElementBase::Id(),1,"");
|
|
//--- Отправим сообщение об изменении в графическом интерфейсе
|
|
::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0,"");
|
|
}
|
|
//--- Обнулить переменные
|
|
m_scroll_state =false;
|
|
m_thumb_size_fixing =0;
|
|
m_clamping_area_mouse =NOT_PRESSED;
|
|
//--- Перерисовать элемент
|
|
Update(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменение размера ползунка по новым условиям |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::ChangeThumbSize(const int items_total,const int visible_items_total)
|
|
{
|
|
m_items_total =items_total;
|
|
m_visible_items_total =visible_items_total;
|
|
//--- Выйдем, если количество элементов списка не больше количества видимой части списка
|
|
if(!IsScroll())
|
|
return;
|
|
//--- Получим количество шагов для ползунка
|
|
m_thumb_steps_total=items_total-visible_items_total;
|
|
//--- Получим размер полосы прокрутки
|
|
if(!CalculateThumbSize())
|
|
return;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт размера полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
bool CScroll::CalculateThumbSize(void)
|
|
{
|
|
//--- Разница в процентах между общим количеством пунктов и видимым
|
|
double percentage_difference=1-(double)(m_items_total-m_visible_items_total)/m_items_total;
|
|
//--- Рассчитаем размер шага ползунка
|
|
uint bg_length=(m_class_name=="CScrollV")? m_y_size-(m_thumb_width*2) : m_x_size-(m_thumb_width*2);
|
|
m_thumb_step_size=(double)(bg_length-(bg_length*percentage_difference))/m_thumb_steps_total;
|
|
//--- Рассчитаем размер рабочей области для перемещения ползунка
|
|
double work_area=m_thumb_step_size*m_thumb_steps_total;
|
|
//--- Если размер рабочей области меньше размера всей области, получим размер ползунка, иначе установим минимальный размер
|
|
double thumb_size=(work_area<bg_length)? bg_length-work_area+m_thumb_step_size : m_thumb_min_length;
|
|
//--- Проверка размера ползунка с учётом приведения типа
|
|
m_thumb_length=((int)thumb_size<m_thumb_min_length)? m_thumb_min_length :(int)thumb_size;
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт границ ползунка полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::CalculateThumbBoundaries(int &x1,int &y1,int &x2,int &y2)
|
|
{
|
|
if(CElementBase::ClassName()=="CScrollV")
|
|
{
|
|
x1 =0;
|
|
y1 =(m_thumb_y>0) ? m_thumb_y : m_thumb_width;
|
|
x2 =x1+m_thumb_width;
|
|
y2 =y1+m_thumb_length;
|
|
}
|
|
else
|
|
{
|
|
x1 =(m_thumb_x>0) ? m_thumb_x : m_thumb_width;
|
|
y1 =0;
|
|
x2 =x1+m_thumb_length;
|
|
y2 =y1+m_thumb_width;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация новыми значениями |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::Reinit(const int items_total,const int visible_items_total)
|
|
{
|
|
m_items_total =(items_total>0)? items_total : 1;
|
|
m_visible_items_total =(visible_items_total>items_total)? items_total : visible_items_total;
|
|
m_thumb_steps_total =m_items_total-m_visible_items_total+1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Показывает элемент |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::Show(void)
|
|
{
|
|
//--- Выйти, если (1) элемент уже видим или (2) его не нужно показывать
|
|
if(CElementBase::IsVisible() || !IsScroll())
|
|
return;
|
|
//--- Состояние видимости
|
|
CElementBase::IsVisible(true);
|
|
//--- Обновить положение объектов
|
|
Moving();
|
|
//--- Показать объекты
|
|
::ObjectSetInteger(m_chart_id,m_canvas.ChartObjectName(),OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS);
|
|
m_button_inc.Show();
|
|
m_button_dec.Show();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Скрывает элемент |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::Hide(void)
|
|
{
|
|
::ObjectSetInteger(m_chart_id,m_canvas.ChartObjectName(),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
|
|
m_button_inc.Hide();
|
|
m_button_dec.Hide();
|
|
//--- Состояние видимости
|
|
CElementBase::IsVisible(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Удаление |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::Delete(void)
|
|
{
|
|
//--- Удаление объектов
|
|
m_canvas.Destroy();
|
|
//--- Инициализация переменных значениями по умолчанию
|
|
m_thumb_x=0;
|
|
m_thumb_y=0;
|
|
CurrentPos(0);
|
|
CElementBase::IsVisible(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует элемент |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::Draw(void)
|
|
{
|
|
//--- Нарисовать фон
|
|
CElement::DrawBackground();
|
|
//--- Нарисовать ползунок
|
|
DrawThumb();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рисует ползунок полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScroll::DrawThumb(void)
|
|
{
|
|
//--- Координаты
|
|
int x1=0,y1=0,x2=0,y2=0;
|
|
//--- Расчёт границ ползунка
|
|
CalculateThumbBoundaries(x1,y1,x2,y2);
|
|
//--- Сохраним координаты ползунка (левый верхний угол)
|
|
m_thumb_x=x1;
|
|
m_thumb_y=y1;
|
|
//--- Нарисовать прямоугольник с заливкой
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,ThumbColorCurrent());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для управления вертикальной полосой прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
class CScrollV : public CScroll
|
|
{
|
|
public:
|
|
CScrollV(void);
|
|
~CScrollV(void);
|
|
//--- Управление ползунком
|
|
bool ScrollBarControl(void);
|
|
//--- Перемещает ползунок на указанную позицию
|
|
void MovingThumb(const int pos=WRONG_VALUE);
|
|
//--- Установить новую координату для полосы прокрутки
|
|
void XDistance(const int x);
|
|
//--- Изменить длину полосы прокрутки
|
|
void ChangeYSize(const int height);
|
|
//--- Обработка нажатия на кнопках полосы прокрутки
|
|
bool OnClickScrollInc(const int id=WRONG_VALUE,const int index=WRONG_VALUE);
|
|
bool OnClickScrollDec(const int id=WRONG_VALUE,const int index=WRONG_VALUE);
|
|
//---
|
|
private:
|
|
//--- Процесс перемещения ползунка
|
|
bool OnDragThumb(const int y);
|
|
//--- Обновление положения ползунка
|
|
void UpdateThumb(const int new_y_point);
|
|
//--- Расчёт координаты Y ползунка
|
|
void CalculateThumbY(void);
|
|
//--- Корректирует номер позиции ползунка
|
|
void CalculateThumbPos(void);
|
|
//--- Быстрая перерисовка ползунка полосы прокрутки
|
|
void RedrawThumb(const int y);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CScrollV::CScrollV(void)
|
|
{
|
|
//--- Сохраним имя класса элемента в базовом классе
|
|
CElementBase::ClassName(CLASS_NAME);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CScrollV::~CScrollV(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Управление ползунком |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollV::ScrollBarControl(void)
|
|
{
|
|
//--- Выйти, если (1) нет указателя на главный элемент или (2) элемент скрыт
|
|
if(!CElement::CheckMainPointer() || !CElementBase::IsVisible())
|
|
return(false);
|
|
//--- Выйти, если родитель отключен другим элементом
|
|
if(!m_main.CElementBase::IsAvailable())
|
|
return(false);
|
|
//--- Проверка фокуса над ползунком
|
|
int x =m_mouse.RelativeX(m_canvas);
|
|
int y =m_mouse.RelativeY(m_canvas);
|
|
CheckThumbFocus(x,y);
|
|
//--- Проверим и запомним состояние кнопки мыши
|
|
CScroll::CheckMouseButtonState();
|
|
//--- Если управление передано полосе прокрутки, определим положение ползунка
|
|
if(CScroll::State())
|
|
{
|
|
//--- Если ползунок переместили
|
|
if(OnDragThumb(y))
|
|
{
|
|
//--- Изменяет номер позиции ползунка
|
|
CalculateThumbPos();
|
|
return(true);
|
|
}
|
|
}
|
|
//---
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещает ползунок на указанную позицию |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::MovingThumb(const int pos=WRONG_VALUE)
|
|
{
|
|
//--- Выйти, если полоса прокрутки не нужна
|
|
if(!IsScroll())
|
|
return;
|
|
//--- Для проверки позиции ползунка
|
|
uint check_pos=0;
|
|
//--- Скорректируем позицию в случае выхода из диапазона
|
|
if(pos<0 || pos>m_items_total-m_visible_items_total)
|
|
check_pos=m_items_total-m_visible_items_total;
|
|
else
|
|
check_pos=pos;
|
|
//--- Запомним позицию ползунка
|
|
CScroll::CurrentPos(check_pos);
|
|
//--- Расчёт и установка координаты Y ползунка полосы прокрутки
|
|
CalculateThumbY();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт и установка координаты Y ползунка полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::CalculateThumbY(void)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return;
|
|
//--- Определим текущую координату Y ползунка
|
|
int scroll_thumb_y=int(m_thumb_width+(CurrentPos()*m_thumb_step_size));
|
|
//--- Если выходим за пределы рабочей области вверх
|
|
if(scroll_thumb_y<=m_thumb_width)
|
|
scroll_thumb_y=m_thumb_width;
|
|
//--- Если выходим за пределы рабочей области вниз
|
|
if(scroll_thumb_y+m_thumb_length>=m_y_size-m_thumb_width ||
|
|
CScroll::CurrentPos()>=m_thumb_steps_total-1)
|
|
{
|
|
scroll_thumb_y=int(m_y_size-m_thumb_width-m_thumb_length);
|
|
}
|
|
//--- Обновим координату и отступ по оси Y
|
|
m_thumb_y=scroll_thumb_y;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменение координаты X элемента |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::XDistance(const int x)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return;
|
|
//--- Обновим координату X элемента...
|
|
CElementBase::X(CElement::CalculateX(x));
|
|
CElementBase::XGap(x);
|
|
m_canvas.X(x);
|
|
//--- Установим координату и отступ
|
|
::ObjectSetInteger(m_chart_id,m_canvas.ChartObjectName(),OBJPROP_XDISTANCE,x);
|
|
m_canvas.XGap(x);
|
|
//--- Переместить объекты
|
|
Moving();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменить длину полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::ChangeYSize(const int height)
|
|
{
|
|
//--- Координаты и размеры
|
|
int y=0,y_size=0;
|
|
//--- Изменить ширину элемента и фона
|
|
CElementBase::YSize(height);
|
|
m_canvas.YSize(height);
|
|
m_canvas.Resize(m_x_size,height);
|
|
//--- Скорректировать положение кнопки декремента
|
|
m_button_dec.Moving();
|
|
//--- Рассчитаем и установим размеры объектов полосы прокрутки
|
|
CalculateThumbSize();
|
|
//--- Корректировка положения ползунка
|
|
if(m_thumb_y+m_thumb_length>=m_y_size-m_thumb_length || m_thumb_y<m_thumb_width)
|
|
{
|
|
CalculateThumbY();
|
|
CalculateThumbPos();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка нажатия на кнопке вверх/влево |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollV::OnClickScrollInc(const int id=WRONG_VALUE,const int index=WRONG_VALUE)
|
|
{
|
|
//--- Проверить идентификатор и индекс элемента, если был внешний вызов
|
|
uint check_id =(id!=WRONG_VALUE)? id : CElementBase::Id();
|
|
uint check_index =(index!=WRONG_VALUE)? index : CElementBase::Index();
|
|
//--- Выйти, если значения не совпадают
|
|
if(check_id!=m_button_inc.Id() || check_index!=m_button_inc.Index())
|
|
return(false);
|
|
//--- Выйдем, если (1) сейчас активен или (2) кол-во шагов неопределено
|
|
if(CScroll::State() || m_thumb_steps_total<1)
|
|
return(false);
|
|
//--- Уменьшим номер позиции полосы прокрутки
|
|
if(CScroll::CurrentPos()>0)
|
|
CScroll::m_current_pos--;
|
|
//--- Расчёт координты Y полосы прокрутки
|
|
CalculateThumbY();
|
|
//--- Отожмём кнопку
|
|
m_button_inc.IsPressed(false);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка нажатия на кнопке вниз/вправо |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollV::OnClickScrollDec(const int id=WRONG_VALUE,const int index=WRONG_VALUE)
|
|
{
|
|
//--- Проверить идентификатор и индекс элемента, если был внешний вызов
|
|
uint check_id =(id!=WRONG_VALUE)? id : CElementBase::Id();
|
|
uint check_index =(index!=WRONG_VALUE)? index : CElementBase::Index();
|
|
//--- Выйти, если значения не совпадают
|
|
if(check_id!=m_button_dec.Id() || check_index!=m_button_dec.Index())
|
|
return(false);
|
|
//--- Выйдем, если (1) сейчас активен или (2) кол-во шагов неопределено
|
|
if(CScroll::State() || m_thumb_steps_total<1)
|
|
return(false);
|
|
//--- Увеличим номер позиции полосы прокрутки
|
|
if(CScroll::CurrentPos()<CScroll::m_thumb_steps_total-1)
|
|
CScroll::m_current_pos++;
|
|
//--- Расчёт координты Y полосы прокрутки
|
|
CalculateThumbY();
|
|
//--- Отожмём кнопку
|
|
m_button_dec.IsPressed(false);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещение ползунка |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollV::OnDragThumb(const int y)
|
|
{
|
|
//--- Для определения новой Y координаты
|
|
int new_y_point=0;
|
|
//--- Если полоса прокрутки неактивна, ...
|
|
if(!CScroll::State())
|
|
{
|
|
//--- ...обнулим вспомогательные переменные для перемещения ползунка
|
|
m_thumb_size_fixing =0;
|
|
m_thumb_point_fixing =0;
|
|
return(false);
|
|
}
|
|
//--- Если точка фиксации нулевая, то запомним текущую координату курсора
|
|
if(m_thumb_point_fixing==0)
|
|
m_thumb_point_fixing=y;
|
|
//--- Если значение расстояния от крайней точки ползунка до текущей координаты курсора нулевое, рассчитаем его
|
|
if(m_thumb_size_fixing==0)
|
|
m_thumb_size_fixing=m_thumb_y-y;
|
|
//--- Если в нажатом состоянии прошли порог вниз
|
|
if(y-m_thumb_point_fixing>0)
|
|
{
|
|
//--- Рассчитаем координату Y
|
|
new_y_point=y+m_thumb_size_fixing;
|
|
//--- Обновим положение ползунка
|
|
UpdateThumb(new_y_point);
|
|
return(true);
|
|
}
|
|
//--- Если в нажатом состоянии прошли порог вверх
|
|
if(y-m_thumb_point_fixing<0)
|
|
{
|
|
//--- Рассчитаем координату Y
|
|
new_y_point=y-::fabs(m_thumb_size_fixing);
|
|
//--- Обновим положение ползунка
|
|
UpdateThumb(new_y_point);
|
|
return(true);
|
|
}
|
|
//---
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обновление положения ползунка |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::UpdateThumb(const int new_y_point)
|
|
{
|
|
int y=new_y_point;
|
|
//--- Обнуление точки фиксации
|
|
m_thumb_point_fixing=0;
|
|
//--- Проверка на выход из рабочей области вниз и корректировка значений
|
|
if(new_y_point>m_y_size-m_thumb_width-m_thumb_length)
|
|
{
|
|
y=m_y_size-m_thumb_width-m_thumb_length;
|
|
CScroll::CurrentPos(int(m_thumb_steps_total-1));
|
|
}
|
|
//--- Проверка на выход из рабочей области вверх и корректировка значений
|
|
if(new_y_point<=m_thumb_width)
|
|
{
|
|
y=m_thumb_width;
|
|
CScroll::CurrentPos(0);
|
|
}
|
|
//--- Текущие координаты
|
|
RedrawThumb(y);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Корректирует номер позиции ползунка |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::CalculateThumbPos(void)
|
|
{
|
|
//--- Выйти, если шаг равен нулю
|
|
if(m_thumb_step_size==0)
|
|
return;
|
|
//--- Корректирует номер позиции полосы прокрутки
|
|
CScroll::CurrentPos(int((m_thumb_y-m_thumb_width+1)/m_thumb_step_size));
|
|
//--- Проверка на выход из рабочей области вниз/вверх
|
|
if(m_thumb_y+m_thumb_length>=m_y_size-m_thumb_width)
|
|
CScroll::CurrentPos(int(m_thumb_steps_total-1));
|
|
if(m_thumb_y<=m_thumb_width)
|
|
CScroll::CurrentPos(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Быстрая перерисовка ползунка полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollV::RedrawThumb(const int y)
|
|
{
|
|
//--- Текущие координаты
|
|
int x1=0,y1=0,x2=0,y2=0;
|
|
CalculateThumbBoundaries(x1,y1,x2,y2);
|
|
//--- Стереть текущее положение ползунка
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,m_back_color);
|
|
//--- Обновим координаты
|
|
m_thumb_y=y;
|
|
y2=y+m_thumb_length;
|
|
//--- Нарисовать новое положение ползунка
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,m_thumb_color_pressed);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для управления горизонтальной полосой прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
class CScrollH : public CScroll
|
|
{
|
|
public:
|
|
CScrollH(void);
|
|
~CScrollH(void);
|
|
//--- Управление ползунком
|
|
bool ScrollBarControl(void);
|
|
//--- Перемещает ползунок на указанную позицию
|
|
void MovingThumb(const int pos=WRONG_VALUE);
|
|
//--- Установить новую координату для полосы прокрутки
|
|
void YDistance(const int y);
|
|
//--- Изменить длину полосы прокрутки
|
|
void ChangeXSize(const int width);
|
|
//--- Обработка нажатия на кнопках полосы прокрутки
|
|
bool OnClickScrollInc(const int id=WRONG_VALUE,const int index=WRONG_VALUE);
|
|
bool OnClickScrollDec(const int id=WRONG_VALUE,const int index=WRONG_VALUE);
|
|
//---
|
|
private:
|
|
//--- Перемещение ползунка
|
|
bool OnDragThumb(const int x);
|
|
//--- Обновление положения ползунка
|
|
void UpdateThumb(const int new_x_point);
|
|
//--- Расчёт координаты X ползунка
|
|
void CalculateThumbX(void);
|
|
//--- Корректирует номер позиции ползунка
|
|
void CalculateThumbPos(void);
|
|
//--- Быстрая перерисовка ползунка полосы прокрутки
|
|
void RedrawThumb(const int x);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CScrollH::CScrollH(void)
|
|
{
|
|
//--- Сохраним имя класса элемента в базовом классе
|
|
CElementBase::ClassName(CLASS_NAME);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CScrollH::~CScrollH(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Управление скроллом |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollH::ScrollBarControl(void)
|
|
{
|
|
//--- Выйти, если (1) нет указателя на главный элемент или (2) элемент скрыт
|
|
if(!CElement::CheckMainPointer() || !CElementBase::IsVisible())
|
|
return(false);
|
|
//--- Выйти, если родитель отключен другим элементом
|
|
if(!m_main.CElementBase::IsAvailable())
|
|
return(false);
|
|
//--- Проверка фокуса над ползунком
|
|
int x=m_mouse.RelativeX(m_canvas);
|
|
int y=m_mouse.RelativeY(m_canvas);
|
|
CheckThumbFocus(x,y);
|
|
//--- Проверим и запомним состояние кнопки мыши
|
|
CScroll::CheckMouseButtonState();
|
|
//--- Если управление передано полосе прокрутки, определим положение ползунка
|
|
if(CScroll::State())
|
|
{
|
|
//--- Если ползунок переместили
|
|
if(OnDragThumb(x))
|
|
{
|
|
//--- Изменяет номер позиции ползунка
|
|
CalculateThumbPos();
|
|
return(true);
|
|
}
|
|
}
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещает ползунок на указанную позицию |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::MovingThumb(const int pos=WRONG_VALUE)
|
|
{
|
|
//--- Выйти, если полоса прокрутки не нужна
|
|
if(!IsScroll())
|
|
return;
|
|
//--- Для проверки позиции ползунка
|
|
uint check_pos=0;
|
|
//--- Скорректируем позицию в случае выхода из диапазона
|
|
if(pos<0 || pos>m_items_total-m_visible_items_total)
|
|
check_pos=m_items_total-m_visible_items_total;
|
|
else
|
|
check_pos=pos;
|
|
//--- Запомним позицию ползунка
|
|
CScroll::CurrentPos(check_pos);
|
|
//--- Расчёт и установка координаты Y ползунка полосы прокрутки
|
|
CalculateThumbX();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Расчёт координаты X ползунка |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::CalculateThumbX(void)
|
|
{
|
|
//--- Определим текущую координату X ползунка
|
|
double scroll_thumb_x=m_thumb_width+(CurrentPos()*m_thumb_step_size);
|
|
//--- Если выходим за пределы рабочей области влево
|
|
if(scroll_thumb_x<=m_thumb_width)
|
|
{
|
|
scroll_thumb_x=m_thumb_width;
|
|
}
|
|
//--- Если выходим за пределы рабочей области вправо
|
|
if(scroll_thumb_x+m_thumb_length>=m_x_size-m_thumb_width ||
|
|
CScroll::CurrentPos()>=m_thumb_steps_total-1)
|
|
{
|
|
scroll_thumb_x=int(m_x_size-m_thumb_width-m_thumb_length);
|
|
}
|
|
//--- Обновим координату и отступ по оси X
|
|
m_thumb_x=(int)scroll_thumb_x;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменение координаты Y элемента |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::YDistance(const int y)
|
|
{
|
|
//--- Выйти, если нет указателя на главный элемент
|
|
if(!CElement::CheckMainPointer())
|
|
return;
|
|
//--- Обновим координату Y элемента...
|
|
CElementBase::Y(CElement::CalculateY(y));
|
|
CElementBase::YGap(y);
|
|
//--- ...и всех объектов полосы прокрутки
|
|
m_canvas.Y(y);
|
|
m_thumb_y=y;
|
|
//--- Установим координату объектам
|
|
::ObjectSetInteger(m_chart_id,m_canvas.ChartObjectName(),OBJPROP_YDISTANCE,y);
|
|
//--- Обновим отступы у всех объектов элемента
|
|
int y_gap=CElement::CalculateYGap(y);
|
|
m_canvas.YGap(CElement::CalculateYGap(y));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменить длину полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::ChangeXSize(const int width)
|
|
{
|
|
//--- Координаты и размеры
|
|
int x=0,x_size=width-1;
|
|
//--- Изменить ширину элемента и фона
|
|
CElementBase::XSize(x_size);
|
|
m_canvas.XSize(x_size);
|
|
m_canvas.Resize(x_size,m_y_size);
|
|
//--- Скорректировать положение кнопки декремента
|
|
m_button_dec.Moving();
|
|
//--- Рассчитаем и установим размеры объектов полосы прокрутки
|
|
CalculateThumbSize();
|
|
//--- Корректировка положения ползунка
|
|
if(m_thumb_x+m_thumb_length>=m_x_size-m_thumb_length || m_thumb_x<m_thumb_width)
|
|
{
|
|
CalculateThumbX();
|
|
CalculateThumbPos();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Нажатие на переключателе влево |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollH::OnClickScrollInc(const int id=WRONG_VALUE,const int index=WRONG_VALUE)
|
|
{
|
|
//--- Проверить идентификатор и индекс элемента, если был внешний вызов
|
|
uint check_id =(id!=WRONG_VALUE)? id : CElementBase::Id();
|
|
uint check_index =(index!=WRONG_VALUE)? index : CElementBase::Index();
|
|
//--- Выйти, если значения не совпадают
|
|
if(check_id!=m_button_inc.Id() || check_index!=m_button_inc.Index())
|
|
return(false);
|
|
//--- Выйдем, если (1) сейчас активен или (2) кол-во шагов неопределено
|
|
if(CScroll::State() || m_thumb_steps_total<1)
|
|
return(false);
|
|
//--- Уменьшим номер позиции полосы прокрутки
|
|
if(CScroll::CurrentPos()>0)
|
|
CScroll::m_current_pos--;
|
|
//--- Расчёт координты X полосы прокрутки
|
|
CalculateThumbX();
|
|
//--- Отожмём кнопку
|
|
m_button_inc.IsPressed(false);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Нажатие на переключателе вправо |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollH::OnClickScrollDec(const int id=WRONG_VALUE,const int index=WRONG_VALUE)
|
|
{
|
|
//--- Проверить идентификатор и индекс элемента, если был внешний вызов
|
|
uint check_id =(id!=WRONG_VALUE)? id : CElementBase::Id();
|
|
uint check_index =(index!=WRONG_VALUE)? index : CElementBase::Index();
|
|
//--- Выйти, если значения не совпадают
|
|
if(check_id!=m_button_inc.Id() || check_index!=m_button_dec.Index())
|
|
return(false);
|
|
//--- Выйдем, если (1) сейчас активен или (2) кол-во шагов неопределено
|
|
if(CScroll::State() || m_thumb_steps_total<1)
|
|
return(false);
|
|
//--- Увеличим номер позиции полосы прокрутки
|
|
if(CScroll::CurrentPos()<CScroll::m_thumb_steps_total-1)
|
|
CScroll::m_current_pos++;
|
|
//--- Расчёт координаты X полосы прокрутки
|
|
CalculateThumbX();
|
|
//--- Отожмём кнопку
|
|
m_button_dec.IsPressed(false);
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещение ползунка |
|
|
//+------------------------------------------------------------------+
|
|
bool CScrollH::OnDragThumb(const int x)
|
|
{
|
|
//--- Для определения новой X координаты
|
|
int new_x_point=0;
|
|
//--- Если полоса прокрутки неактивна, ...
|
|
if(!CScroll::State())
|
|
{
|
|
//--- ...обнулим вспомогательные переменные для перемещения ползунка
|
|
CScroll::m_thumb_size_fixing =0;
|
|
CScroll::m_thumb_point_fixing =0;
|
|
return(false);
|
|
}
|
|
//--- Если точка фиксации нулевая, то запомним текущую координаты курсора
|
|
if(CScroll::m_thumb_point_fixing==0)
|
|
CScroll::m_thumb_point_fixing=x;
|
|
//--- Если значение расстояния от крайней точки ползунка до текущей координаты курсора нулевое, рассчитаем его
|
|
if(CScroll::m_thumb_size_fixing==0)
|
|
CScroll::m_thumb_size_fixing=m_thumb_x-x;
|
|
//--- Если в нажатом состоянии прошли порог вправо
|
|
if(x-CScroll::m_thumb_point_fixing>0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x+CScroll::m_thumb_size_fixing;
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateThumb(new_x_point);
|
|
return(true);
|
|
}
|
|
//--- Если в нажатом состоянии прошли порог влево
|
|
if(x-CScroll::m_thumb_point_fixing<0)
|
|
{
|
|
//--- Рассчитаем координату X
|
|
new_x_point=x-::fabs(CScroll::m_thumb_size_fixing);
|
|
//--- Обновление положения полосы прокрутки
|
|
UpdateThumb(new_x_point);
|
|
return(true);
|
|
}
|
|
//---
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обновление положения полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::UpdateThumb(const int new_x_point)
|
|
{
|
|
int x=new_x_point;
|
|
//--- Обнуление точки фиксации
|
|
CScroll::m_thumb_point_fixing=0;
|
|
//--- Проверка на выход из рабочей области вправо и корректировка значений
|
|
if(new_x_point>m_x_size-m_thumb_width-m_thumb_length)
|
|
{
|
|
x=m_x_size-m_thumb_width-m_thumb_length;
|
|
CScroll::CurrentPos(0);
|
|
}
|
|
//--- Проверка на выход из рабочей области влево и корректировка значений
|
|
if(new_x_point<=m_thumb_width)
|
|
{
|
|
x=m_thumb_width;
|
|
CScroll::CurrentPos(int(m_thumb_steps_total));
|
|
}
|
|
//--- Текущие координаты
|
|
RedrawThumb(x);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Корректирует номер позиции ползунка |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::CalculateThumbPos(void)
|
|
{
|
|
//--- Выйти, если шаг равен нулю
|
|
if(CScroll::m_thumb_step_size==0)
|
|
return;
|
|
//--- Корректирует номер позиции полосы прокрутки
|
|
double pos=(m_thumb_x-m_thumb_width)/m_thumb_step_size;
|
|
CScroll::CurrentPos((int)::MathCeil(pos));
|
|
//--- Проверка на выход из рабочей области влево/вправо
|
|
if(m_thumb_x+m_thumb_length>=m_x_size-m_thumb_width-1)
|
|
CScroll::CurrentPos(int(m_thumb_steps_total-1));
|
|
if(m_thumb_x<m_thumb_width)
|
|
CScroll::CurrentPos(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Быстрая перерисовка ползунка полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
void CScrollH::RedrawThumb(const int x)
|
|
{
|
|
//--- Текущие координаты
|
|
int x1=0,y1=0,x2=0,y2=0;
|
|
CalculateThumbBoundaries(x1,y1,x2,y2);
|
|
//--- Стереть текущее положение ползунка
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,m_back_color);
|
|
//--- Обновим координаты
|
|
m_thumb_x=x;
|
|
x2=x+m_thumb_length;
|
|
//--- Нарисовать новое положение ползунка
|
|
m_canvas.FillRectangle(x1,y1,x2-1,y2-1,m_thumb_color_pressed);
|
|
}
|
|
//+------------------------------------------------------------------+
|