InvBox

Da Gambas-it.org - Wikipedia.

(Autore del Componente e del testo: Gianluigi])

Il componente che andremo a creare è una TextBox con invito, l'uso di questo controllo ci permetterà di evitare le Label di spiegazione.

L'idea è questa; sfruttando la trasparenza della TextBox inseriremo sotto di essa una Label con backgroung (fondo) bianco e foreground (scritta) grigio che riporterà per l'appunto una scritta di invito che apparirà come se fosse della TextBox stessa.

Quando cambieremo i dati nella TextBox, sfruttando l'evento Change della stessa, faremo sparire o apparire la scritta di invito in base alla necessità.


Prima di cimentarvi in qualcosa che potrebbe non funzionare si consiglia di fare questa semplice prova.

Apriamo un nuovo progetto grafico QT application e diamogli un nome qualunque del tipo PoiTiCancello.

Disegnate sulla FMain.form una Label abbastanza lunga e sopra a coprirla abbondantemente disegnate una TextBox.

Poi fate doppio click sulla maschera per passare alla FMain.class e scrivete questo codice:

Public Sub Form_Open()
  TextBox1.Background = Color.Transparent
  Label1.Background = Color.TextBackground
  Label1.Text = "Se mi vedi puoi proseguire"
End

Avviate (F5) e se riuscite a leggere la scritta su sfondo bianco potete proseguire con la prova altrimenti dovete impostare il vostro sistema in modo che supporti la trasparenza oppure dovete desistere

Esiste il software QT Configuration sicuramente per le QT4 ma credo ci sia qualcosa anche per QT5, ad esempio per Ubuntu c'è nel Software Center Impostazioni QT che se configurato su Cleanlooks o Plastique funziona benissimo per tante cose, non solo la trasparenza.


Nota: Occorre sempre ragionare prima di usare oggetti particolari che hanno bisogno di settaggi ad hoc.

Pensiamo a chi lo dovrà usare e se sarà in grado di utilizzarlo.


Quindi dopo aver letto quanto scritto da Milio sul componente, apriamo un nuovo progetto di Gambas3 clicchiamo su QT application e poi su Seguente, scegliamo quindi dove mettere il nostro progetto e poi diamogli il nome InvBox e come titolo TextBox con invito.

Clicchiamo sul menu Progetto>Proprietà... si apre la finestra Proprietà dove in Project type agendo sugli spin sceglieremo la voce Componente.

Apparirà sull'elenco di sinistra una nuova voce Information scegliamola cliccandoci sopra, nella finestra che appare scegliamo la voce Sperimentale per Progress, scegliamo NO per This component is idden e spuntiamo la casella Gestione grafica della form, quindi diamo OK.

Nella parte sinistra della finestra in area progetto cliccate tasto destro sulla voce Sorgenti e dal menu contestuale scegliete Nuovo>Classe...

Si apre la finestra Nuovo file alla voce classe cambiatene il nome in InvBox, spuntate Esportato e date 'OK.


Se vi siete dimenticati di spuntare Esportato poco male scrivete Export appena sotto ' Gambas class file.

Il componente che stiamo per creare è un controllo pertanto dovrà ereditare da UserControl quindi appena sotto Export scriviamo Inherits UserControl.

Affinché Gambas comprenda cosa vogliamo ottenere occorre che glielo si indichi attraverso varie cose, iniziamo dalle costanti pubbliche.

Tutte sono utili ma nessuna è indispensabile la principale è la costante delle proprietà. Stavo per scrivere che la costante delle proprietà è indispensabile, in realtà essa lo è solo se vogliamo mostrare all'utente il nostro controllo alla stregua di tutti gli altri.

Come avete già letto nella wiki tutto quello che viene indicato in questa costante ve lo ritroverete nella sezione delle proprietà degli widget (controlli) nella scheda .form, l'area disegno dei form.

Noi per il nostro widget abbiamo bisogno di aggiungere la proprietà Invito quindi scriviamo appena sotto a Inherits UserControl:

Public Const _Properties As String = "*,Invito"

L'asterisco dice a Gambas che il nostro componente mostra tutte le proprietà di UserControl e in più gli dice di aggiungere la proprietà Invito. Badate bene UserControl non vuol dire TextBox che se voi volete dal vostro componente esattamente tutte le proprietà di una TextBox con in più la proprietà Invito dovrete digitare tutte le proprietà che distinguono la TextBox rispetto al controllo base.

Aggiungiamo:

Public Const _DefaultSize As String = "24,4"

Sono le misure del controllo, attenzione anche qui perché queste misure sono particolari esattamente otto pixel cadauna, come se disegnaste a mano nella IDE, vale a dire che di default il vostro componente misurerà 192x32 pixel e così si disegnerà sulla finestra facendogli doppio click sopra dalla ToolBox.

Public Const _Similar As String = "TextBox"

Scrivendo questo dite a Gambas che il vostro componente è simile a una TextBox.

Public Const _DefaultEvent As String = "Change"

Qui diciamo a Gambas che creeremo, come per la TextBox normale, l'evento Change e che questo è l'evento che si scriverà automaticamente nella scheda codice (es. FMain.class) facendoci sopra doppio click.

Se aggiungiamo

Public Const _DrawWith As String = "TextBox" 

il nostro componente si disegnerà sul form esattamente come una TextBox altrimenti potrete dargli un vostro stile con tanto di icona.


Nota: Il nostro componente sarà visto dall' utilizzatore del programma come una normale casella di testo, qui si parla di come lo vede il programmatore nella IDE.


Se desiderate riunire tutti i vostri componenti in una scheda a se stante, potete aggiungere:

Public Const _Group As String = "Componenti"

o qualunque nome vi aggrada.

In questo caso non fatelo, così il nostro componente verrà caricato insieme agli altri controlli grafici classici di base nella scheda Form.

Ora, a seguire, diremo a Gambas quali oggetti abbiamo intenzione di usare per costruire il nostro componente, come detto useremo una TextBox e una Label ma non possiamo usare la Label come contenitore della TextBox o viceversa infatti come potete ben vedere dalla scheda Container nessun controllo può essere usato come contenitore. Il più comodo contenitore è senz'altro Panel e infatti useremo questo per il nostro controllo.

Attenzione noi qui possiamo elencare i nostri attrezzi nell'ordine che vogliamo ma poi nel costruttore (_new) occorrerà fare attenzione all'ordine di disegno in quanto il primo rimane sotto al secondo che a sua volta rimane sotto il terzo e così via.

Scriviamo quindi:

Private $hTbox As TextBox
Private $hTxt As Label
Private $hPanel As Panel

A seguire andiamo a dichiarare le proprietà sia quelle che dovranno apparire nella IDE che quelle che ci servono solo nel codice, ad esempio UserControl non ha una proprietà Text e normalmente questa proprietà una TextBox la mostra nella IDE, ma non avrebbe senso inserire una frase di partenza nella nostra InvBox essendoci già l'invito.

Completiamo pertanto così la parte delle dichiarazioni:

'' Mostra in InvBox la frase di invito.
Property Invito As String
Private $sInvito As String  
'' Mostra la frase digitata.
Property Text As String
'' Viene invocato ad ogni cambiamento nel testo.
Event Change

Nota: I commenti in doppio apice verranno visti nella guida in linea e negli aiuti durante la digitazione.


Scriviamo il costruttore della nostra classe:

Public Sub _new()  
  $hPanel = New Panel(Me)
  $htxt = New Label($hPanel)
  $hTbox = New TextBox($hPanel) As "Tbox"
  $hPanel.Arrangement = Arrange.Fill  
  $hTbox.Background = Color.Transparent
  $hTxt.Background = Color.TextBackground  
  $hTxt.Foreground = Color.RGB(150, 150, 150)
  $hTxt.Padding = 5
  Me.Proxy = $hTbox
End

Con questo noi abbiamo detto a Gambas che il nostro componente è racchiuso in un Panel, con arrangement a fill egli espande completamente alle sue misure ciò che contiene.

Contiene appunto la Label e la TextBox a quest'ultima assegniamo gli eventi con “Tbox

Come detto diamo la trasparenza alla TextBox, lo sfondo TextBackground alla Label e sempre alla Label il colore grigio per il testo di invito.

Con il padding alla label sincronizziamo i testi di entrambi i controlli.

Con Proxy passiamo al nostro controllo le proprietà e gli eventi base di UserControl, potete vederne la lista nella guida in linea facendo F2 sulla parola all'interno della IDE.


Continuiamo:

Public Sub Tbox_Change()
  If Trim$($hTbox.Text) = "" Then
    $hTxt.Text = $sInvito
  Else
    $hTxt.Text = ""
  Endif
  Raise Change  
End

Utilizziamo l'evento interno proprio della TextBox per mostrare o nascondere il testo di invito e per propagare con Raise l'evento Change al nostro componente.


Continuiamo:

Private Function Invito_Read() As String
  Return $sInvito
End

Private Sub Invito_Write(Value As String)
  $sInvito = Value
  If Trim$($hTbox.Text) = "" Then
    $hTxt.Text = $sInvito
  Else
    $hTxt.Text = ""
  Endif
End

Assegna semplicemente il testo di invito alla proprietà testo della Label solo quando non c'è testo nella TextBox.


Continuiamo:

Private Function Text_Read() As String
  Return $hTbox.Text
End

Private Sub Text_Write(Value As String)
  $hTbox.Text = Value
End

Assegnamo al nostro controllo il testo della TextBox.


Infine:

'' Pulisce InvBox dai dati presenti.
Public Sub Clear()  
  $hTbox.Clear  
End

Creiamo il nostro metodo con tanto di spiegazione per la guida.

Abbiamo finito, a questo punto, se tutti i passaggi sono stati eseguiti correttamente, nella ToolBox, scheda Form dovrebbe esserci il componente InvBox. Se non appare provate a dare un Compila tutto dal menu Progetto, un click sul pulsante Ricarica o estrema ratio provate a riavviare.

Per verificare se il nostro controllo funziona a dovere potete usare tranquillamente la FMain del componente senza che questi ne abbia a patire, dalla ToolBox della FMain.form facciamo due volte doppio click sul controllo InvBox per disegnare due InvBox sulla finestra, posizioniamo convenientemente i due controlli nella finestra, evidenziamo un controllo alla volta per scrivere nella proprietà Invito rispettivamente Digita qui il nome e Digita qui il cognome, aggiungiamo un Button con scritto nella proprietà Text “Leggi”, aggiungiamo un secondo Button con scritto nella proprietà Text “Cancella”.

All'interno della FMain.class scriviamo il seguente codice:

Public Sub Form_Open()
  ' Si può impostare/cambiare l'invito a runtime
  ' attraverso la proprietà invito.
  InvBox1.Invito = "Nuovo invito..."  
End

Public Sub InvBox1_Change()  
  ' Si può utilizzare l'eveto Change.
  Print "Il testo di InvBox1 è cambiato"  
End

Public Sub InvBox2_Change()  
  ' Si può utilizzare l'evento Change.
  Print "Il testo di InvBox2 è cambiato"  
End

Public Sub Button1_Click()
  ' Legge.
  Print InvBox1.Text;; InvBox2.Text
  InvBox1.SetFocus()  
End

Public Sub Button2_Click()
  ' Azzerando o cancellando i dati
  ' riappariranno gli inviti.
  InvBox1.Text = ""
  InvBox2.Clear
  InvBox1.SetFocus()
End

Se funziona tutto, complimenti avete portato a buon fine il componente.


Se si desidera per il nostro componente una grafica particolare allora disegniamo una icona massimo di 32x32 px. nominiamola con lo stesso nome del componente tutto minuscolo (invbox.png) e inseriamola nella cartella creata appositamente e nominata control che poi andremo a inserire a sua volta nella cartella .hidden del progetto InvBox.

Si consiglia di fare queste cose al di fuori della IDE di Gambas, è più agevole.


Adesso che abbiamo un componente funzionante vediamo un modo semplice per incorporarlo nei nostri progetti, anche in questo caso è più facile agire al di fuori della IDE:

Creiamo un nuovo progetto QT e nominiamolo ProvaComponente chiudiamolo e apriamo le cartelle sia quella di InvBox che quella di ProvaComponente e diamo ad entrambe la possibilità di mostrare i file nascosti pertanto:

  • se desideriamo usare solo il componente senza fronzoli ci basta copiare il file InvBox.class (quello con la tazzina di caffè) dalla cartella .src e incollarlo nella cartella .src di ProvaComponente quindi dopo aver chiuso le cartelle avviare il nostro nuovo progetto e dare Ctrt+F (Progetto>Compila tutto).
  • se invece desideriamo importare anche la grafica occorre copiare da InvBox cartella .hidden e incollare in ProvaComponente cartella .hidden anche la cartella control in questo caso è facile che occorra oltre a compilare tutto, anche ricaricare la grafica attraverso il controllo Ricarica.

Ora potrete usufruire nel vostro nuovo progetto anche del nuovo controllo, il componente InvBox.