Es gibt die Möglichkeit eine Grafik interaktiver zu gestaltet und diverse Proceduren aus den Makros zu triggern wenn in der Grafik auf bestimmte Objekte geklickt wird. Es stehen zwei Optionen zur Verfügung:
Klick auf ein Grafik-Objekt löst eine Prozedure aus
Klick auf einen GUI-Button löst eine Prozedure aus
Beide Optionen werden in diesem Kapitel genauer beschrieben.
Interaktive Objekte
Mit der Interface-Methode ISS.SETACTIONCALLBACK kann man Objekte interaktiv gestalten. Verwendet man diese Methode, wird eine Prozedure ausgeführt, wenn auf ein Objekt geklickt wird:
ISS.SETACTIONCALLBACK(<nObjID>, "objectclicked", "<Makroverzeichnis\Makroname.bas>", "<Prozedurename>", "", "", "")
Beispiel:
In unserem fiktiven Haustür-Beispiel möchten wir gerne, dass eine Prozedure ausgeführt wird, wenn auf den Drücker geklickt wird:
ISS.SETACTIONCALLBACK(nIDDruecker, "objectclicked", "HT\GrafikHT.bas", "EventDruecker", "", "", "")
Unsere ID des Drückers ist 'nIDDruecker'. Mit "objectclicked" markieren wir den Drücker als 'klickbares' Objekt. Die Procedure die beim Klicken ausgeführt werden soll heißt "EventDruecker" und befindet sich im root-Verzeichnis im Ordner HT in der BAS-Datei namens "GrafikHT". Die letzten 3 Parameter werden für andere Steuerungen benötigt und müssen in unserem Beispiel einfach als Leerstring mit übergeben werden.
In der Prozedure "EventDruecker" wird uns mit der Interface-Methode die ID des Objektes als STRING zurück geliefert. Somit muss die Procedure mit einem Input-Parameter versehen werden:
PROCEDURE EventDruecker
DEFINE PARAMETER INPUT pObjID
END
Dadurch, dass wir die ID in der Procedure zurückbekommen, können wir die Prozedure auch für andere Objekte verwenden und innerhalb der Prozedure abfragen, auf welches Objekt bzw. ID geklickt wurde.
Die Prozedure "EventDruecker" könnte nun zum Beispiel steuern, dass beim Klick auf den Drücker der Fokus der Konfiguration auf den Frageparameter "Drücker" springt:
PROCEDURE EventDruecker
DEFINE PARAMETER INPUT pObjID
IF VAL(pObjID) = nIDDruecker THEN ISS.CHANGEPARAMETERFOCUS("FpDruecker","<LevelID>")
END
Interaktive Buttons
Neben der Funktion eine Prozedure durch Klick auf ein Objekt auszulösen, gibt es auch die Möglichkeit GUI-Buttons auf ein Objekt zu legen, welche wiederum beim Klick eine Prozedure auslösen. In diesem Kapitel wird erläutert, wie Buttons erzeugt, gestaltet und positioniert werden können. Als Beispiel wird in diesem Kapitel mit folgendem Objekt gearbeitet:
Allgemeines
Die GUI-Buttons werden immer einem Objekt zugeordnet, und können nicht frei im 3D-Raum platziert werden. Die Positionierung und Ausrichtung der Buttons kann variabel eingestellt werden, und wird in diesem Kapitel noch genauer beschrieben. Die Buttons sind immer im Vordergrund, und können daher nicht von anderen Objekten verdeckt werden. Man kann die Buttons so einstellen, dass diese immer und zu jedem Zeitpunkt sichtbar sind, oder nur Sichtbar werden, wenn der Mauszeiger auf dem Objekt liegt. Ist ein Button so eingestellt, dass dieser nicht immer sichtbar ist, dann lässt sich mit einem Klick auf das Objekt der Button dauerhaft anzeigen, bis wieder auf das Objekt oder ein anderes Objekt geklickt wird. Für die Icons werden SVG-Dateien verwendet und eine Auswahl an SVGs finden Sie in unseren Zentralen Stammdaten. Alle Informationen der Buttons (Position/Optik/Verhalten) werden in einer JSON gebündelt und gesammelt und anschließend vom Grafikviewer verarbeitet. Für die Programmierung dieser Buttons stehen einige zentrale Prozeduren zur Verfügung und werden nachfolgend genauer beschrieben.
Schritt 1: Buttons definieren und gestalten (CreateButton)
Um Buttons einem Objekt hinzuzufügen müssen diese zuerst definiert und die Optik gestaltet werden. Dafür steht die zentrale Procedure 'CreateButton' zur Verfügung:
cButtondefinition = ""
RUN public\lib3D.CreateButton(cButtondefinition, "buttonID", "Kommando", "SVGName", nButtonSize, "Tooltip", nButtonRadius, nBorderWidth)
Parameter | Beschreibung |
---|---|
cButtondefinition | Muss als Leerstring übergeben werden. Wird für den JSON-String benötigt |
buttonID | Name des Buttons |
Kommando | Name des Kommandos |
SVGName | Angabe der SVG-Datei welche für den Button verwendet werden soll |
nButtonSize | Angabe der Buttongröße |
Tooltip | Angabe der Beschreibung welche bei Mouseover angezeigt werden soll |
nButtonRadius | Kreisform des Buttons. 100 steht für vollständigen Kreis / 0 für ein Rechteck |
nBorderWidth | Angabe der Dicke der Umrandungslinie |
SVG-Dateien
In den zentralen Stammdaten finden Sie einen Ordner namens 'SVG' welche eine Auswahl an Icons für die Buttons bereitstellt. Dieser Ordner muss in das Verzeichnis der Version kopiert werden. (Z.b. MasterData\iss_10101\)
Im Explorer werden die Icons alle schwarz angezeigt, im Grafikviewer werden allerdings die entsprechend richtigen Farben verwendet.
Beispiel
cButtondefinition = ""
RUN CreateButton(cButtondefinition, "buttonUp", "Up","ArrowUp", 3,"Neue Box nach oben",100 )
RUN CreateButton(cButtondefinition, "buttonDown", "Down","ArrowDown", 3,"Neue Box nach unten",100 )
RUN CreateButton(cButtondefinition, "buttonLeft", "Left","ArrowLeft", 3,"Neue Box nach Links",100 )
RUN CreateButton(cButtondefinition, "buttonRight", "Right","ArrowRight", 3,"Neue Box nach Rechts",100 )
RUN CreateButton(cButtondefinition, "buttonColor", "Color","Cog6Tooth", 3,"Farbe ändern",100 )
Schritt 2: Buttons initialisieren
Nachdem alle Buttons definiert wurden, müssen diese einmalig initialisiert werden. Dafür steht folgende zentrale Prozedure zur Verfügung:
RUN public\lib3D.InitiateActionButton(cButtondefinition)
Schritt 3: Button-Linie erzeugen (CreateButtonLine) [optional]
Möchte man auf einem Objekt Buttons auf verschiedenen Seiten positionieren, müssen zuvor eigene Button-Linien erzeugt werden. Wird nur eine Linie benötigt, kann dieser Punkt übersprungen werden.
In unserem Beispiel wird auf einem Objekt, auf insgesamt 5 verschiedenen Linien Buttons platziert:
Um Button-Linien zu definieren steht eine eigene zentrale Procedure zur Verfügung:
cbuttonLine1 = ""
RUN public\lib3D.CreateButtonLine(cButtonLine1,"<ButtonID>","<Kommando>")
Die ButtonID muss zuvor mit CreateButton erzeugt worden sein. Das Kommando kann an dieser Stelle nochmal überschrieben werden. So besteht die Möglichkeit, mit dem selben Button für jede Linie ein eigenes Kommandos zu vergeben. Der Parameter für ButtonID und Kommando ist Pipe-getrennt und ermöglicht damit mehrere Buttons auf derselben Linie:
cButtonLine1 = ""
RUN public\lib3D.CreateButtonLine(cButtonLine1,"buttonID1|buttonID2","Kommando1|Kommando2")
Beispiel
In unserem Fall benötigen wir 5 Linien, daher sieht der Code so aus:
buttonLineUp = ""
RUN CreateButtonLine(buttonLineUp, "buttonUp", "Up" )
buttonLineDown = ""
RUN CreateButtonLine(buttonLineDown, "buttonDown", "Down" )
buttonLineLeft = ""
RUN CreateButtonLine(buttonLineLeft, "buttonLeft", "Left")
buttonLineRight = ""
RUN CreateButtonLine(buttonLineRight, "buttonRight", "Right")
buttonLineColor = ""
RUN CreateButtonLine(buttonLineColor, "buttonColor", "Color")
Schritt 4: Buttons/Button-Linien positionieren (PositionButton)
Um die Buttons bzw. die Button-Linien auf dem Objekt richtig auszurichten, muss die folgende zentrale Procedure verwendet werden, nachdem die Definition über 'CreateButton' bzw. 'CreateButtonLine' vollzogen wurde:
cButtonPosition = ""
RUN public\lib3D.PositionButton(cButtonPosition, cButtondefinition, nStartFace, nEndFace, nStartIndex, nEndIndex, bShowFix, nShrinkLine, nShrinkFace, nShrinkBox)
Parameter | Beschreibung |
---|---|
cButtonPosition | Muss als Leerstring übergeben werden. Wird für den JSON-String benötigt |
cButtondefinition | Buttondefinition welche über CreateButton oder CreateButtonLine erzeugt wurde |
nStartFace | Angabe der Fläche auf der die Buttons platziert werden sollen (Startpunkt) |
nEndFace | Angabe der Fläche auf der die Buttons platziert werden sollen (Endpunkt) |
nStartIndex | Angabe der Linie auf der angegebenen Fläche (Startpunkt) |
nEndIndex | Angabe der Linie auf der angegebenen Fläche (Endpunkt) |
bShowFix | Soll der Button immer sichtbar sein? |
nShrinkLine | Prozentangabe um wieviel sich die Buttons von aussen nach innen verschieben sollen (0-99) |
nShrinkFace | Prozentangabe um wieviel sich die Buttons ins Zentrum der Fläche bewegen sollen (0-99) |
nShrinkBox | Prozentangabe um wieviel sich die Buttons ins Zentrum des umhüllenden Quaders bewegen sollen (0-99) |
Beispiel
cButtonPos = ""
RUN PositionButton(cButtonPos, buttonLineUp, -1, -1, 6, 4, TRUE, 50, -1, -1)
RUN PositionButton(cButtonPos, buttonLineDown, -1, -1, 0, 2, TRUE, 50, -1, -1)
RUN PositionButton(cButtonPos, buttonLineLeft, -1, -1, 0, 6, TRUE, 50, -1, -1)
RUN PositionButton(cButtonPos, buttonLineRight, -1, -1, 2, 4, TRUE, 50, -1, -1)
RUN PositionButton(cButtonPos, buttonLineColor, -1, -1, -1, -1, FALSE, -1, -1, -1)
Schritt 5: Button mit Objekt verbinden (SetActionButton)
Der letzte Schritt ist nun die Buttons mit einem Objekt zu verbinden, sowie die Angabe der Procedure welche ausgeführt werden soll, wenn auf den Button geklickt wird. Dafür gibt es eine eigene zentrale Procedure:
RUN public\lib3D.SetActionButton(nObjID, "<Makroverzeichnis\Makroname.bas>", "<Prozedurename>", cButtonPos)
Beispiel
In unserem Fall sollen die Buttons auf das Objekt mit der ID 'nBoxID' gelegt werden. Die Prozedure namens 'EventButtonClicked' in 'McrButton.bas' soll beim Klicken auf die Buttons ausgeführt werden. Zusätzlich übergeben wir den String 'ButtonPos' welche zuvor mit 'PositionButton' erzeugt wurde:
RUN SetActionButton(nBoxID, "McrButtons.bas", "EventButtonClicked", cButtonPos)
In der Procedure wird als Übergabeparameter das Kommando sowie die Objekt-ID übergeben als String übergeben. Der Trenner ist immer Pipe. Der Anfang der Procedure muss daher immer so lauten:
PROCEDURE EventButtonClicked
DEFINE PARAMETER INPUT CommandAndObjectID
DEFINE VARIABLE cCommand, nObjID
cCommand = ENTRY(1,CommandAndObjectID,"|")
nObjID = VAL(ENTRY(2,CommandAndObjectID,"|")
Praxisbezogene Beispiele eines Events
Beispiel A (Klick auf Objekt)
Beim Klicken auf eine Bemaßungslinie wird der Focus des Frageparameters auf den entsprechenden Parameter geändert:
PROCEDURE EventChangeMeasure
DEFINE PARAMETER INPUT ObjectID
IF VAL(ObjectID) = nIDMeasureBoxB THEN ISS.CHANGEPARAMETERFOCUS("FpBoxBreite","001")
IF VAL(ObjectID) = nIDMeasureBoxH THEN ISS.CHANGEPARAMETERFOCUS("FpBoxHoehe","001")
END
Beispiel B (Klick auf Button)
Beim Klicken auf einen Button wird eine Erweiterte Information geöffnet:
PROCEDURE EventButtonInfo
DEFINE PARAMETER INPUT CommandObjectID
DEFINE VARIABLE cCommand, cObjID
cCommand = ENTRY(1,CommandObjectID,"|")
cObjID = ENTRY(2,CommandObjectID,"|")
IF VAL(cObjID) = nInfoBox1 THEN ISS.SHOWADDINF("ButtonInfo1")
IF VAL(cObjID) = nInfoBox2 THEN ISS.SHOWADDINF("ButtonInfo2")
END