12. Mai 2012

DE_flag GB_flag

for english readers

Unterformulare gestalten

Die in der V12 neuen Unterformulare sind Klasse. Sie sparen viel doppelten Aufwand – seit ich weiß, wie mit Unterformularen umzugehen.

edges

Vorbereitung

Es hat sich bewährt:

  • ein unsichtbares Rechteck in die rechte untere Ecke zu legen
  • die Größe des Formulars von diesem Rechteck abhängig zu machen, mit Rändern 0
  • das Rechteck auf Seite 0 zu platzieren
  • rote Füllung, kein Rand, findet sich sofort
Außerdem verwende ich die Markierungslinien in Eingabeformularen. Das ist dann wichtig, wenn das Formular als Subform verwendet werden soll, weil so die automatische Größe weiß, welche Werte anzuwenden sind.

Events aktivieren

Die Werkseinstellungen haben weder On Unload noch On Close Box aktivert. On After Keystroke ist zu viel wenn auch On After Edit aktiv ist – dann gibt es zweimal einen Event während der Tastatur-Eingabe.

mainContent

Formular gestalten

Erste Maxime: für Ränder reicht der Platz nicht, erst recht nicht in einem Unterformular.

Das rote Rechteck markiert die Größenänderungsecke – solange 4D noch Carbon ist. Dieser Platz ist also tabu. Ausnahme sind Objekte mit horizontalen und vertikalen Rollbalken. Dann ist die rechte untere Ecke ungenutzt.

Nicht die Größenänderungseinstellungen für jedes Objekt vergessen! Am besten sofort testen und den Run-Button klicken.

Ein Unterformular braucht keine OK- und Abbrechen-Button!

inputEvents

Methode

Das Formular für die spätere Einbindung als Unterformular und alle seine Objekte rufen die eine Projekt-Methode auf. Denn es gibt vielleicht noch ein Super-Wooper-Komplett-Formular. Das kann dieselbe Projekt-Methode benutzen und ich muß Code nicht zweimal warten.

Hier am Beispiel der Formular-Methode und des dazugehörenden Abschnitts der Projektmethode.

Um ein Formular als Subform einsetzen zu können ist der Event On bound variable change wichtig und dazu gehörend $P_boundObj:=OBJECT Get pointer(Object subform container).

Muß nicht der gesamte On Load der Subform mit dem On Load des Hauptformulars ablaufen, bietet sich an, auf Object subform container zu prüfen und nur bei (Nil($P_boundObj)) auszuführen.

Die Subform kann jetzt auf eine Änderung der Subform-Variablen reagieren. Ich unterscheide nur nach numerisch – dann geht es um die eindeutige Record-ID, meist eine Longint – oder nach alphanumerisch – dann wurde die UUID übergeben oder eine Steuersequenz. Glücklicherweise müssen Formvariablen nur mehr einen Objektnamen haben. Den Datentyp lege ich in der Eigenschaften-Liste fest. Ist der Datentyp numerisch erzeugt 4D eine Real, habe ich doch eine Variable benannt ist sie eine Longint. Also werden alle zueinander passenden numerischen Datentypen in On bound variable change geprüft – das spart Debuggen.

Die 50 Zeilen Code setzt ein Macro ein.

In meinen ersten Versuchen habe ich die Subform an Ort und Stelle des Hauptformulars plaziert. Ziemlich bald mußte ich die Subform nachbessern, sie mußte etwas schmaler werden, dafür höher. Dann paßt sie in dieses Hauptformular und im nächsten wieder nicht. Das ist eine Rumzuppelei – viel zu viel Arbeit und macht die Idee, Unterformulare mehrfach zu nutzen zunichte!

Ich fing schon an, mir Gedanken zu machen und die Objekte über Koordinaten zu positionieren, darüber Buch zu führen, die Objekte zu verwalten, Raster einzurichten, mir dazu eine Datenstruktur im Hintergrund vorzuhalten. Das wäre in Arbeit ausgeartet. Der Clou ist:

container

Container anlegen

Jetzt lege ich mir Container als Platzhalter an. Container sind transparente Rechtecke, mit farblich hervorgehoben Rahmen und eindeutigen Objektnamen. Die liegen jetzt an Ort und Stelle, wo später die Subforms liegen werden, mal die eine und mal die andere.

Weiter unterhalb der sichtbaren Zone liegen die Subforms und meine grün umrandete Parkfläche. Wird eine Subform in einen Container im sichtbaren Bereich bewegt, müssen sich die nicht mehr gebrauchten zum Parkplatz bewegen.

Alle Container und alle Unterformulare sind unsichtbar gestellt. Erst wenn ein Unterformular gebraucht wird, wird es sichtbar gestellt. 4D macht hier gute Arbeit, kein Blinken, kein Durchscheinen, kein Warten.

Ich würde gerne ein wenig Warten akzeptieren, wenn es durch eine Animation belebt würde. Schön wäre, das eine Unterformular verschwinden zu sehen und das andere erscheinen. Aber die V15 will auch noch Neues bringen, fällt mit Cocoa ab, …

Object_Move_To

Die Subform einpassen

Meine Unterformulare sind außerhalb des sichtbaren Bereiches. Will ich sie sehen, muß ich die Koordinaten des Zielcontainers ermitteln und die Subform auf diese Koordinaten bewegen. Liegt schon ein Unterformular auf diesem Container, muß dieses Platz machen. Also Koordinaten des Parkplatzes ermitteln und dorthin bewegen.

Sowas muß gekapselt werden! Object_Move_To macht das und muß wissen

  • was tun $what
  • wohin $zielObjName und
  • welches Objekt $moveObjName.
Micro-Optimierung und sich merken was wo liegt macht mehr Arbeit als sich lohnt. Ein bereits parkendes Objekt noch einmal zu parken ist viel einfacher und 4D juckt es nicht.

Hier werden alle Objekte, die nicht sichtbar sein sollen, zum Parken geschickt:
Object_Move_To ("Hide";$parkingLot;$sfBhndlgPosObj)
Object_Move_To ("Hide";$parkingLot;$sfBhndlgTerminObj)
Object_Move_To ("Hide";$parkingLot;$sfBhndlgUntersuchung)
Object_Move_To ("Hide";$parkingLot;$sf_Medikamente)
und das nun wichtige in den Hauptbereich bewegt
Object_Move_To ("Move";$mainArea;$objName)

""

Wissen die Objekte im Unterformular sich zu bewegen , sieht es gut aus.

container