Galleria di interfacce utente scritte in MQL - pagina 58

 
hini #:

Sì, è importante rilasciare prima un programma completo.

Lo farò.
 
Una versione di base completamente funzionale del motore e del costruttore è un obiettivo valido e raggiungibile. Richiede un piano chiaro e una definizione delle priorità. A sua volta, significa la fine dell'aggiunta di grandi compiti ai piani e l'inizio della risoluzione di problemi urgenti.

Vorrei fare un'analogia con la costruzione di un grattacielo. Immaginiamo un progetto in cui il capomastro non sa esattamente quanti piani devono essere costruiti. Supponiamo che non sia stato informato. Ma in fondo è un creatore, una persona creativa. Non gli importa. Più grande è, meglio è. Gli piacciono le case alte e i grattacieli. Mentre lavora, la costruzione continua, i piani vengono aggiunti e l'edificio cresce verso il cielo. Ma gli appartamenti non possono essere consegnati agli inquilini, perché le impalcature non sono state rimosse e lo spazio abitativo non è stato pulito. Anche le porte non sono state inserite. La casa è incompiuta. Ma per il capomastro si tratta di inezie. Sta guardando in alto. Il cielo. E gli inquilini aspettano impazienti, hanno bisogno di appartamenti.

In generale, per il capomastro è tempo di "cambiare il firmware" e di riorganizzarsi mentalmente. Smettere di costruire i piani e iniziare a mettere le porte nelle aperture. E infine iniziare a pulire l'area, intonacare le pareti, posare il parquet e installare i lampadari .....

Mettiamola così: i pavimenti, per ora, non verranno costruiti. Invece, i pavimenti che sono già stati costruiti saranno finiti. I lavori saranno pianificati in modo da consegnare la casa agli inquilini il prima possibile.

Dopo tutto, la casa è stata costruita per loro....


 

Ciao a tutti,

Alla luce della recente discussione, vorrei proporre di documentare i risultati e i progressi del progetto di Peter Konow nel "Codebase" piuttosto che sul forum. Il forum è eccellente per le discussioni e il feedback immediato, ma manca della struttura e della coerenza necessarie per presentare il quadro generale e le politiche coerenti del progetto.

Utilizzando il Codebase, possiamo garantire che tutte le informazioni rilevanti siano organizzate, facilmente accessibili e forniscano una chiara panoramica dello stato del progetto. Questo non solo aiuterà a mantenere la chiarezza, ma anche a facilitare una migliore collaborazione e comprensione tra tutti i membri del team e gli stakeholder.

Vi sarei molto grato se poteste prendere in considerazione questo suggerimento.

 
Yutaka Okamoto progetto di Peter Konow siano documentati in Codebase piuttosto che sul forum. Il forum è ottimo per la discussione e il feedback immediato, ma manca della struttura e della coerenza necessarie per presentare il quadro generale e le politiche coerenti del progetto.

Utilizzando un "Codebase" possiamo garantire che tutte le informazioni pertinenti siano organizzate, facilmente accessibili e forniscano un quadro chiaro dello stato del progetto. Questo non solo aiuterà a mantenere la chiarezza, ma promuoverà anche una migliore cooperazione e comprensione tra tutti i membri del team e gli stakeholder.

Vi sarei molto grato se prendeste in considerazione questa proposta.

È un suggerimento molto razionale, grazie. Indubbiamente, il codebase è comodo per pubblicare gli aggiornamenti e comunicare con gli utenti. È una grande aggiunta allo sviluppo del progetto. Anche se in passato ho usato poco il codebase, ora vedo il senso pratico di esplorare i termini e le condizioni e di adattarmi ai requisiti. Per farmi un'idea delle possibilità e dei limiti di questa piattaforma, cercherò progetti di membri noti della comunità. Prendendo esempio da loro, sarò in grado di condurre il progetto nel codebase in modo informativo e competente.

 

Il rilascio è previsto per oggi.

Tuttavia, ho deciso di seguire l'utile consiglio di un membro del forum e di pubblicare la nuova versione nel codebase. Per farlo bene, avrò bisogno di qualche giorno per studiare esempi di pubblicazioni simili, per fare un piano di gestione parallela del progetto sul forum e lì. E anche per passare attraverso la moderazione.

Qualche parola su questo rilascio:

1. Concettualizzato e implementato un sistema di interazione programmatica tra un programma utente e la sua interfaccia grafica.

Ulteriori dettagli:

  • Dopo aver condotto prove tecniche e analizzato i risultati, si è deciso di utilizzare le funzioni wrapper degli elementi invece delle proprietà globali astratte. Come si è visto, questa è la variante più efficace e semplice dell'accoppiamento programmatico degli algoritmi con l'ambiente grafico.
  • Sono state apportate delle aggiunte alle funzioni di salvataggio del progetto e di stampa dei file UIDATA.mqh e API.mqh, in modo che ogni elemento interattivo dell'interfaccia riceva automaticamente una funzione wrapper quando il progetto viene salvato.
  • Allo stesso tempo, le funzioni wrapper degli elementi hanno un corpo molto ridotto e il loro compito principale è quello di chiamare la funzione centrale, passando tre parametri principali: numero dell'elemento, valore e valore della proprietà.
  • Lasemplicità esterna delle funzioni non ostacola la versatilità della loro applicazione:

1. Quando vengono chiamate con le parentesi vuote, le funzioni restituiscono il valore del parametro elemento con uno dei tre tipi: int, double, stringa a seconda del tipo di elemento.

     int i    = w6_i_CHECKBOX_Some_checkbox(); //Элемент чекбокс. Буква i  после префикса означает что тип возвращаемого/устанавливаемого значения int.
     
     double d = w6_d_S_EDIT_Spin_the_value();  //Элемент поле ввода с кнопками. Буква d после префикса означает что тип возвращаемого/устанавливаемого значения double.

     string s = w7_s_EDIT_Comment_1();         //Элемент текстовое поле ввода. Буква s означает что тип возвращаемого/устанавливаемого значения string.

2 Quando vengono chiamate con un valore tra parentesi, le funzioni impostano il valore passato al parametro elemento e poi lo ridisegnano (il valore è impostato su int, double o string, a seconda del tipo di elemento).

     int i    = w6_i_CHECKBOX_Some_checkbox(0/1/2/3); //Элемент чекбокс. Передача нуля,единицы, двойки или тройки для смены между нейтральным, активированным, нетр.блокир. и актив. блокир. состояниями элемента. 
                                                      //Тот же метод работает для всех кнопок.
     
     double d = w6_d_S_EDIT_Spin_the_value(653.89);   //Элемент поле ввода с кнопками. Передача значения параметра в функцию для установки его в элемент.

     string s = w7_s_EDIT_Comment_1("Any text");      //Элемент текстовое поле ввода. Передача текста для установки в поле ввода.   


3. quando vengono chiamate con il valore predefinito del primo parametro e un numero di proprietà (tra quelle disponibili), le funzioni restituiscono il valore di questa proprietà dell'elemento (tutti i numeri di proprietà sono di tipo int, passati nel parametro della proprietà).

      int i = w6_i_BUTTON_Start(get_i,_A_COLOR); //Элемент Кнопка. Возврат значения цвета из свойства _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                  //Однако, данных тип функции принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).
                                                                  //Значение первого параметра get_i говорит функции что не нужно принимать значение первого параметра в расчет, а лишь вернуть значение свойства _A_COLOR.


4 . Quando vengono chiamate convalore e valoredella proprietà tra parentesi, le funzioni impostano i valori passati alle proprietà disponibili dell'elemento. Ilnumero della proprietàviene passato nel parametro property , il valore della proprietàviene passato nel parametrovalue .

     int i = w6_i_BUTTON_Start(C'255,0,0',_A_COLOR); //Элемент Кнопка. Передача и установка польз. значения цвета в свойство _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                      //Однако, тип функции этого элемента принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).


La struttura dei nomi delle funzioni-wrapper: w6_i_BUTTON_Start();

1. w è la lettera iniziale di tutte le funzioni wrapper. È un'abbreviazione di window.

2. 6 (o altro numero) - il numero di sequenza della finestra contenente l'elemento.

3. i (o d o s) - indica il tipo del valore restituito/impostato del parametro dell'elemento.

  • Può essere int: per pulsanti, caselle di controllo, cursori, campi di input con/senza pulsanti, barre di avanzamento, barre grafiche, pulsanti di opzione.
  • Può essere double: per cursori, campi di input con/senza pulsanti.
  • Può essere una stringa: per i campi di input di testo, per gli elementi VALUE, per le celle di tabella, per gli elenchi a comparsa.


4. BUTTON - nome del tipo di elemento a cui appartiene la funzione wrapper. Può essere qualsiasi altro elemento.

5. INIZIO - nome di un elemento specifico .


  • Tutte le funzioni wrapper hanno una struttura di nomi identica.
  • Ripeto: tutte le funzioni vengono stampate automaticamente.

//----------------------------------------------------------------------------------------------------

Applicazione intelligente del sistema intellisense:

Si è deciso di utilizzare uno speciale sistema di prefissi che aiuta a cercare e trovare rapidamente le funzioni-wrapper necessarie di finestre ed elementi. Ecco un esempio:

Tutte le funzioni wrapper di finestre ed elementi hanno la lettera w all'inizio. Tuttavia, se si mette un trattino basso dopo w: _ si apre una finestra intellisense con un elenco di nomi di tutte le funzioni delle finestre dell'interfaccia utente. Quindi, è necessario trovare la finestra con il nome desiderato nell'elenco, guardare il suo numero (è stampato nel nome della funzione), cancellare il trattino e mettere questo numero dopo w. Apparirà subito l'elenco di intellisense con i nomi delle funzioni degli elementi inclusi nella finestra. Ecco come fare:

Questo è un modo semplice per navigare rapidamente nell'elenco delle funzioni wrapper degli elementi. Non è nemmeno necessario stamparle.

//----------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------

Sono state inoltre apportate modifiche e aggiunte al file API. Ora sono disponibili all'utente più informazioni sull'elemento e sulla finestra:

 switch(Element)
   {
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      BUTTON
//NAME:         Start
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_BUTTON_Start(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Start:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when button pressed or released?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case pressed:  Alert("BUTTON Start pressed!");   break;
  
                case released:  Alert("BUTTON Start released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set an option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_an_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_an_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_an_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_an_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set another option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_another_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_another_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_another_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_another_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      D_LIST
//NAME:         D_LIST 1
//PARAMETER:    string
//INIT OPTION:  L_ITEM  1
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   string w6_s_D_LIST_D_LIST_1(string value = get_s, int Property = 0)      | PFX: w6
//=====================================================================================================================
 
Spero di poter provare presto queste funzioni.
 
hini #:
Spero di poter provare presto queste funzionalità.
Domani sera caricherò la nuova versione su codobase.
 
Rilascio in tarda serata.
 

Presento una versione del motore che interagisce programmaticamente con l'interfaccia grafica.

Ho fatto molto. C'è qualcosa da dire e da mostrare.

Dopo averla testata pubblicamente, la caricherò nella base di codice.

È emersa una cosa interessante...

Maggiori dettagli domani.

File:
4uh38_06.08.24.zip  1712 kb
 

Con un po' di anticipo, posso dire di aver trovato una soluzione molto comoda per gli utenti. All'interno del loro codice possono navigare facilmente tra le finestre, gli elementi e le proprietà. La soluzione consente loro di non ricordare i nomi degli elementi o delle proprietà, ma di trovarli e lavorarci facilmente. Allo stesso tempo, ogni elemento ha un elenco di proprietà get/set disponibili solo per esso e per gli elementi "correlati". Con il prefisso incorporato nel nome della funzione dell'elemento, l'utente la chiama e non commette mai l'errore di cercare di restituire o impostare una proprietà che l'elemento non ha.

Le funzioni wrapper si sono rivelate così versatili e facili da usare da sorprendere me stesso. Restituiscono il valore di un parametro quando le parentesi sono vuote, impostano quando il valore è uno, restituiscono il valore di una proprietà da un elenco quando il primo parametro è vuoto e l'indice della proprietà è nel secondo. Impostano un valore a una proprietà quando c'è un valore nel primo parametro e un indice di proprietà nel secondo. Restituiscono inoltre una notifica di risultato come 1 in caso di successo e -1 in caso di errore (valore o proprietà non validi). Le funzioni ridisegnano gli elementi stessi. Non è necessario occuparsene.

Cosa si può fare con le funzioni wrapper:

1. Ottenere il valore del parametro dell'elemento.

2. Impostare il valore di un parametro dell'elemento.

3. Ottenere i valori delle proprietà dell'elemento dall'elenco individuale delle proprietà appartenenti al suo tipo di elementi (chiamato dal prefisso scritto nel nome della funzione).

4. Impostare i valori delle proprietà dell'elemento dallo stesso elenco.

5. Impostare lo stato dell'elemento: neutro, attivato, (on/off), bloccato neutro, bloccato attivato.

6. Restituisce lo stato attuale dell'elemento.


Nel primo caso la funzione restituisce il valore del parametro.

Nel secondo caso restituisce il risultato: successo o errore. L'errore viene inviato al registro.

Nel terzo caso, restituisce il valore della proprietà.

Nel quarto caso, il risultato: successo o errore di impostazione della proprietà.

Nel quinto, restituisce 1 o -1.

Nel sesto - restituisce l'indice di stato dell'elemento (i dettagli sono riportati di seguito).


Tutto viene fatto da una funzione wrapper che viene stampata automaticamente. Per trovarla, digitate w_, si aprirà l'elenco di intellisense, che contiene i nomi delle finestre. In una di esse si trova l'elemento che si sta cercando. È necessario ricordare all'incirca in quale finestra si trova. Quindi, cancellate il diavolo e digitate il numero della finestra e selezionate quello che vi serve dall'elenco degli elementi. Nessuna memorizzazione.

Non è nemmeno necessario ricordare le proprietà degli elementi. Guardate il nome dell'elemento, vedete il prefisso per aprire un elenco di proprietà individuali. Digitare, aprire, selezionare la proprietà. Non è necessario ricordare nulla. Non è nemmeno necessario digitare. Intellisense fa tutto.

Anche Windows ha i propri wrapper. Possono essere aperti e chiusi. Il resto delle funzionalità non è ancora stato implementato.


È stato fatto un grosso aggiornamento al file API. Ora contiene un'enorme quantità di informazioni utili sull'elemento. Vale a dire: vengono stampati i prefissi, le proprietà individuali, i prototipi della funzione wrapper dell'elemento e della sua finestra, la posizione esatta dell'elemento (tabella, canvas e scheda a cui l'elemento appartiene, se presente), il tipo del suo parametro (int, double, string...), le proprietà del suo parametro (valore minimo, valore massimo, passo, numero di cifre dopo la virgola). Valore iniziale o opzione selezionata (a seconda dell'elemento). Tutto è progettato in modo abbastanza leggibile e comprensibile.

Ho testato parzialmente la nuova funzionalità e ne sono soddisfatto. Tutto funziona come previsto.

Domani la mostrerò nella pratica.