//--- connette la libreria di elementi di controllo
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- costanti predefinite
#define X_PROPERTY_NAME_1 10 // coordinate x del nome della proprietà nella prima colonna
#define X_PROPERTY_VALUE_1 225 // coordinate x del valore della proprietà nella prima colonna
#define X_PROPERTY_NAME_2 345 // coordinate x del nome della proprietà nella seconda e terza colonna
#define X_PROPERTY_VALUE_2 550 // coordinate x del valore della proprietà nella seconda e terza colonna
#define X_BUTTON_1 285 // coordinate x del bottone nella prima colonna
#define X_BUTTON_2 700 // coordinate x del bottone nella seconda colonna
#define Y_PROPERTY_1 30 // coordinate y dell'inizio della prima e seconda colonna
#define Y_PROPERTY_2 286 // coordinate y dell'inizion della terza colonna
#define Y_DISTANCE 16 // distanza assiale y tra le linee
#define LAST_PROPERTY_NUMBER 111 // numero dell'ultima proprietà grafica
//--- parametri di input
input color InpFirstColor=clrDodgerBlue; // Colore delle righe dispari
input color InpSecondColor=clrGoldenrod; // Colore delle righe pari
//--- variabili ed arrays
CChartObjectLabel ExtLabelsName[]; // etichetta per visualizzazione dei nomi delle proprietà
CChartObjectLabel ExtLabelsValue[]; // etichetta per visualizzazione dei valori delle proprietà
CChartObjectButton ExtButtons[]; // bottoni
int ExtNumbers[]; // indici delle proprietà
string ExtNames[]; // nomi delle proprietà
uchar ExtDataTypes[]; // tipi di dato delle proprietà (integer, double, string)
uint ExtGroupTypes[]; // array che memorizza i dati sulla appartenenza delle proprietà ad uno dei gruppi
uchar ExtDrawTypes[]; // array che memorizza i dati sul tipo di proprietà display
double ExtMaxValue[]; // massimo valori delle proprietà che sono possibili quando si lavora con il pannello
double ExtMinValue[]; // minimi valori delle proprietà che sono possibili quando si lavora con il pannello
double ExtStep[]; // steps per il cambio delle proprietà
int ExtCount; // numero totale di tutte le proprietà
color ExtColors[2]; // array di colori per la visualizzazione delle righe
string ExtComments[2]; // array di commenti (per la priprietà CHART_COMMENT)
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione Indicatore Personalizzato |
//+--------------------------------------------------------------------------------+
int OnInit()
{
//--- visualizza un commento sul grafico
Comment("SomeComment");
//--- memorizza i colori nell'array per potervi passare tra essi in un secondo momento
ExtColors[0]=InpFirstColor;
ExtColors[1]=InpSecondColor;
//--- memorizza i commenti nell'array per potervi passare tra essi in un secondo momento
ExtComments[0]="FirstComment";
ExtComments[1]="SecondComment";
//--- prepara e visualizza il pannello di controllo per la gestione delle proprietà del chart
if(!PrepareControls())
return(INIT_FAILED);
//--- esecuzione avvenuta
return(INIT_SUCCEEDED);
}
//+--------------------------------------------------------------------------------+
//| Funzione deinizializzazione dell'expert |
//+--------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- rimuove il commento sul chart
Comment("");
}
//+--------------------------------------------------------------------------------+
//| Handler di un evento chart |
//+--------------------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- controlla l'evento del clic sull'oggetto chart
if(id==CHARTEVENT_OBJECT_CLICK)
{
//--- divide il nome dell'oggetto per separatore
string obj_name[];
StringSplit(sparam,'_',obj_name);
//--- controlla se l'oggetto è un bottone
if(obj_name[0]=="Button")
{
//--- riceve l'indice del bottone
int index=(int)StringToInteger(obj_name[1]);
//--- rilascia il bottone
ExtButtons[index].State(false);
//--- imposta il nuovo valore della proprietà a seconda del suo tipo
if(ExtDataTypes[index]=='I')
ChangeIntegerProperty(index);
if(ExtDataTypes[index]=='D')
ChangeDoubleProperty(index);
if(ExtDataTypes[index]=='S')
ChangeStringProperty(index);
}
}
//--- ri-disegna i valori delle proprietà
RedrawProperties();
ChartRedraw();
}
//+--------------------------------------------------------------------------------+
//| Cambia la proprietà integer del chart |
//+--------------------------------------------------------------------------------+
void ChangeIntegerProperty(const int index)
{
//--- riceve il valore corrente della proprietà
long value=ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index]);
//--- definisce il seguente valore della proprietà
switch(ExtDrawTypes[index])
{
case 'C':
value=GetNextColor((color)value);
break;
default:
value=(long)GetNextValue((double)value,index);
break;
}
//--- imposta il nuovo valore della proprietà
ChartSetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index],0,value);
}
//+--------------------------------------------------------------------------------+
//| Cambia la proprietà double del chart |
//+--------------------------------------------------------------------------------+
void ChangeDoubleProperty(const int index)
{
//--- riceve il valore corrente della proprietà
double value=ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index]);
//--- definisce il seguente valore della proprietà
value=GetNextValue(value,index);
//--- imposta il nuovo valore della proprietà
ChartSetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index],value);
}
//+--------------------------------------------------------------------------------+
//| Cambia la proprietà string del chart |
//+--------------------------------------------------------------------------------+
void ChangeStringProperty(const int index)
{
//--- variabile statica per il passaggio all'interno dell'array ExtComments
static uint comment_index=1;
//--- indice di cambiamento per ricevere un altro commento
comment_index=1-comment_index;
//--- imposta il nuovo valore della proprietà
ChartSetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[index],ExtComments[comment_index]);
}
//+--------------------------------------------------------------------------------+
//| Ottiene il prossimo valore della proprietà |
//+--------------------------------------------------------------------------------+
double GetNextValue(const double value,const int index)
{
if(value+ExtStep[index]<=ExtMaxValue[index])
return(value+ExtStep[index]);
else
return(ExtMinValue[index]);
}
//+--------------------------------------------------------------------------------+
//| Ottiene il prossimo colore per la proprietà di tipo colore |
//+--------------------------------------------------------------------------------+
color GetNextColor(const color clr)
{
//--- restituisce i seguenti valori del colore
switch(clr)
{
case clrWhite: return(clrRed);
case clrRed: return(clrGreen);
case clrGreen: return(clrBlue);
case clrBlue: return(clrBlack);
default: return(clrWhite);
}
}
//+--------------------------------------------------------------------------------+
//| Re-disegna i valori della proprietà |
//+--------------------------------------------------------------------------------+
void RedrawProperties(void)
{
//--- testo valore della proprietà
string text;
long value;
//--- loop del numero delle proprietà
for(int i=0;i<ExtCount;i++)
{
text="";
switch(ExtDataTypes[i])
{
case 'I':
//--- riceve il corrente valore della proprietà
if(!ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[i],0,value))
break;
//--- testo integer della proprietà
switch(ExtDrawTypes[i])
{
//--- proprietà colore
case 'C':
text=(string)((color)value);
break;
//--- proprietà booleana
case 'B':
text=(string)((bool)value);
break;
//--- proprietà di enumerazione ENUM_CHART_MODE
case 'M':
text=EnumToString((ENUM_CHART_MODE)value);
break;
//--- proprietà di enumerazione ENUM_CHART_VOLUME_MODE
case 'V':
text=EnumToString((ENUM_CHART_VOLUME_MODE)value);
break;
//--- numero tipo int
default:
text=IntegerToString(value);
break;
}
break;
case 'D':
//--- testo proprietà double
text=DoubleToString(ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[i]),4);
break;
case 'S':
//--- testo proprietà string
text=ChartGetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[i]);
break;
}
//--- valore della prorpietà display
ExtLabelsValue[i].Description(text);
}
}
//+--------------------------------------------------------------------------------+
//| Crea il pannello per gestire le proprietà del chart |
//+--------------------------------------------------------------------------------+
bool PrepareControls(void)
{
//--- alloca la memoria per array con una riseva
MemoryAllocation(LAST_PROPERTY_NUMBER+1);
//--- variabili
int i=0; // variable loop
int col_1=0; // numero di proprietà nella prima colonna
int col_2=0; // numero di proprietà nella seconda colonna
int col_3=0; // numero di proprietà nella terza colonna
//--- numero corrente della proprità - 0
ExtCount=0;
//--- visualizzazione per le proprietà nel loop
while(i<=LAST_PROPERTY_NUMBER)
{
//--- immagazzina il corrente numero della proprietà
ExtNumbers[ExtCount]=i;
//--- incrementa il valore della variabile loop
i++;
//--- controlla se c'è una proprietà con tale numero
if(CheckNumber(ExtNumbers[ExtCount],ExtNames[ExtCount],ExtDataTypes[ExtCount],ExtGroupTypes[ExtCount],ExtDrawTypes[ExtCount]))
{
//--- crea elementi di controllo per la proprietà
switch(ExtGroupTypes[ExtCount])
{
case 1:
//--- crea etichette d un bottone per la proprietà
if(!ShowProperty(ExtCount,0,X_PROPERTY_NAME_1,X_PROPERTY_VALUE_1,X_BUTTON_1,Y_PROPERTY_1+col_1*Y_DISTANCE,true))
return(false);
//--- il numero degli elementi nella prima colonna è aumentato
col_1++;
break;
case 2:
//--- crea etichette d un bottone per la proprietà
if(!ShowProperty(ExtCount,1,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,X_BUTTON_2,Y_PROPERTY_1+col_2*Y_DISTANCE,true))
return(false);
//--- il numero degli elementi nella seconda colonna è aumentato
col_2++;
break;
case 3:
//--- crea solo etichette per la proprietà
if(!ShowProperty(ExtCount,2,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,0,Y_PROPERTY_2+col_3*Y_DISTANCE,false))
return(false);
//--- il numero degli elementi nella terza colonna è aumentato
col_3++;
break;
}
//--- definisce il valore della proprietà massimo e minimo e lo step
GetMaxMinStep(ExtNumbers[ExtCount],ExtMaxValue[ExtCount],ExtMinValue[ExtCount],ExtStep[ExtCount]);
//--- incrementa il numero delle proprietà
ExtCount++;
}
}
//--- libera la memoria non usata dagli array
MemoryAllocation(ExtCount);
//--- ri-disegna i valori delle proprietà
RedrawProperties();
ChartRedraw();
//--- esecuzione avvenuta
return(true);
}
//+--------------------------------------------------------------------------------+
//| Alloca la memoria per gli array |
//+--------------------------------------------------------------------------------+
void MemoryAllocation(const int size)
{
ArrayResize(ExtLabelsName,size);
ArrayResize(ExtLabelsValue,size);
ArrayResize(ExtButtons,size);
ArrayResize(ExtNumbers,size);
ArrayResize(ExtNames,size);
ArrayResize(ExtDataTypes,size);
ArrayResize(ExtGroupTypes,size);
ArrayResize(ExtDrawTypes,size);
ArrayResize(ExtMaxValue,size);
ArrayResize(ExtMinValue,size);
ArrayResize(ExtStep,size);
}
//+--------------------------------------------------------------------------------+
//| Controlla se l'indice della proprietà appartiene ad uno di quelli dell' |
//| enumerazioni ENUM_CHART_PROPERTIES |
//+--------------------------------------------------------------------------------+
bool CheckNumber(const int ind,string &name,uchar &data_type,uint &group_type,uchar &draw_type)
{
//--- controllare se la proprietà è di tipo integer
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_INTEGER)ind);
if(_LastError==0)
{
data_type='I'; // proprietà dall'enumerazione ENUM_CHART_PROPERTY_INTEGER
GetTypes(ind,group_type,draw_type); // definisce i parametri della proprietà display
return(true);
}
//--- controllare se la proprietà è di tipo double
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_DOUBLE)ind);
if(_LastError==0)
{
data_type='D'; // proprietà dall' enumerazione ENUM_CHART_PROPERTY_DOUBLE
GetTypes(ind,group_type,draw_type); // definisce i parametri della proprietà display
return(true);
}
//--- controlla se la proprietà è di tipo stringa
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_STRING)ind);
if(_LastError==0)
{
data_type='S'; // proprietà dall'enumerazione ENUM_CHART_PROPERTY_STRING
GetTypes(ind,group_type,draw_type); // definisce i parametri della proprietà display
return(true);
}
//--- la proprietà non corrisponde a nessuna enumerazione
return(false);
}
//+--------------------------------------------------------------------------------+
//| Definisce il gruppo nel quale la proprietà dev'essere memorizzata |
//| così come il tipo della sua visualizzazione |
//+--------------------------------------------------------------------------------+
void GetTypes(const int property_number,uint &group_type,uchar &draw_type)
{
//--- controlla se la proprietà appartiene al terzo gruppo
//--- le proprietà del terzo gruppo vengono visualizzate nella seconda colonna a partire da CHART_BRING_TO_TOP
if(CheckThirdGroup(property_number,group_type,draw_type))
return;
//--- controlla se la proprietà appartiene al secondo gruppo
//--- le proprietà del secondo gruppo sono visualizzate all'inizio della seconda colonna
if(CheckSecondGroup(property_number,group_type,draw_type))
return;
//---se vi trovate qui, la proprietà appartiene al primo gruppo (prima colonna)
CheckFirstGroup(property_number,group_type,draw_type);
}
//+-------------------------------------------------------------------------------+
//| Controlla se la proprietà appartiene al terzo gruppo e |
//| definisce il suo tipo di visualizzazione in caso di risposta positiva |
//+-------------------------------------------------------------------------------+
bool CheckThirdGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- controlla se la proprietà appartiene al terzo gruppo
switch(property_number)
{
//--- proprietà booleane
case CHART_IS_OBJECT:
case CHART_WINDOW_IS_VISIBLE:
draw_type='B';
break;
//--- proprietà integer
case CHART_VISIBLE_BARS:
case CHART_WINDOWS_TOTAL:
case CHART_WINDOW_HANDLE:
case CHART_WINDOW_YDISTANCE:
case CHART_FIRST_VISIBLE_BAR:
case CHART_WIDTH_IN_BARS:
case CHART_WIDTH_IN_PIXELS:
draw_type='I';
break;
//--- proprietà double
case CHART_PRICE_MIN:
case CHART_PRICE_MAX:
draw_type='D';
break;
//--- in realtà, questa proprietà è un comando di visualizzazione del chart in cima a tutti gli altri
//--- non vi è alcuna necessità di applicare questo pannello, siccome la finestra sarà sempre
//--- in cima ad altre prima che noi la usiamo
case CHART_BRING_TO_TOP:
draw_type=' ';
break;
//--- la proprietà non appartiene al terzo gruppo
default:
return(false);
}
//--- la proprietà appartiene al terzo gruppo
group_type=3;
return(true);
}
//+-------------------------------------------------------------------------------+
//| Controlla se la proprietà appartiene al secondo gruppo e |
//| definisce il suo tipo di visualizzazione in caso di risposta positiva |
//+-------------------------------------------------------------------------------+
bool CheckSecondGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- controlla se la proprietà appartiene al secondo gruppo
switch(property_number)
{
//--- ENUM_CHART_MODE type property
case CHART_MODE:
draw_type='M';
break;
//--- ENUM_CHART_VOLUME_MODE type property
case CHART_SHOW_VOLUMES:
draw_type='V';
break;
//--- proprietà stringa
case CHART_COMMENT:
draw_type='S';
break;
//--- proprietà color
case CHART_COLOR_BACKGROUND:
case CHART_COLOR_FOREGROUND:
case CHART_COLOR_GRID:
case CHART_COLOR_VOLUME:
case CHART_COLOR_CHART_UP:
case CHART_COLOR_CHART_DOWN:
case CHART_COLOR_CHART_LINE:
case CHART_COLOR_CANDLE_BULL:
case CHART_COLOR_CANDLE_BEAR:
case CHART_COLOR_BID:
case CHART_COLOR_ASK:
case CHART_COLOR_LAST:
case CHART_COLOR_STOP_LEVEL:
draw_type='C';
break;
//--- la proprietà non appartiene al secondo gruppo
default:
return(false);
}
//--- la proprietà appartiene al secondo gruppo
group_type=2;
return(true);
}
//+-------------------------------------------------------------------------------------+
//| Chiamato solo se è si sa già che la proprietà non appartiene |
//| al secondo e terzo gruppo proprietà |
//+-------------------------------------------------------------------------------------+
void CheckFirstGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- la proprietà appartiene al primo gruppo
group_type=1;
//--- definisce il tipo di proprietà display
switch(property_number)
{
//--- proprietà integer
case CHART_SCALE:
case CHART_HEIGHT_IN_PIXELS:
draw_type='I';
return;
//--- proprietà double
case CHART_SHIFT_SIZE:
case CHART_FIXED_POSITION:
case CHART_FIXED_MAX:
case CHART_FIXED_MIN:
case CHART_POINTS_PER_BAR:
draw_type='D';
return;
//--- solo le proprietà booleane sono rimaste
default:
draw_type='B';
return;
}
}
//+--------------------------------------------------------------------------------+
//| Crea l'etichetta ed il bottone per la proprietà |
//+--------------------------------------------------------------------------------+
bool ShowProperty(const int ind,const int type,const int x1,const int x2,
const int xb,const int y,const bool btn)
{
//--- Array statico per la commutazione all'interno di array di colore ExtColors
static uint color_index[3]={1,1,1};
//--- indice di cambiamento per la ricezione di un altro colore
color_index[type]=1-color_index[type];
//--- mostra le etichette ed un bottone (se btn=true) per la proprietà
if(!LabelCreate(ExtLabelsName[ind],"name_"+(string)ind,ExtNames[ind],ExtColors[color_index[type]],x1,y))
return(false);
if(!LabelCreate(ExtLabelsValue[ind],"value_"+(string)ind,"",ExtColors[color_index[type]],x2,y))
return(false);
if(btn && !ButtonCreate(ExtButtons[ind],(string)ind,xb,y+1))
return(false);
//--- esecuzione avvenuta
return(true);
}
//+--------------------------------------------------------------------------------+
//| Crea etichette |
//+--------------------------------------------------------------------------------+
bool LabelCreate(CChartObjectLabel &lbl,const string name,const string text,
const color clr,const int x,const int y)
{
if(!lbl.Create(0,"Label_"+name,0,x,y)) return(false);
if(!lbl.Description(text)) return(false);
if(!lbl.FontSize(10)) return(false);
if(!lbl.Color(clr)) return(false);
//--- esecuzione avvenuta
return(true);
}
//+--------------------------------------------------------------------------------+
//| Crea bottoni |
//+--------------------------------------------------------------------------------+
bool ButtonCreate(CChartObjectButton &btn,const string name,
const int x,const int y)
{
if(!btn.Create(0,"Button_"+name,0,x,y,50,15)) return(false);
if(!btn.Description("Next")) return(false);
if(!btn.FontSize(10)) return(false);
if(!btn.Color(clrBlack)) return(false);
if(!btn.BackColor(clrWhite)) return(false);
if(!btn.BorderColor(clrBlack)) return(false);
//--- esecuzione avvenuta
return(true);
}
//+--------------------------------------------------------------------------------+
//| Definisce il massimo ed il minimo valore e step delle proprietà |
//+--------------------------------------------------------------------------------+
void GetMaxMinStep(const int property_number,double &max,double &min,double &step)
{
double value;
//--- imposta i valori a seconda del tipo di proprietà
switch(property_number)
{
case CHART_SCALE:
max=5;
min=0;
step=1;
break;
case CHART_MODE:
case CHART_SHOW_VOLUMES:
max=2;
min=0;
step=1;
break;
case CHART_SHIFT_SIZE:
max=50;
min=10;
step=2.5;
break;
case CHART_FIXED_POSITION:
max=90;
min=0;
step=15;
break;
case CHART_POINTS_PER_BAR:
max=19;
min=1;
step=3;
break;
case CHART_FIXED_MAX:
value=ChartGetDouble(0,CHART_FIXED_MAX);
max=value*1.25;
min=value;
step=value/32;
break;
case CHART_FIXED_MIN:
value=ChartGetDouble(0,CHART_FIXED_MIN);
max=value;
min=value*0.75;
step=value/32;
break;
case CHART_HEIGHT_IN_PIXELS:
max=700;
min=520;
step=30;
break;
//--- valori default
default:
max=1;
min=0;
step=1;
}
}
|