Zitat:
Original erstellt von Brischke:
[..] Ich halte eine derartige Vorgehensweise jedoch nicht für so gut.
Ich auch nicht.
Zitat:
[..] Lass es dir durch den Kopf gehen. Auch wenn es am Anfang etwas mehr Aufwand bedeutet - es zahlt sich am Ende aus.
Das kann ich nur unterstützen. Ich versuche innerhalb meiner Programme die Dialogsteuerung um 4 Variablen herum zu stricken:
ValueList - Assoziations-Liste zum Vorhalten aller Dialog-relevanten Werte
RescueList - Assoziations-Liste zum Vorhalten aller relevanten DialogBox-Inhalte
ModeList - Assoziations-Liste zum Vorhalten aller relevanten "mode_tile"s
ComponentList - Assoziations-Liste zum Vorhalten aller DCL-Keys
In allen Fällen gibt's da noch meiner Faulheit zu verdankende Hilfsfunktionen, die jeweils Werte aus diesen Variablen heraus bzw. in diese Variablen hinein stecken. Die sehen dann so aus:
(:RList->"eb_x") - holt den der DCL-Komponente "eb_x" zugeordneten Wert
(:->RList"eb_x" "1.0") - setzt eben diesen Wert auf "1.0"
Analog funktionieren :->VList, :VList->, :->MList und :MList->.
ComponentList ist hier nur eine Liste, in der Informationen für :dcl-leaveDialog (zumindest in diesem Fall hier) vorgehalten werden. Hier werden also nur alle Dialog-Comonenten-Keys gespeichert.
Ein kleines Beispiel kann vielleicht die Idee illustrieren: (Allerdings hab' ich gemerkt, dass es gar nicht klein bleiben kann, so sehr ich mich auch bemühe. Da fehlen jetzt sicher ein paar Funktions-Definitionen, aber die meisten wurden hier schon so oder so ähnlich erklärt)
Code:
(defun fuehre_dd_punktAuswahl (#dclID ValueList RescueList ModeList
/ ComponentList
dclStatus
;**** lokal deklarierte Funktionen ****
buildPunkt!
)
;**** lokal deklarierte Funktionen ****
(defun buildPunkt! ( / );** das lässt sich besser in einem Bibliotheks-Gesamt-Konzept unterbringen
;** aber hier will ich mal nicht all zu sehr übertreiben
(:->VList'Punkt
(mapcar'atof
(mapcar':RList->'("eb_x""eb_y""eb_z"))
)
)
); end DEFUN <buildPunkt!>
;**** lokal deklarierte Funktionen ****
;**** Initialisierung ****
(setq dclStatus'auf-gehts)
(:dclInitVal-get_point)
;**** Initialisierung ****
;**** Dialog-Loop ****
(while dclStatus
;**** Dialog initialisieren ... ****
(:dcl-newDialog "punktauswahl" #dclID)
(:dclInit-get_point (:VList->'Punkt))
(action_tile "accept" "(:dcl-leaveDialog 1)")
(action_tile "cancel" "(:dcl-leaveDialog 0)")
(:apply-map'set_tile RescueList)
(:apply-map'mode_tile ModeList)
;**** ... und starten ****
(setq dclStatus (start_dialog))
(cond
((= 8 dclStatus);** by <get_point>
;**** darf ruhig verbessert werden - vor allen Dingen fehlt ABBRUCH-Kontrolle ****
(:dclSet-get_point (getpoint"\nPunkt wählen:"))
)
((= 0 dclStatus);** by <cancel>
(setq ValueList nil);** dann wird eben nix zurück gegeben
(setq dclStatus nil) ;** und noch einen Durchlauf braucht's auch nicht
)
((= 1 dclStatus);** by <accept>
(buildPunkt!)
(setq dclStatus nil);** und fertig
)
)
)
(:return ValueList)
); end DEFUN <fuehre_dd_punktAuswahl>
Ein Aufruf könnte z.B. so aussehen:
Code:
; ...
(setq dialog-ID (:dcl-load "eine-Datei-mit-sowas-wie-unten.DCL"))
; ...
(fuehre_dd_punktAuswahl
dialog-ID
'((Punkt 1 0 0));** 's ist nur ein Beispiel
nil
nil
)
; ...
(unload_dcl dialog-ID)
Ich denke mal, das schießt u.U. ordendlich über's Ziel hinaus, zeigt aber, was eigendlich da sein muss, um anschließend flott DCL-Dialoge programmieren zu können - finde ich zumindest. Vor allen Dinge habe ich gemerkt, dass es gar nicht so einfach ist, ein Beispiel für ein solches Konzept in aller Kürze aufzuschreiben - insbesondere, wenn all der Bibliotheks-Teil auch noch aufgeführt werden muss. Einen Teil davon will ich hier noch als eine Art PS anhängen. Wichtig ist aber, dass gerde der Abschnitt oberhalb zeigt, wie glatt - und vor allen Dingen knapp - alles mit der nötigen Vorarbeit laufen kann.
Achim Dabrunz
.. und hier noch die Mini-DCL-Datei:
Code:
//
// SEGMENT : get_point
//
get_point :column {
key = "seg_get_point";
label = " Einfügepunkt ";
fixed_height = true;
:button{label = "&Punkt wählen <"; key = "b_getpoint";}
:edit_box{label = "&X:"; key = "eb_x"; edit_width = 10;}
:edit_box{label = "&Y:"; key = "eb_y"; edit_width = 10;}
:edit_box{label = "&Z:"; key = "eb_z"; edit_width = 10;}
spacer_1;
}// end SEGMENT <get_point>punktauswahl: dialog{
label = "kleine Demo";
:column{
get_point;
ok_cancel;
errtile;
}
}
.. und eine Hand voll Bibliotheks-Funktionen - da fehlen sicher noch einige, aber die sind flott selbst definiert oder müssen halt nochmal erfragt werden ..
Code:
;
;***************************************************
;**** Funktionen für die Dialog-Steuerung ****
;***************************************************
;
(defun :dclInit-get_point (#pnt / )
(action_tile "b_getpoint" "(:dcl-leaveDialog 8)")
(action_tile "eb_x" "(:dcl-Real?! $key $value'ueberschreiben)")
(action_tile "eb_y" "(:dcl-Real?! $key $value'ueberschreiben)")
(action_tile "eb_z" "(:dcl-Real?! $key $value'ueberschreiben)")
(:dclSet-get_point #pnt)
); end DEFUN <:dclInit-get_point>
(defun :dclInitVal-get_point ( / )
(:l-union!'ComponentList'("eb_x""eb_y""eb_z"))
); end DEFUN <:dclInitVal-get_point>
(defun :dclSet-get_point (#pnt / )
(mapcar':->RList
'("eb_x""eb_y""eb_z")
(mapcar':str-or-empty #pnt)
)
); end DEFUN <:dclSet-get_point>
;
;***********************************************************************************
;**** (:dcl-Real?! <DCL-Key> <Wert> <FLAG-überschreiben?> ) ****
;***********************************************************************************
;
(defun :dcl-Real?! (#key #value #overwriteOnError? / real-number)
(setq real-number (distof(vl-string-subst"."","(:?'#value'(get_tile #key)))))
(if real-number
(progn
(:dcl-error-clear)
(set_tile #key (rtos real-number 2 4))
(:->RList #key (get_tile #key))
(distof(:RList-> #key))
)
(progn
(:dcl-error"Ungültiger Wert : Zahl erwartet")
(if #overwriteOnError? (set_tile #key (:?'(:RList-> #key)"<ungültig>")))
(:dcl-SelectEB #key)
(:return nil)
)
)
); end DEFUN <:dcl-Real?!>
;
;***************************************************
;**** (:dcl-leaveDialog <done_dialog-No> ) ****
;**** überschreibt <RescueList> ****
;***************************************************
;
(defun :dcl-leaveDialog (#done / )
(setq RescueList
(:merge-AssL RescueList
(mapcar
'(lambda(x) (cons x (get_tile x)))
ComponentList
)
)
)
(if #done (done_dialog #done))
); end DEFUN <:dcl-leaveDialog>
;
;***************************************************
;**** (:dcl-error-clear) ****
;***************************************************
;
(defun :dcl-error-clear ()
(set_tile "error" "")
)
;
;***************************************************
;**** (:dcl-error <Error-Meldung> ) ****
;***************************************************
;
(defun :dcl-error (#msg)
(set_tile "error"#msg)
)
;
;***************************************************
;**** (:dcl-SelectEB <:dcl-Key> ) ****
;***************************************************
;
(defun :dcl-SelectEB (#key / )
(mode_tile #key 2)
(mode_tile #key 3)
); end DEFUN <:dcl-SelectEB>
;**** und noch 1-2 andere ****
;
;***************************************************
;**** (:str-or-empty <Zahl> ) ****
;***************************************************
;
(defun :str-or-empty (#zahl / )
(cond
((numberp #zahl)(rtos #zahl 2 4))
((:str? #zahl) #zahl)
('else "")
)
); end DEFUN <:str-or-empty>
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP