System: BeOS,Haiku,Zeta
Worum es in diesem Tutorial geht
In laufe der letzten Jahre habe ich an diversen kleineren und größeren yab Anwendungen gearbeitet. Mit diesen Jahren habe ich vieles gelernt und optimiert. Wenn ich Programmkodes von damals mit heute vergleiche sind dort große Unterschiede zu sehen.
Wenn man anfängt mit Programmieren zählt vor allen die Funktion, da wird noch nicht so viel Wert auf das Aussehen und die Hintergrundabläufe geachtet. Das ändert sich jedoch mit der Zeit. Wenn man immer wieder die selben Programmierarbeiten durchführt gewöhnt man sich schnell an diese aus Vorherigen Programmkodes zu entnehmen. Findet man eine Möglichkeit diese Abläufe zu verbessern, so finden diese schnell Einzug in den Programmieralltag.
Heute befinden sich in meinen Programmen diverse Abfragen zum Thema Programmablauf. Dabei überlasse ich ungern etwas dem Zufall. Wenn ich zum Beispiel bestimmte Verzeichnisse oder Dateien für mein Programm benötige, so überprüfe ich diese im Vorwege. Alles was fehlt wird entweder erstellt oder der Benutzer darüber informiert.
In diesem Tutorial möchte ich diese Erfahrungen nun mit Denen teilen die Interesse daran haben.
Inhalt
- Auf einhaltlichtes Design achten
- Auf Auslagern in Libraries während der Programmierung verzichten
- Benutzerfreundlichkeit
- Eine gute Basis
- Ermittlung der Bildschirmauflösung
- GUI Elemente splittbar machen
- Statusbar richtig Einsetzen
- Überprüfen auf Vorhandensein von Ordnern und Dateien
- Verwenden von festen Schriftarten
- Zeilen einsparen
Auf einhaltlichtes Design achten
Wie man beim Essen sagt "Das Auge ist mit", so trifft das auch auf das Aussehen von Programmen zu. Hat eine Anwendung ein ansehnliches, übersichtliches Design wird des Benutzer diese gerne verwenden. Herrscht allerdings Chaos, so schreckt das den Benutzer ab. Das betrifft die Farbwahl, die Schriftart, Aufbau der Schaltflächen, Textbereiche, etc.
Allerdings ist wichtig, dass man darauf achtet das bei allen Designtechnischen Dingen nicht die Logik und Bedienungsfreundlichkeit drunter leidet. Es ist nicht immer einfach hier den richtigen Weg zu finden.
Oftmals sind es Kleinigkeiten die am Ende die größte Wirkung haben. Ich für meinen Teil verwende z.B. so gut wie nie die bei den yab Modulen eingefügten Beschriftungsbereiche, sondern erstelle sie mit DRAW TEXT und füge dann das gewünschte Modul (z.B. eine Textcontrol) hinten an.
DRAW TEXT 10,25, "Name: ", "View" TEXTCONTROL 110,7 TO 320,17, "TC:Name", "", "", "View" |
Dadurch ist die Position der im Beispiel verwendeten Textcontrol "an sich" (das Eingabefeld) nicht abhängig von dem Text davor. Somit kann man zum Beispiel mehrere Textcontrols untereinander positionieren, die alle unterschiedlich beschriftet sind, aber trotzdem alle genau an der selben vertikalen Position beginnen.
zurück zur Übersicht
Auf Auslagern in Libraries während der Programmierung verzichten
Normalerweise sollte man immer so programmieren, dass man nichts doppelt anfassen muss. Dies spart Zeit und verhindert ewiges ändern des schon bestehenden Kodes beim weiterprogrammieren. Dies ist aber immer leichter gesagt als getan, denn oftmals zwingen einen neue Optionen im Programm andere Bereiche des Kodes, im verlauf der Programmierung, erneut an zu fassen.
Daher ist es während der Programmierung nicht immer ratsam alles und jedes in Libraries auszulagern, denn ein ewiges wechseln in die anderen geöffneten Dateien kann sehr viel Zeit rauben und auch sehr unübersichtlich werden.
Ist eine Programm oder eine Programmbereich komplett fertig programmiert kann man gerne diese Bereiche auslagern.
Aber letztendlich muss das jeder für sich selber entscheiden, wie dies am besten zu handhaben ist. Für mich hat sich bewehrt, hinter allen Programmabschnitten die miteinander verwoben sind ein Kommentar zu schreiben über welchen ich mit Hilfe der Suche schnell im Kode hin und her springen kann. Die Tastenkombination "Alt + g" ist schneller gedrückt als mit der Mouse auf eine andere Datei zu wechseln.
Button 10,20 to 110,40, "Sort", "Sortieren", "View" //sorting case "Sort|" //sorting Sub Sortieren() //sorting |
- Was ist wirklich wichtig für den Benutzer?
- Wie wird der Benutzer mit dem Programm zurecht kommen?
- Brauche ich eine Anleitung oder erklärt sich das Programm soweit selber?
Dies sind Fragen, die man sich immer stellen sollte. Gehe dabei nie davon aus wie Du es selber siehst, denn wer ein Programm schreibt sieht darin immer eine "eigene" Logik, die nicht immer auf den Benutzer übertragbar ist.
zurück zur Übersicht
Eine gute Basis
Mit einer guten Basis ist gemeint, dass man eine bewerte und alles umfassendes Grundgerüst verwendet. Es macht wenig Sinn immer wieder von Vorne an zu fangen. Im laufe der Jahre hat sich mein Grundgerüst immer wieder etwas verändert. Nicht wirklich viel aber es hat sich bewährt. Mit meinem Grundgerüst konnte ich bisher jedes Projekt verwirklichen, daher kann ich dieses nur empfehlen:
#!/boot/home/config/bin/yab REM Name of Program REM Developer REM Build Version / Date REM yab Version if (peek("isbound")) then ProgramFolder$ = peek$("directory") else ProgramFolder$ = system$("pwd") ProgramFolder$ = left$(ProgramFolder$, len(ProgramFolder$)-1) fi //Program info screenWidth = peek("desktopwidth") screenHeight = peek("desktopheight") //Main Window dim part$(1) inloop = true while(inloop) msg$ = message$ if (split(msg$, part$(), ":|") > 2) then PartOne$=part$(1) PartTwo$ = part$(2) PartThree$ = part$(3) fi if (split(msg$, part$(), ":|") > 3) then PartFour$ = part$(4) fi if (msg$ <> "") print msg$ switch msg$ //Cases default: end switch //Special Cases if(window count<1) inloop = false sleep 0.05 wend //Subroutines sub IfExists(filename$) return not system("test -e "+filename$) end sub |
Ermittlung der Bildschirmauflösung
Eine Ermittlung der Bildschirmgröße kann vielerlei Vorteile haben. Zum Beispiel hat dies beim Aufbau eines Programms den optischen Vorteil, dass man mit diesen Daten das Programmfenster mittig vom Bildschirm anzeigen kann. Ein andere Anwendungsmöglichkeit ist ein Programmfenster den Bildschirmspezifischen Möglichkeiten anzupassen (z.B. für Vollbild- , Minimalansicht).
Die Bildschirmgröße zu ermitteln ist sehr einfach und benötigt nur zwei Zeilen des Programmkodes:
screen_width = peek("desktopwidth") screen_height = peek("desktopheight") |
Die Variablen screen_width und screen_height sind dabei Namen die der Entwickler selber vergeben kann. Diese Zahlenvariable kann nun für jeden Größenangabe des Programmfensters, oder natürlich auch für jedes andere Fenster, verwendet werden. Die einfachste Lösung ist dabei die Zahlenvariable durch zwei zu teilen und dann die Hälfte der gewünschten Fenstergröße abzuziehen und für die andere Position dazuzugeben.
window open screen_width/2-300, screen_height/2-200 to screen_width/2+300, screen_height/2+200, "Main Window", "Musterprogramm" |
GUI Elemente splittbar machen
Um eine Abfrage der Bedienung der Anwendung übersichtlicher zu machen und um GUI Elemente genauer zu definieren, kann man dessen Namen so gestalten, daß man diesen splitten kann.
Wenn man z.B. ein Button mit einem Namen versieht, der diesen als ein Button ausweist, kann man alle Buttons des Programms über eine Case abfragen:
Definition des Buttons:
BUTTON x1,y1 TO x2 ,y2, "BT:Name" , Label$, View$ |
Case Abfrage dazu:
case "BT:"+PartTwo$+"|" if(PartTwo$="Name1")then //Aktion bei Button 1 elseif(PartTwo$="Name2")then //Aktion bei Button 2 endif break |
Das gleiche gilt für alle GUI Elemente. Somit hätte man dann für je ein GUI Element eine Case- Abfrage. Natürlich kann das auch am Ende unübersichtlich werden, kommt immer darauf an wie viele Abfrage dieser Art notwendig sind. Ich für meinen Teil habe mir diese Vorgehenseweise angenommen und bin damit sehr zufrieden.
Hier eine Tabelle mit meinen Kürzeln für meine GUI Elemente:
Kürzel | GUI Element |
AL | Alert |
BT | Button / Button Image |
BV | Boxview |
CV | Canvas |
CD | Calendar |
XB | Checkbox |
CV | Canvas |
CB | Columnbox |
DB | Dropbox |
FP | Filepanel |
LB | Listbox |
RB | Radiobutton |
SL | Slider |
XV | Splitview |
SV | Stackview |
SB | Statusbar |
TV | Tabview |
TE | Textedit |
TC | Textcontrol |
TB | Treebox |
VI | View |
WD | Window |
Man kann natürlich den Namen eines GUI Elements auch mehr als einmal aufteilen. Im Grunde genommen so oft wie es nötig und sinnvoll ist.
zurück zur Übersicht
Überprüfen auf Vorhandensein von Verzeichnissen und Dateien
Verwendet man in einem Programm feste Verzeichnisse oder verwendet externe Programme, sollte diese im Vorfeld überprüft werden. Selbst wenn man diese selber mit dem Programm zusammen ausliefert, sollte eine Überprüfung durchgeführt werden, denn man weiß nie ob jemand im System etwas verändert hat.
Beispiel: Beim Programmstart wird eine Konfigurationsdatei ausgelesen, welche alle wichtigen Informationen für die Anwendung beinhaltet. Sollte diese Datei nicht da sein kann das Programm an dieser Stelle nicht weiterlaufen, sprich es stürzt ab. Der Benutzer der Anwendung sieht keinerlei Information warum dies geschehen ist, denn das Programm wird scheinbar einfach beendet.
Nun gibt es mehrere Möglichkeiten dieses zu lösen.
Zum Beispiel könnte man ein Infofenster anzeigen mit einer Fehlermeldung, die dem Benutzer darüber informiert weshalb ein Fehler aufgetreten ist.
Schöner wäre allerdings, würde man die Konfigurationsdatei automatisch erstellen lassen, sollte diese fehlen. Aus diesem Grund liefere ich bei Verwendung einer Konfigurationsdatei diese nicht mehr mit aus, sondern lasse sie durch eine Abfrage automatisch erstellen. So ist es egal ob sie vorhanden ist oder nicht, denn selbst wenn eine Konfigurationsdatei, weshalb auch immer, auf einmal nicht mehr vorhanden sein sollte, wird eine Standard- Konfigurationsdatei neu erstellt.
Dazu bietet sich ein Lösungsweg an, der in der yabIDE eingesetzt wird. Diese verwendet eine IF- Abfrage, eine Sub- Routine und den Terminal Befehl test um die gesuchte Datei/Verzeichnis zu überprüfen:
filename$="/Pfad/zur/gesuchten/Datei oder Verzeichnis" If(IfExists$(filename$))then else Hier Programmkode für den Fall das keine Datei gefunden wurde endif |
Und die Sub- Routine im Bereich außerhalb der Mainloop:
sub IfExists(filename$) return not system("test -e "+filename$) end sub |
Jetzt könnte man natürlich sagen, was passiert wenn der Terminal Befehl test auf einmal entfällt in Haiku? Nun dann sollte man, wenn man auf Nummer Sicher gehen möchte, diesen auch überprüfen oder noch besser mit dem Programm mit ausliefern.
zurück zur Übersicht
Statusbar richtig einsetzen
Wann benötigt man eine Statusbar?
Eigentlich immer dann, wenn man dem Benutzer einen Prozess anzeigen möchte. Wichtig dabei ist, dass der Benutzer nicht das Gefühl bekommt, dass das Programm stehen geblieben ist (Ein Fehler aufgetreten ist).
Daher sollte man immer bevor der Prozess gestartet ist, die Statusbar mit 5- 10 Prozent der Anzeigefläche füllen. Danach kann dann der Prozess ganz normal durchlaufen (Natürlich mit zwischenzeitiger Aktuallisierung der Statusbar).
Am Ende sollte dann die gesamte Statusbar gefüllt und mindestens 2- 3 Sekunden in diesem Zustand angezeigt werden (Fall diese dann entfernt oder zurückgesetzt wird).
Der Benutzer sollte immer genügend Zeit bekommen zu realisieren, wenn etwas beginnt und beendet wird. |
Verwenden von feste Schriftarten
Bei dem Versuch ein einheitliches Bild einer Anwendung zu erhalten spielt die Schrift einen erheblichen Rolle. Ist diese nicht definiert wird die Standardschrift des Systems verwendet (Einstellbar durch den Benutzer). Dadurch kann es passieren das die verwendetet Textbereiche der Anwendung bei jedem anders aussehen und optische Fehler auftreten. Zum Beispiel könnte ein vor ein Bild gesetzter Text, durch eine große Schriftgröße des Systems, auf einmal länger sein als vorgesehen, sprich der Text endet nicht vor, sondern mitten im Bild.
yab Commands: Fonts
zurück zur Übersicht
Zeilen sparen
Je umfangreicher ein Programm wird, desto mehr wächst der Wunsch den Kode kleiner und übersichtlicher zu halten.
Hier ein paar Möglichkeiten den Kode zu verjüngen:
Cases
Bei den Cases kann man zum Beispiel mehre Cases, die ein und die selbe Funktion Aufrufen, hintereinander schreiben und nur mit einem break beenden.
case "Musterprogramm:_QuitRequested|" case "Musterprogramm:Programm:Ende|" window close "Musterprogramm" break |
Abfragen
Beim Auslesen von Verzeichnissen und Dateien kann man ebenso eine Vielzahl an Zeilen einsparen. An statt jedes Mal, wenn man eine Datei oder Verzeichnis auslesen möchte, die gesamt Abfrage zu verwenden kann man diese prima in eine Sub- Routine auslagern und dann bei Bedarf aufrufen. Um die Informationen für das Auslesen zu übergeben, verwendet man dann einfach immer die selben Variablen.
Dieses Beispiel zeigt wie man beim auslesen von Verzeichnissen immer die selbe Sub- Routine und zu erhalten der benötigten Informationen gleiche Variablen verwendet.
Wir geben in der Variablen target$ das Verzeichnis an, welches ausgelesen werden soll. Dann rufen wir die Sub- Routine auf. In der Sub- Routine wird dann mit Hilfe des ls Terminalbefehls das Verzeichnis target$ ausgelesen. In dem Array SplitProfile$(1) speichern wir alle Einträge des ausgelesenen Verzeichnisses (target$) die mit einem /n (Zeilenumbruch) getrennt sind. In diesem Beispiel gebe ich nun alle Einträge des Arrays automatisch aus.
target$="/boot/home/config/meinprogramm/profiles" readtarget() |
sub readtarget() filename$=system$("ls -G -1 "+target$) dim SplitProfiles$(1) pf=0 pfa=0 pf = split(filename$, SplitProfiles$(), "\n") for pfa = 1 to pf print SplitProfiles$(pfa) next pfa end sub |
Bereitgestellt durch BeSly die BeOS, Haiku und Zeta Wissensbasis. |