Basis-uitleg:
- hoe componenten in Gambas werken
- hoe ze zelf te maken
- hoe ze te installeren.
De originele documentatie over componenten vermeldt uitdrukkelijk dat alle “onderstaande tekst” voor Gambas3 is, dus ik doorloop het even in en voor Gambas2:
Componenten
De componenten die je in de Gambas IDE ziet (project, properties), zijn mee geïnstalleerd met de Gambas IDE. (Kijk in je Linux pakket manager om bij te installeren).
In bv OpenSUSE vind je ze na installatie in: /usr/lib64/gambas2/
Bv de gb.chart.component
en gb.chart.gambas
De .component is een tekstbestand, en bevat voor gb.chart:
[Component]
Key=gb.chart
State=2
Authors=Fabien Bodard
Needs=Form
Requires=gb.form
en voor gb.settings:
[Component]
Key=gb.settings
Authors=Benoît Minisini
In de IDE zijn de componenten uit te kiezen bij de projecteigenschappen, en tonen bovenstaande zich als:
gb.chart
Chart drawing (Beta version)
Authors: Fabien Bodard
Requires: Graphical form management, gb.form.
en
gb.settings
Application settings managament
Authors: Benoit Minisini
Bij het gebruik van Settings in je broncode worden volgende methodes en eigenschappen zichtbaar in de editor:
De broncode, van bv Settings, vind je na het afhalen en uitpakken van de broncode:
gambas2-2.23.1/comp/src/gb.settings
Een uittreksel (… is overgeslagen code):
' Gambas class file
'
EXPORT
CREATE STATIC
'
CLASS Window
'
STATIC PROPERTY READ Path AS String
'
PRIVATE $sPath AS String
PRIVATE $sTitle AS String
PRIVATE $cSlot AS Collection
PRIVATE $bModify AS Boolean
'
PRIVATE SUB Load()
'
DIM hFile AS File
DIM iLine AS Integer
DIM sLine AS String
DIM sSlot AS String
DIM iPos AS Integer
'
$cSlot = NEW Collection
IF NOT Exist($sPath) THEN RETURN
' ...
PUBLIC SUB _new(OPTIONAL Path AS String, OPTIONAL Title AS String)
'
DIM sDir AS String
DIM sPath AS String
DIM sElt AS String
'
IF Left(Path) <> "/" THEN
IF NOT Path THEN
' ...
PUBLIC SUB _free()
'
TRY ME.Save
'
END
'
PUBLIC SUB Save()
'
DIM aKey AS NEW String[]
DIM cSlot AS Collection
DIM sKey AS String
DIM hFile AS File
DIM vVal AS Variant
'
IF NOT $bModify THEN RETURN
' ....
PRIVATE FUNCTION GetSlot(sKey AS String) AS String
' ...
PUBLIC FUNCTION _get(Key AS String, OPTIONAL {Default} AS Variant) AS Variant
' ...
PUBLIC SUB _put(Value AS Variant, Key AS String)
' ...
PUBLIC SUB Clear(ParentKey AS String)
' ...
PUBLIC SUB Read(hObject AS Object, OPTIONAL sKey AS String, OPTIONAL vDefault AS Variant)
'
DIM sVal AS String
DIM aVal AS String[]
'
IF Object.Is(hObject, "Window") THEN
sKey = Object.Type(hObject) &/ sKey
LoadWindow(hObject, sKey)
ELSE
IF NOT sKey THEN TRY sKey = hObject.Name
sKey = GetTopLevel(hObject) &/ sKey
'DEBUG sKey
TRY hObject.Settings = ME[sKey, vDefault]
ENDIF
'
END
'
PUBLIC SUB Write(hObject AS Object, OPTIONAL sKey AS String)
'
IF Object.Is(hObject, "Window") THEN
sKey = Object.Type(hObject) &/ sKey
SaveWindow(hObject, sKey)
ELSE 'IF Object.Is(hObject, "SidePanel") THEN
IF NOT sKey THEN TRY sKey = hObject.Name
sKey = GetTopLevel(hObject) &/ sKey
'DEBUG sKey
TRY ME[sKey] = hObject.Settings
ENDIF
'
END
'
STATIC PRIVATE FUNCTION Path_Read() AS String
'
DIM sPath AS String = Application.Env["XDG_CONFIG_HOME"]
IF NOT sPath THEN sPath = System.User.Home &/ ".config"
RETURN sPath &/ "gambas"
'
END
'
STATIC PUBLIC FUNCTION Array(...) AS String[]
'
DIM aVal AS NEW String[]
DIM iInd AS Integer
DIM sVal AS String
DIM vVal AS Variant
'
FOR iInd = 0 TO Param.Max
vVal = Param[iInd]
IF IsBoolean(vVal) THEN
sVal = IIf(vVal, "1", "0")
ELSE
sVal = CStr(vVal)
ENDIF
aVal.Add(sVal)
NEXT
'
RETURN aVal
'
END
'
PUBLIC SUB Reload()
'
Load
'
END
Conclusies:
Classe begint met:
EXPORT
CREATE STATIC
De bruikbare, dwz van buitenaf zichtbare elementen zijn vet weergegeven in de broncode hierboven.
Het path is een eigenschap die van buitenaf (enkel) leesbaar moet zijn.
Dat wordt gerealiseerd met een interne variabele die in de (automatisch bestaande) functie _Read() wordt gebruikt om de externe alleen-lezen variabele af te schermen. Als gevolg komt die eigenlijk twee keer voor, waarbij je onderscheid moet kunnen maken tussen de namen, wat hier gedaan wordt door de private variabele als $sPath te definieren, en de externe gewoon als Path:
STATIC PROPERTY READ Path AS String
PRIVATE $sPath AS String
'
STATIC PRIVATE FUNCTION Path_Read() AS String
'
DIM sPath AS String = Application.Env["XDG_CONFIG_HOME"]
IF NOT sPath THEN sPath = System.User.Home &/ ".config"
RETURN sPath &/ "gambas"
'
END
Allerlei procedures (groene bol) zonder of met (één of meer optionele) parameters:
PUBLIC SUB Save()
PUBLIC SUB Reload()
PUBLIC SUB Clear(ParentKey AS String)
PUBLIC SUB Write(hObject AS Object, OPTIONAL sKey AS String)
PUBLIC SUB Read(hObject AS Object, OPTIONAL sKey AS String, OPTIONAL vDefault AS Variant)
De array ziet er zo uit (groene kubus):
STATIC PUBLIC FUNCTION Array(...) AS String[]
Zelf Component maken
Zelf maak je in de IDE een nieuw project, of wijzigt* een bestaand via menu:
Project, Properties, Options
kruis aan:
Options, Component: Yes. (Advancement: Beta)
Dat voegt onmiddellijk de tabbladen “Provides” en “Requieres” toe:
Component in Gambas2
* Wijzigen van een bestaand, niet als component gestart project naar “component” leverde me een crash op bij een klik in het tabblad “Provides” als daar nog niets aanwezig is.
Bij een nieuw project krijg je dan
Classes:
En onder Data de Controls:
- ccontainer.png
- ccontrol.png
Class CContainer bevat:
' Gambas class file
EXPORT
INHERITS UserContainer
PUBLIC SUB _new()
END
En Class CControl bevat:
' Gambas class file
EXPORT
INHERITS UserControl
PUBLIC SUB _new()
DIM hLabel AS Label
hLabel = NEW Label(ME) AS "MyLabel"
hLabel.Text = "Gambas!"
hLabel.Font = Font["+4,Bold,Italic"]
hLabel.Border = Border.Plain
END
PUBLIC SUB MyLabel_Enter()
LAST.Text = "Gambas Almost Means BASIC!"
END
PUBLIC SUB MyLabel_Leave()
LAST.Text = "Gambas!"
END
De IDE maakte deze bestanden aan, samen met 2 grafische bestanden, en ik veronderstel dat de code een soort voorbeeldcode is die je zelf kan aanpassen of weggooien als je ze niet nodig hebt.
Bij een bestaand project met classen die je algemeen wil hergebruiken: Begin van je project en pas aan zoals hierboven uitgelegd. Ter vergelijking kan je de broncode van Gambas2 gebruiken als voorbeeld.
In de broncode van je class zelf moet je volgens de documentatie met sleutelwoord “EXPORT” aangeven dat ze geëxporteerd moet worden.
Je kan er een gewoon source archive van maken (tar.gz) om te verspreiden naar de gebruikers.
Je kan als gebruiker het project “compileren”; met “make executable”. Daar krijg je een extra optie:
“Install in the user component directory”
Daardoor wordt de component bruikbaar vanuit je Gambas2 IDE, menu Project, Properties, Components.
Hij komt onderaan in de lijst van de componenten, onder de extra titel “User Components”. Geniaal eenvoudig!
De bestanden .gambas en .component worden geïnstalleerd(*) in
~/.local/lib/gambas2
waardoor ze bruikbaar worden in al de gebruiker’s gambas2 projecten.
* Opgelet!
Ze worden daar niet naartoe gekopieerd, maar er wordt slechts een link, een verwijzing gemaakt naar de gecompileerde versie (i.e. de locatie waar je ze gecompileerd hebt). Gooi het originele project daar weg, en je hebt een probleem!
Nota: virtuele class
In geval van een hierarchie van klassen, waarbij de hoogste een virtuele klasse is, die nooit rechtstreeks gebruikt wordt, moet je ze benoemen met een begin-underscore “_”, zodat ze onzichtbaar wordt. De verwijzing INHERITS hoofdklasse in de subklassen ook aanpassen naar INHERITS _hoofdklasse natuurlijk.