185 lines
6.1 KiB
MQL5
185 lines
6.1 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| Screen.mqh |
| |
//| Copyright 2025, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
#property copyright "Copyright 2025, MetaQuotes Ltd."
| |
#property link "https://www.mql5.com"
| |
#property version "1.00"
| |
| |
#include <Collection/DynamicArraylist.mqh>
| |
#include "ZoneObject.mqh"
| |
#include "ScreenListener.mqh"
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
class Screen
| |
{
| |
| |
private:
| |
long m_chart_id;
| |
int m_width, m_height;
| |
| |
long m_zoom;
| |
int m_fontSize;
| |
long m_min_zoom_to_keep_texts;
| |
bool m_min_zoom_reached_already;
| |
| |
datetime m_from_time, m_to_time;
| |
double m_min_price, m_max_price;
| |
| |
CArrayList<ZoneObject*>* objects;
| |
| |
| |
void UpdateViewBounds();
| |
void OnZoomChanged();
| |
void OnViewChanged();
| |
void OnMinZoomReached();
| |
| |
int FindExist(ZoneObject* zoneObject)
| |
{
| |
for(int i = objects.Size() - 1; i >= 0; i--)
| |
{
| |
ZoneObject* z = objects.At(i);
| |
| |
if(z.GetName() == zoneObject.GetName() && z.GetName() == zoneObject.GetName())
| |
{
| |
return i;
| |
}
| |
}
| |
return -1;
| |
| |
}
| |
int GetScaledFontSize(int baseSizePoints) const
| |
{
| |
return (int)MathMax(6.0, baseSizePoints - (m_zoom - 2));
| |
}
| |
| |
public:
| |
Screen(): m_fontSize(12), m_chart_id(ChartID()) { objects = new CArrayList<ZoneObject*>(); UpdateViewBounds(); }
| |
~Screen() {delete objects;}
| |
| |
void SetMinZoomForTexts(long zoomLevel) { m_min_zoom_to_keep_texts = zoomLevel; }
| |
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam);
| |
void AddLevel(ZoneObject* zoneObject);
| |
| |
void Render();
| |
};
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
| |
{
| |
if(id == CHARTEVENT_CHART_CHANGE)
| |
{
| |
| |
UpdateViewBounds();
| |
}
| |
}
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::AddLevel(ZoneObject* zoneObject)
| |
{
| |
if(zoneObject.GetSymbol() != _Symbol)
| |
{
| |
Print("Error Adding Levels");
| |
return;
| |
}
| |
| |
objects.Add(zoneObject);
| |
Render();
| |
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::Render()
| |
{
| |
UpdateViewBounds();
| |
bool boundsValid = (m_from_time < m_to_time && m_min_price < m_max_price);
| |
| |
for(int i = objects.Size() - 1; i >= 0; i--)
| |
{
| |
objects.At(i).UpdateDraw(ChartGetInteger(m_chart_id, CHART_SCALE), m_from_time, m_to_time, m_min_price, m_max_price, m_min_zoom_to_keep_texts);
| |
}
| |
}
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::OnZoomChanged()
| |
{
| |
if(!m_min_zoom_reached_already)
| |
{
| |
for(int i = objects.Size() - 1; i >= 0; i--)
| |
{
| |
objects.At(i).SetFontSize(GetScaledFontSize(m_fontSize));
| |
}
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::OnViewChanged()
| |
{
| |
Render();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void Screen::OnMinZoomReached()
| |
{
| |
for(int i = objects.Size() - 1; i >= 0; i--)
| |
{
| |
objects.At(i).DeleteAllText();
| |
}
| |
}
| |
//+------------------------------------------------------------------+
| |
//| View bounds update |
| |
//+------------------------------------------------------------------+
| |
void Screen::UpdateViewBounds()
| |
{
| |
long old_zoom = m_zoom;
| |
datetime old_from = m_from_time;
| |
datetime old_to = m_to_time;
| |
double old_minp = m_min_price;
| |
double old_maxp = m_max_price;
| |
| |
m_width = (int)ChartGetInteger(m_chart_id, CHART_WIDTH_IN_PIXELS);
| |
m_height = (int)ChartGetInteger(m_chart_id, CHART_HEIGHT_IN_PIXELS);
| |
m_zoom = ChartGetInteger(m_chart_id, CHART_SCALE);
| |
| |
int sub_window = 0;
| |
ChartXYToTimePrice(m_chart_id, 0, 0, sub_window, m_from_time, m_max_price);
| |
ChartXYToTimePrice(m_chart_id, m_width, m_height, sub_window, m_to_time, m_min_price);
| |
| |
if(m_zoom != old_zoom)
| |
{
| |
OnZoomChanged();
| |
bool below_threshold = (m_zoom < m_min_zoom_to_keep_texts);
| |
| |
if(below_threshold && !m_min_zoom_reached_already)
| |
{
| |
OnMinZoomReached();
| |
m_min_zoom_reached_already = true;
| |
| |
}
| |
else
| |
if(!below_threshold)
| |
{
| |
m_min_zoom_reached_already = false;
| |
// Render();
| |
}
| |
}
| |
| |
if(m_from_time != old_from || m_to_time != old_to ||
| |
m_min_price != old_minp || m_max_price != old_maxp)
| |
{
| |
OnViewChanged();
| |
}
| |
| |
}
| |
//+------------------------------------------------------------------+
|