//--- inclut la bibliothèque des éléments de contrôle
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//--- constantes prédéfinies
#define X_PROPERTY_NAME_1 10 // coordonnée x du nom de la propriété dans la première colonne
#define X_PROPERTY_VALUE_1 225 // coordonnée x de la valeur de la propriété dans la première colonne
#define X_PROPERTY_NAME_2 345 // coordonnée x du nom de la propriété dans les deuxième et troisième colonnes
#define X_PROPERTY_VALUE_2 550 // coordonnée x de la valeur de la propriété dans les deuxième et troisième colonnes
#define X_BUTTON_1 285 // coordonnée x du bouton dans la première colonne
#define X_BUTTON_2 700 // coordonnée x du bouton dans la deuxième colonne
#define Y_PROPERTY_1 30 // coordonnée y du début des première et deuxième colonne
#define Y_PROPERTY_2 286 // coordonnée y du début de la troisième colonne
#define Y_DISTANCE 16 // distance axiale y entre les lignes
#define LAST_PROPERTY_NUMBER 111 // numéro de la dernière propriété graphique
//--- paramètres d'entrée
input color InpFirstColor=clrDodgerBlue; // Couleur des lignes impaires
input color InpSecondColor=clrGoldenrod; // Couleur des lignes paires
//--- variables et tableaux
CChartObjectLabel ExtLabelsName[]; // étiquettes pour afficher les noms des propriétés
CChartObjectLabel ExtLabelsValue[]; // étiquettes pour affichers les valeurs des propriétés
CChartObjectButton ExtButtons[]; // boutons
int ExtNumbers[]; // indices des propriétés
string ExtNames[]; // nom des propriétés
uchar ExtDataTypes[]; // type de données des propriétés (integer, double, string)
uint ExtGroupTypes[]; // tableau pour stocker les données appartenant aux propriétés de l'un des groupes
uchar ExtDrawTypes[]; // tableau pour stocker les données du type d'affichage des propriétés
double ExtMaxValue[]; // valeurs maximum possibles des propriétés lors de l'utilisation du panneau
double ExtMinValue[]; // valeurs minimum possibles des propriétés lors de l'utilisation du panneau
double ExtStep[]; // pas de changement des propriétés
int ExtCount; // nombre total de propriétés
color ExtColors[2]; // tableau de couleurs pour l'affichage des lignes
string ExtComments[2]; // tableau de commentaires (pour la propriété CHART_COMMENT)
//+----------------------------------------------------------------------------------------------------+
//| Fonction d'initialisation d'un indicateur personnalisé |
//+----------------------------------------------------------------------------------------------------+
int OnInit()
{
//--- affichage d'un commentaire sur le graphique
Comment("SomeComment");
//--- stocke les couleurs dans le tableau pour pouvoir basculer entre elles par la suite
ExtColors[0]=InpFirstColor;
ExtColors[1]=InpSecondColor;
//--- stocke les commentaires dans le tableau pour pouvoir basculer entre eux par la suite
ExtComments[0]="FirstComment";
ExtComments[1]="SecondComment";
//--- prépare et affiche le panneau de contrôle pour gérer les propriétés du graphique
if(!PrepareControls())
return(INIT_FAILED);
//--- exécution réussie
return(INIT_SUCCEEDED);
}
//+----------------------------------------------------------------------------------------------------+
//| Fonction de désinitialisation de l'expert |
//+----------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- efface le commentaire sur le graphique
Comment("");
}
//+----------------------------------------------------------------------------------------------------+
//| Handler d'un évènement du graphique |
//+----------------------------------------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- vérifie l'évènement de clic sur l'objet graphique
if(id==CHARTEVENT_OBJECT_CLICK)
{
//--- sépare le nom de l'objet avec un séparateur
string obj_name[];
StringSplit(sparam,'_',obj_name);
//--- vérifie si l'objet est un bouton
if(obj_name[0]=="Button")
{
//--- récupère l'indice du bouton
int index=(int)StringToInteger(obj_name[1]);
//--- relâche le bouton
ExtButtons[index].State(false);
//--- définit la nouvelle valeur de la propriété suivant son type
if(ExtDataTypes[index]=='I')
ChangeIntegerProperty(index);
if(ExtDataTypes[index]=='D')
ChangeDoubleProperty(index);
if(ExtDataTypes[index]=='S')
ChangeStringProperty(index);
}
}
//--- redessine les valeurs de la propriété
RedrawProperties();
ChartRedraw();
}
//+----------------------------------------------------------------------------------------------------+
//| Change une propriété de type integer du graphique |
//+----------------------------------------------------------------------------------------------------+
void ChangeIntegerProperty(const int index)
{
//--- récupère la valeur courante de la propriété
long value=ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index]);
//--- définit la valeur suivante de la propriété
switch(ExtDrawTypes[index])
{
case 'C':
value=GetNextColor((color)value);
break;
default:
value=(long)GetNextValue((double)value,index);
break;
}
//--- définit la nouvelle valeur de la propriété
ChartSetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index],0,value);
}
//+----------------------------------------------------------------------------------------------------+
//| Change une propriété de type double du graphique |
//+----------------------------------------------------------------------------------------------------+
void ChangeDoubleProperty(const int index)
{
//--- récupère la valeur courante de la propriété
double value=ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index]);
//--- définit la valeur suivante de la propriété
value=GetNextValue(value,index);
//--- définit la nouvelle valeur de la propriété
ChartSetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index],value);
}
//+----------------------------------------------------------------------------------------------------+
//| Change une propriété de type string du graphique |
//+----------------------------------------------------------------------------------------------------+
void ChangeStringProperty(const int index)
{
//--- variable statique pour basculer dans le tableau ExtComments
static uint comment_index=1;
//--- change l'indice pour récupérer un autre commentaire
comment_index=1-comment_index;
//--- définit la nouvelle valeur de la propriété
ChartSetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[index],ExtComments[comment_index]);
}
//+----------------------------------------------------------------------------------------------------+
//| Récupère la valeur de la propriété suivante |
//+----------------------------------------------------------------------------------------------------+
double GetNextValue(const double value,const int index)
{
if(value+ExtStep[index]<=ExtMaxValue[index])
return(value+ExtStep[index]);
else
return(ExtMinValue[index]);
}
//+----------------------------------------------------------------------------------------------------+
//| Récupère la couleur suivante pour une propriété de type color |
//+----------------------------------------------------------------------------------------------------+
color GetNextColor(const color clr)
{
//--- retourne la couleur suivante
switch(clr)
{
case clrWhite: return(clrRed);
case clrRed: return(clrGreen);
case clrGreen: return(clrBlue);
case clrBlue: return(clrBlack);
default: return(clrWhite);
}
}
//+----------------------------------------------------------------------------------------------------+
//| Redessine les valeurs de la propriété |
//+----------------------------------------------------------------------------------------------------+
void RedrawProperties(void)
{
//--- valeur textuelle de la propriété
string text;
long value;
//--- boucle sur les propriétés
for(int i=0;i<ExtCount;i++)
{
text="";
switch(ExtDataTypes[i])
{
case 'I':
//--- récupère la valeur courante de la propriété
if(!ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[i],0,value))
break;
//--- propriété de type integer
switch(ExtDrawTypes[i])
{
//--- propriété de type color
case 'C':
text=(string)((color)value);
break;
//--- propriété de type boolean
case 'B':
text=(string)((bool)value);
break;
//--- propriété de type énumération ENUM_CHART_MODE
case 'M':
text=EnumToString((ENUM_CHART_MODE)value);
break;
//--- propriété de type énumération ENUM_CHART_VOLUME_MODE
case 'V':
text=EnumToString((ENUM_CHART_VOLUME_MODE)value);
break;
//--- propriété de type int
default:
text=IntegerToString(value);
break;
}
break;
case 'D':
//--- propriété de type double
text=DoubleToString(ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[i]),4);
break;
case 'S':
//--- propriété de type string
text=ChartGetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[i]);
break;
}
//--- affiche la valeur de la propriété
ExtLabelsValue[i].Description(text);
}
}
//+----------------------------------------------------------------------------------------------------+
//| Crée le panneau de gestion des propriétés du graphique |
//+----------------------------------------------------------------------------------------------------+
bool PrepareControls(void)
{
//--- alloue la mémoire pour les tableaux avec une réserve
MemoryAllocation(LAST_PROPERTY_NUMBER+1);
//--- variables
int i=0; // variable de boucle
int col_1=0; // nombre de propriétés dans la première colonne
int col_2=0; // nombre de propriétés dans la deuxième colonne
int col_3=0; // nombre de propriétés dans la troisième colonne
//--- nombre actuel de propriétés - 0
ExtCount=0;
//--- recherche des propriétés dans la boucle
while(i<=LAST_PROPERTY_NUMBER)
{
//--- stocke le numéro actuel de la propriété
ExtNumbers[ExtCount]=i;
//--- augmente la valeur de la variable de boucle
i++;
//--- vérifie s'il existe une propriété avec ce numéro
if(CheckNumber(ExtNumbers[ExtCount],ExtNames[ExtCount],ExtDataTypes[ExtCount],ExtGroupTypes[ExtCount],ExtDrawTypes[ExtCount]))
{
//--- crée les éléments de contrôle pour la propriété
switch(ExtGroupTypes[ExtCount])
{
case 1:
//--- crée les étiquettes et un bouton pour la propriété
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);
//--- le nombre d'éléments dans la première colonne a augmenté
col_1++;
break;
case 2:
//--- crée les étiquettes et un bouton pour la propriété
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);
//--- le nombre d'éléments dans la deuxième colonne a augmenté
col_2++;
break;
case 3:
//--- ne crée que les étiquettes pour la propriété
if(!ShowProperty(ExtCount,2,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,0,Y_PROPERTY_2+col_3*Y_DISTANCE,false))
return(false);
//--- le nombre d'éléments dans la troisième colonne a augmenté
col_3++;
break;
}
//--- définit les valeurs maximum et minimum de la propriété et le pas
GetMaxMinStep(ExtNumbers[ExtCount],ExtMaxValue[ExtCount],ExtMinValue[ExtCount],ExtStep[ExtCount]);
//--- augmente le nombre de propriétés
ExtCount++;
}
}
//--- libère la mémoire non utilisée par les tableaux
MemoryAllocation(ExtCount);
//--- redessine les valeurs de la propriété
RedrawProperties();
ChartRedraw();
//--- exécution réussie
return(true);
}
//+----------------------------------------------------------------------------------------------------+
//| Alloue la mémoire pour les tableaux |
//+----------------------------------------------------------------------------------------------------+
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);
}
//+----------------------------------------------------------------------------------------------------+
//| Vérifie si l'indice de la propriété appartient à l'une des |
//| énumérations ENUM_CHART_PROPERTIES |
//+----------------------------------------------------------------------------------------------------+
bool CheckNumber(const int ind,string &name,uchar &data_type,uint &group_type,uchar &draw_type)
{
//--- vérifie si la propriété est de type integer
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_INTEGER)ind);
if(_LastError==0)
{
data_type='I'; // propriété de l'énumération ENUM_CHART_PROPERTY_INTEGER
GetTypes(ind,group_type,draw_type); // définit les paramètres d'affichage de la propriété
return(true);
}
//--- vérifie si la propriété est de type double
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_DOUBLE)ind);
if(_LastError==0)
{
data_type='D'; // propriété de l'énumération ENUM_CHART_PROPERTY_DOUBLE
GetTypes(ind,group_type,draw_type); // définit les paramètres d'affichage de la propriété
return(true);
}
//--- vérifie si la propriété est de type string
ResetLastError();
name=EnumToString((ENUM_CHART_PROPERTY_STRING)ind);
if(_LastError==0)
{
data_type='S'; // propriété de l'énumération ENUM_CHART_PROPERTY_STRING
GetTypes(ind,group_type,draw_type); // définit les paramètres d'affichage de la propriété
return(true);
}
//--- la propriété n'appartient à aucune énumeration
return(false);
}
//+----------------------------------------------------------------------------------------------------+
//| Définit le groupe dans lequel la propriété devrait être stockée, |
//| ainsi que son type d'affichage |
//+----------------------------------------------------------------------------------------------------+
void GetTypes(const int property_number,uint &group_type,uchar &draw_type)
{
//--- vérifie si la propriété appartient au troisième groupe
//--- les propriétés du troisième groupe sont affichées dans la deuxième colonne à partir de CHART_BRING_TO_TOP
if(CheckThirdGroup(property_number,group_type,draw_type))
return;
//--- vérifie si la propriété appartient au deuxième groupe
//--- les propriétés du deuxième groupe sont affichées au début de la deuxième colonne
if(CheckSecondGroup(property_number,group_type,draw_type))
return;
//--- si vous vous retrouvez ici, la propriété appartient au premier groupe (première colonne)
CheckFirstGroup(property_number,group_type,draw_type);
}
//+------------------------------------------------------------------------------------------------+
//| Vérifie si la propriété appartient au troisième groupe et |
//| définit son type d'affichage si c'est le cas |
//+------------------------------------------------------------------------------------------------+
bool CheckThirdGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- vérifie si la propriété appartient au troisième groupe
switch(property_number)
{
//--- propriétés de type boolean
case CHART_IS_OBJECT:
case CHART_WINDOW_IS_VISIBLE:
draw_type='B';
break;
//--- propriétés de type 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;
//--- propriétés de type double
case CHART_PRICE_MIN:
case CHART_PRICE_MAX:
draw_type='D';
break;
//--- en fait, cette propriété est une commande pour afficher le graphique par-dessus tous les autres
//--- il n'y a pas besoin d'appliquer ce panneau, puisque la fenêtre sera toujours
//--- par-dessus toutes les autres avant qu'on ne l'utilise
case CHART_BRING_TO_TOP:
draw_type=' ';
break;
//--- la propriété n'appartient pas au troisième groupe
default:
return(false);
}
//--- la propriété appartient au troisième groupe
group_type=3;
return(true);
}
//+------------------------------------------------------------------------------------------------+
//| Vérifie si la propriété appartient au deuxième groupe et |
//| définit son type d'affichage si c'est le cas |
//+------------------------------------------------------------------------------------------------+
bool CheckSecondGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- vérifie si la propriété appartient au deuxième groupe
switch(property_number)
{
//--- propriété de type ENUM_CHART_MODE
case CHART_MODE:
draw_type='M';
break;
//--- propriété de type ENUM_CHART_VOLUME_MODE
case CHART_SHOW_VOLUMES:
draw_type='V';
break;
//--- propriété de type string
case CHART_COMMENT:
draw_type='S';
break;
//--- propriété de type 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 propriété n'appartient pas au deuxième groupe
default:
return(false);
}
//--- la propriété appartient au deuxième groupe
group_type=2;
return(true);
}
//+--------------------------------------------------------------------------------------------+
//| Appelé seulement s'il est déjà connu que la propriété n'appartient pas |
//| au deuxième ou au troisième groupe de propriétés |
//+--------------------------------------------------------------------------------------------+
void CheckFirstGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- la propriété appartient au premier groupe
group_type=1;
//--- définit le type d'affichage de la propriété
switch(property_number)
{
//--- propriété de type integer
case CHART_SCALE:
case CHART_HEIGHT_IN_PIXELS:
draw_type='I';
return;
//--- propriétés de type 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;
//--- il ne reste que les propriétés de type boolean
default:
draw_type='B';
return;
}
}
//+----------------------------------------------------------------------------------------------------+
//| Crée l'étiquette et le bouton pour la propriété |
//+----------------------------------------------------------------------------------------------------+
bool ShowProperty(const int ind,const int type,const int x1,const int x2,
const int xb,const int y,const bool btn)
{
//--- tableau statique pour basculer dans le tableau des couleurs ExtColors
static uint color_index[3]={1,1,1};
//--- change l'indice pour récupérer une autre couleur
color_index[type]=1-color_index[type];
//--- affiche les étiquettes et un bouton (si btn=true) pour la propriété
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);
//--- exécution réussie
return(true);
}
//+----------------------------------------------------------------------------------------------------+
//| Crée l'étiquette |
//+----------------------------------------------------------------------------------------------------+
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);
//--- exécution réussie
return(true);
}
//+----------------------------------------------------------------------------------------------------+
//| Crée le bouton |
//+----------------------------------------------------------------------------------------------------+
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("Suivant")) 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);
//--- exécution réussie
return(true);
}
//+----------------------------------------------------------------------------------------------------+
//| Définit les valeurs maximum et minimum de la propriété et le pas |
//+----------------------------------------------------------------------------------------------------+
void GetMaxMinStep(const int property_number,double &max,double &min,double &step)
{
double value;
//--- définit les valeurs suivant le type de la propriété
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;
//--- valeurs par défaut
default:
max=1;
min=0;
step=1;
}
}
|