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();
| |||
}
| |||
| |||
}
| |||
//+------------------------------------------------------------------+
|