InvBox
(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 fate col mouse tasto desto 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 l'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 eredita 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 no, così il nostro componente verrà caricato insieme agli altri componenti grafici classici di base.
Ora, a seguire, diremo a Gambas che 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 questo noi useremo 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 che senso avrebbe inserire una frase di partenza nella nostra InvBox?
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 Private $sText 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 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.
Continuiamo:
Public Sub Tbox_Change() If Trim$($hTbox.Text) = "" Then $hTxt.Text = $sInvito Else $hTxt.Text = "" Endif Raise Change End
Utilizziamo l'evento privato 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 $hTxt.Text = $sInvito End
Quanto sopra mi pare non abbia bisogno di spiegazioni, assegna semplicemente il testo di invito alla proprietà testo della label.
Continuiamo:
Private Function Text_Read() As String Return $sText End Private Sub Text_Write(Value As String) $sText = Value $hTbox.Text = $sText End
Stessa cosa ma per la TextBox.
Infine:
'' Pulisce InvBox dai dati presenti. Public Sub Clear() $hTbox.Clear End
Creiamo il nostro metodo con tanto di spiegazione per la guida.
Per controllare se il vostro componente funziona a dovere potete usare tranquillamente la FMain del componente senza che questi ne abbia a patire, scriviamo pertanto all'interno della FMain.class il seguente codice:
Public Sub Button1_Click() ' Azzerando o cancellando i dati ' riappariranno gli inviti. InvBox1.Text = "" InvBox2.Clear End 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
Se funziona tutto, complimenti avete portato a buon fine il vostro primo componente, altrimenti controllate il codice confrontandolo con quello del file allegato.
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 è molto più semplice 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 quindi:
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 quidi dopo aver chiuso le cartelle avviare il nostro nuovo progetto e dare Ctrt+F (Progetto>Compila tutto).
Se invece si desidera 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.