diff --git a/Lisp/ssg_core.lsp b/Lisp/ssg_core.lsp index 298e43c..cfe95c8 100644 --- a/Lisp/ssg_core.lsp +++ b/Lisp/ssg_core.lsp @@ -1622,6 +1622,44 @@ ) +;; ------------------------------------------------------------ +;; DCL ZUR LAUFZEIT GENERIEREN +;; ------------------------------------------------------------ +;; Escaped Anfuehrungszeichen in einem DCL-Label-String ("->''), damit ein +;; Label mit Anfuehrungszeichen (z.B. aus Nutzerdaten oder Zoll-Angaben) die +;; DCL-Zeile nicht vorzeitig beendet. Fachlich identisch zu +;; geruest-dcl-label (GeruestInsert.lsp), aber hier als generischer +;; Kernel-Helfer fuer jeden Aufrufer, der DCL-Text zusammenbaut. +(defun ssg-dcl-label-escape (text / i c out) + (setq i 0 out "") + (while (< i (strlen text)) + (setq c (substr text (1+ i) 1)) + (setq out (strcat out (if (= c "\"") "''" c))) + (setq i (1+ i)) + ) + out +) + +;; Schreibt eine Liste von Textzeilen als temporaere DCL-Datei und liefert +;; deren Pfad zurueck (oder nil bei Fehler, z.B. wenn open scheitert). Der +;; Aufrufer ist fuer load_dialog/unload_dialog UND das Loeschen der Datei +;; (vl-file-delete) danach selbst verantwortlich - analog zum bestehenden +;; Muster in GeruestInsert.lsp (geruest-dcl-schreiben), hier nur als +;; generischer Baustein fuer WEITERE Aufrufer (GeruestInsert.lsp selbst +;; bleibt unveraendert, um dessen Code nicht anzufassen). +(defun ssg-dcl-temp-schreiben (praefix zeilen / pfad f) + (setq pfad (vl-filename-mktemp praefix nil ".dcl")) + (if (setq f (open pfad "w")) + (progn + (foreach zeile zeilen (write-line zeile f)) + (close f) + pfad + ) + nil + ) +) + + ;; ------------------------------------------------------------ ;; REKURSIVER JSON-PARSER ;; ------------------------------------------------------------ diff --git a/Lisp/vf_core.lsp b/Lisp/vf_core.lsp index ec18f05..a1db915 100644 --- a/Lisp/vf_core.lsp +++ b/Lisp/vf_core.lsp @@ -704,7 +704,8 @@ eingabe) (defun vf-eingabe-abfragen ( / eingabe-modus line-points startpunkt endpunkt differenz - deltaL deltaH deltaX deltaY richtung antwort hz-winkel) + deltaL deltaH deltaX deltaY richtung antwort hz-winkel + hoehe-override) ;; Eingabemodus: von einem Menue-Wrapper vorbelegt (dann keine Frage) oder ;; interaktiv. Die Vorauswahl gilt nur EINMAL und wird hier verbraucht, ;; damit ein spaeterer Direktaufruf wieder fragt. @@ -750,6 +751,17 @@ (progn (setq richtung "Ab") (setq deltaH (abs deltaH)) (princ (ssg-text "vfc-foerderrichtung-ab"))) ) + ;; Einfuegehoehe explizit abfragbar - ueberschreibt NUR die absolute + ;; Z-Hoehe des Startpunkts (Vorschlag = Z des Linien-Startpunkts, + ;; Enter uebernimmt ihn unveraendert). deltaH/Steigung bleiben davon + ;; unberuehrt, die kommen weiterhin aus der Geometrie der gepickten + ;; Linie selbst - nur WO die Anlage absolut eingefuegt wird, ist + ;; jetzt eingebbar (bisher ausschliesslich aus der Linie abgeleitet). + (setq hoehe-override + (getreal (ssg-textf "vfc-prompt-einfuegehoehe-3dlinie" + (list (rtos (caddr startpunkt) 2 1))))) + (if hoehe-override + (setq startpunkt (list (car startpunkt) (cadr startpunkt) hoehe-override))) ) (progn (princ (ssg-text "vfc-modus-werteingabe-header")) @@ -1055,12 +1067,64 @@ (list vf-insert vf-endpunkt) ) +;; Startpunkt der Anlage per Dialog waehlen (Punktwahl-Button + Anzeige, +;; dcl/variofoerderer.dcl Tile vfc_startpunkt) - dasselbe "Schliessen- +;; Picken-Neu-Zeigen"-Muster wie der Linienzug-Wizard +;; (vflw-gruppe-punkt-hoehe-impl, vf_linienzug.lsp:697), aber ohne dessen +;; Wizard-Pending-Queue: der Punkt wird direkt zurueckgegeben. kopf/ +;; pt_anzeige kommen per set_tile aus ssg-text - anders als +;; vfc-dialog-typ-waehlen also KEIN *ssg-lang*-Gate noetig, der Dialog +;; funktioniert in jeder Sprache. Rueckgabe: Punkt (Liste X Y Z) oder nil, +;; wenn kein Dialog gezeigt werden konnte/durfte (GUI aus) ODER abgebrochen +;; wurde - der Aufrufer (vf-dialog-ablauf) faellt dann auf den alten +;; Konsolen-getpoint zurueck. +(defun vfc-dialog-startpunkt-waehlen (kopf-key / dcl-pfad dat ergebnis gpunkt fertig) + (if (or (not (car (atoms-family 1 '("SSG-GUI-P")))) (ssg-gui-p)) + (progn + (setq fertig nil) + (while (not fertig) + (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl")) + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "vfc_startpunkt" dat)) + (progn + (if (and dat (>= dat 0)) (unload_dialog dat)) + (setq fertig t gpunkt nil) + ) + (progn + (set_tile "kopf" (ssg-text "vfc-dlg-startpunkt-kopf")) + (if gpunkt + (set_tile "pt_anzeige" + (strcat "X=" (rtos (car gpunkt) 2 1) + " Y=" (rtos (cadr gpunkt) 2 1) + " Z=" (rtos (caddr gpunkt) 2 1))) + ) + (action_tile "pick" "(done_dialog 2)") + (action_tile "accept" "(done_dialog 1)") + (action_tile "cancel" "(done_dialog 0)") + (setq ergebnis (start_dialog)) + (unload_dialog dat) + (cond + ((= ergebnis 2) (setq gpunkt (getpoint (ssg-text kopf-key)))) + ((= ergebnis 1) (setq fertig t)) + (t (setq fertig t gpunkt nil)) + ) + ) + ) + ) + gpunkt + ) + nil + ) +) + ;; Neuanlage (Menue/Konsole -> Dialog) fuer einen Registry-Typ: Startpunkt ;; (X/Y) picken, Basis-Dialog, dann vf-dialog-berechnen-einfuegen. (defun vf-dialog-ablauf (typ vf-nummer horizontal-p / eingabe deltaL deltaH richtung z-start hz seite startpunkt startpunkt-xy dim geruest-einzelmodul geruest-typ motorseite) - (setq startpunkt-xy (getpoint (ssg-text "vfc-prompt-startpunkt-aus"))) + (setq startpunkt-xy (vfc-dialog-startpunkt-waehlen "vfc-prompt-startpunkt-aus")) + (if (null startpunkt-xy) + (setq startpunkt-xy (getpoint (ssg-text "vfc-prompt-startpunkt-aus")))) (if (null startpunkt-xy) (setq startpunkt-xy '(0 0 0))) (setq eingabe (vfs-dialog-eingabe-basis nil)) (if (null eingabe) diff --git a/Lisp/vf_standard.lsp b/Lisp/vf_standard.lsp index 99e8daf..9f11549 100644 --- a/Lisp/vf_standard.lsp +++ b/Lisp/vf_standard.lsp @@ -808,6 +808,19 @@ ;; zwei DCL-Dialoge: Basis-Eingabe und Winkel/Verteilung. Die ;; 3D-Linie-Eingabe sowie die Typen "etage"/"linienzug" bleiben ;; unveraendert interaktiv (siehe Verzweigung in c:VarioFoerderer). +;; +;; Beide Dialoge existieren je in zwei Varianten: +;; -popup (Dropdowns, urspruengliche Implementierung, unveraendert) und +;; -radio (Radio-Buttons statt Dropdown). Radio-Button-Labels lassen sich +;; nach new_dialog nicht per set_tile aendern (DCL-Limitierung) - die +;; -radio-Varianten loesen das, indem sie ihre DCL-Datei bei JEDEM Aufruf +;; frisch per ssg-dcl-temp-schreiben (ssg_core.lsp) schreiben und die +;; Labels dabei direkt mit dem schon von ssg-text/ssg-textf aufgeloesten +;; String befuellen - funktioniert dadurch in jeder Sprache, keine +;; Sprachweiche noetig (anders als vfc-dialog-typ-waehlen). Die +;; namenlosen Dispatcher-Funktionen (ohne Suffix) bevorzugen -radio und +;; fallen nur bei einem technischen Fehler (Temp-Datei nicht schreibbar/ +;; ladbar, Sentinel 'FEHLER) auf -popup zurueck. ;; ============================================================ ;; Bau-Parameter eines bestehenden VF_n-Blocks aus XDATA + Attributen lesen - @@ -846,14 +859,76 @@ (cons "hz" hz) (cons "z-start" z-start))) -;; Basis-Eingabe (Dialog 1): deltaL, deltaH, Richtung, Einfuegehoehe, -;; Fahrtrichtung, Seite, Geruest fuer Einzelmodul, Geruestoption. +;; Baut die DCL-Zeilen einer boxed_radio_column mit einem radio_button pro +;; Eintrag in "labels" (Tile-Keys "_0".."_(n-1)"). labels +;; sind bereits fertige, uebersetzte Strings (ssg-text/ssg-textf) - werden +;; hier nur noch fuer die DCL-Syntax escaped (ssg-dcl-label-escape). +;; Gemeinsam genutzt von vfs-dialog-eingabe-basis-radio UND +;; vfs-dialog-winkel-verteilung-radio. +(defun vfs-dcl-radio-gruppe-zeilen (prefix box-label labels / zeilen i) + (setq zeilen (list + ": boxed_radio_column {" + (strcat " label = \"" (ssg-dcl-label-escape box-label) "\";") + (strcat " key = \"" prefix "\";"))) + (setq i 0) + (foreach lbl labels + (setq zeilen (append zeilen (list + (strcat " : radio_button { key = \"" prefix "_" (itoa i) "\"; label = \"" + (ssg-dcl-label-escape lbl) "\"; }")))) + (setq i (1+ i)) + ) + (append zeilen (list "}")) +) + +;; Baut das (cond ...)-Fragment (als String), das innerhalb eines +;; action_tile-Callbacks den gewaehlten Index 0..(n-1) einer per +;; vfs-dcl-radio-gruppe-zeilen erzeugten Gruppe ermittelt. n ist die +;; tatsaechliche Options-Anzahl zum Generierungszeitpunkt - dadurch bleibt +;; z.B. die Geruesttyp- oder Winkel-Gruppe korrekt, auch wenn deren Anzahl +;; sich einmal aendert (kein hartkodiertes "_1"/"_2"/"_3" im Aufrufer). +(defun vfs-dcl-radio-idx-cond (prefix n / s i) + (setq s "(cond " i 1) + (while (< i n) + (setq s (strcat s "((= (get_tile \"" prefix "_" (itoa i) "\") \"1\") " (itoa i) ")")) + (setq i (1+ i)) + ) + (strcat s "(t 0))") +) + +;; L_GF1/L_GF2 aus dem gewaehlten Verteilungsmodus ("0".."3") berechnen - +;; gemeinsam genutzt von der Popup- UND der Radio-Variante von +;; vfs-dialog-winkel-verteilung (frueher inline in beiden dupliziert). +;; Rueckgabe: (L_GF1 L_GF2). +(defun vfs-verteilung-berechnen (verteilung-modus L_GF staustrecke-basis lgf1-manuell-str / + L_GF1 L_GF2) + (cond + ((= verteilung-modus "0") + (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) + ((= verteilung-modus "1") + (setq L_GF1 (float staustrecke-basis)) + (setq L_GF2 (max 0.0 (- L_GF (float staustrecke-basis))))) + ((= verteilung-modus "2") + (setq L_GF2 (float staustrecke-basis)) + (setq L_GF1 (max 0.0 (- L_GF (float staustrecke-basis))))) + ((= verteilung-modus "3") + (setq L_GF1 (atof lgf1-manuell-str)) + (if (or (null L_GF1) (< L_GF1 0)) (setq L_GF1 (/ L_GF 2.0))) + (if (> L_GF1 L_GF) (setq L_GF1 L_GF)) + (setq L_GF2 (max 0.0 (- L_GF L_GF1)))) + (t (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) + ) + (list L_GF1 L_GF2) +) + +;; Basis-Eingabe (Dialog 1, Popup-Variante): deltaL, deltaH, Richtung, +;; Einfuegehoehe, Fahrtrichtung, Seite, Geruest fuer Einzelmodul, +;; Geruestoption. ;; prefill: Assoziationsliste zur Vorbelegung (fuer VARIOFOERDERER_EDIT) mit ;; Schluesseln "deltaL" "deltaH" "richtung" "einfuegehoehe" "hz" "seite" ;; "geruest-einzelmodul" "geruest-typ" - oder nil fuer Neuanlage mit Defaults. ;; Rueckgabe: (deltaL deltaH richtung einfuegehoehe hz seite ;; geruest-einzelmodul geruest-typ) oder nil bei Abbruch. -(defun vfs-dialog-eingabe-basis (prefill / dcl-pfad dat ergebnis +(defun vfs-dialog-eingabe-basis-popup (prefill / dcl-pfad dat ergebnis dlg-deltal dlg-deltah dlg-richtung dlg-hoehe dlg-fahrtrichtung dlg-seite dlg-motorseite dlg-dimension dlg-geruest-einzelmodul dlg-geruest-typ @@ -973,17 +1048,169 @@ ) ) -;; Winkel/Verteilung-Eingabe (Dialog 2): Winkel-Popup aus den vorher +;; Basis-Eingabe (Dialog 1, Radio-Button-Variante) - siehe Kopfkommentar +;; des DCL-DIALOG-Abschnitts. Gleiche prefill-Struktur/Rueckgabe wie +;; -popup; 'FEHLER bei technischem Fehler (Dispatcher faellt dann zurueck). +(defun vfs-dialog-eingabe-basis-radio (prefill / zeilen dcl-pfad dat ergebnis + dlg-deltal dlg-deltah dlg-hoehe + dlg-richtung-idx dlg-fahrt-idx dlg-seite-idx + dlg-motorseite-idx dlg-dim-idx + dlg-geruest-einzelmodul dlg-geruest-typ-idx + deltaL deltaH richtung hz seite z-start dim + motorseite geruest-einzelmodul geruest-typ + sel-richtung sel-fahrt sel-seite sel-motorseite + sel-dim sel-geruest-typ n-geruest-typ) + ;; Vorbelegte Auswahl-Indizes aus prefill ableiten - gleiche Logik wie + ;; -popup, nur als Index statt als Popup-Tile-Wert. + (setq sel-richtung + (if (and prefill (equal (cdr (assoc "richtung" prefill)) "Ab")) 1 0)) + (setq sel-fahrt + (if prefill + (cond ((equal (cdr (assoc "hz" prefill)) 90.0 0.1) 1) + ((equal (cdr (assoc "hz" prefill)) 180.0 0.1) 2) + ((equal (cdr (assoc "hz" prefill)) 270.0 0.1) 3) + (t 0)) + 0)) + (setq sel-seite + (if (and prefill (equal (cdr (assoc "seite" prefill)) "links")) 1 0)) + (setq sel-motorseite + (if (and prefill (equal (cdr (assoc "motorseite" prefill)) "links")) 1 0)) + (setq sel-dim + (if (equal (cond ((cdr (assoc "dim" prefill))) ((ssg-ils-dim-aktuell))) "2D") 1 0)) + (setq n-geruest-typ (length *ssg-geruest-optionen*)) + (setq sel-geruest-typ + (ssg-geruest-typ-to-idx (if prefill (cdr (assoc "geruest-typ" prefill)) nil))) + + (setq zeilen (list + "vfs_basis_dyn : dialog {" + " label = \"VarioFoerderer (Standard) - Eingabe\";" + " : column {" + " : boxed_column {" + " label = \"Geometrie\";" + " : row {" + " : edit_box { key = \"deltal\"; label = \"Horizontale Distanz deltaL (mm):\"; edit_width = 10; }" + " : edit_box { key = \"deltah\"; label = \"Hoehenunterschied deltaH (mm):\"; edit_width = 10; }" + " }")) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "richtung" "Foerderrichtung:" + (list (ssg-text "vfs-dlg-richtung-auf") (ssg-text "vfs-dlg-richtung-ab"))))) + (setq zeilen (append zeilen (list + " : edit_box { key = \"einfuegehoehe\"; label = \"Einfuegehoehe (mm):\"; edit_width = 10; }" + " }" + " : boxed_column {" + " label = \"Ausrichtung\";"))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "fahrtrichtung" "Fahrtrichtung:" + (list (ssg-textf "gf-dlg-richtung-0" (list grad-zeichen)) + (ssg-textf "gf-dlg-richtung-90" (list grad-zeichen)) + (ssg-textf "gf-dlg-richtung-180" (list grad-zeichen)) + (ssg-textf "gf-dlg-richtung-270" (list grad-zeichen)))))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "seite" "Seite:" + (list (ssg-text "gf-dlg-rechts") (ssg-text "gf-dlg-links"))))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "motorseite" "Motorseite:" + (list (ssg-text "gf-dlg-rechts") (ssg-text "gf-dlg-links"))))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "dimension" "Darstellung (2D/3D):" (list "3D" "2D")))) + (setq zeilen (append zeilen (list + " }" + " : boxed_column {" + " label = \"Geruest\";" + " : toggle { key = \"geruest_einzelmodul\"; label = \"Geruest fuer Einzelmodul\"; }"))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "geruest_typ" "Geruestoption:" *ssg-geruest-optionen*))) + (setq zeilen (append zeilen (list + " }" + " }" + " ok_cancel;" + "}"))) + + (setq dcl-pfad (ssg-dcl-temp-schreiben "vfsbasis" zeilen)) + (if (null dcl-pfad) + 'FEHLER + (progn + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "vfs_basis_dyn" dat)) + (progn + (if (and dat (>= dat 0)) (unload_dialog dat)) + (vl-file-delete dcl-pfad) + 'FEHLER + ) + (progn + (set_tile "deltal" (if prefill (rtos (cdr (assoc "deltaL" prefill)) 2 0) "15000")) + (set_tile "deltah" (if prefill (rtos (cdr (assoc "deltaH" prefill)) 2 0) "3000")) + (set_tile "einfuegehoehe" (if prefill (rtos (cdr (assoc "einfuegehoehe" prefill)) 2 1) "0")) + (set_tile (strcat "richtung_" (itoa sel-richtung)) "1") + (set_tile (strcat "fahrtrichtung_" (itoa sel-fahrt)) "1") + (set_tile (strcat "seite_" (itoa sel-seite)) "1") + (set_tile (strcat "motorseite_" (itoa sel-motorseite)) "1") + (set_tile (strcat "dimension_" (itoa sel-dim)) "1") + (set_tile "geruest_einzelmodul" + (if (or (null prefill) (equal (cdr (assoc "geruest-einzelmodul" prefill)) "1")) "1" "0")) + (set_tile (strcat "geruest_typ_" (itoa sel-geruest-typ)) "1") + + (action_tile "accept" + (strcat + "(setq dlg-deltal (get_tile \"deltal\"))" + "(setq dlg-deltah (get_tile \"deltah\"))" + "(setq dlg-hoehe (get_tile \"einfuegehoehe\"))" + "(setq dlg-richtung-idx " (vfs-dcl-radio-idx-cond "richtung" 2) ")" + "(setq dlg-fahrt-idx " (vfs-dcl-radio-idx-cond "fahrtrichtung" 4) ")" + "(setq dlg-seite-idx " (vfs-dcl-radio-idx-cond "seite" 2) ")" + "(setq dlg-motorseite-idx " (vfs-dcl-radio-idx-cond "motorseite" 2) ")" + "(setq dlg-dim-idx " (vfs-dcl-radio-idx-cond "dimension" 2) ")" + "(setq dlg-geruest-einzelmodul (get_tile \"geruest_einzelmodul\"))" + "(setq dlg-geruest-typ-idx " (vfs-dcl-radio-idx-cond "geruest_typ" n-geruest-typ) ")" + "(done_dialog 1)" + ) + ) + (action_tile "cancel" "(done_dialog 0)") + + (setq ergebnis (start_dialog)) + (unload_dialog dat) + (vl-file-delete dcl-pfad) + + (if (= ergebnis 1) + (progn + (setq deltaL (atof dlg-deltal)) + (setq deltaH (atof dlg-deltah)) + (setq richtung (nth dlg-richtung-idx '("Auf" "Ab"))) + (setq z-start (atof dlg-hoehe)) + (setq hz (nth dlg-fahrt-idx '(0.0 90.0 180.0 270.0))) + (setq seite (nth dlg-seite-idx '("rechts" "links"))) + (setq motorseite (nth dlg-motorseite-idx '("rechts" "links"))) + (setq dim (nth dlg-dim-idx '("3D" "2D"))) + (setq geruest-einzelmodul dlg-geruest-einzelmodul) + (setq geruest-typ (ssg-geruest-idx-to-typ dlg-geruest-typ-idx)) + (list deltaL deltaH richtung z-start hz seite dim geruest-einzelmodul geruest-typ motorseite) + ) + nil + ) + ) + ) + ) + ) +) + +;; Dispatcher: bevorzugt die Radio-Button-Variante (siehe Kopfkommentar des +;; DCL-DIALOG-Abschnitts), Rueckfall auf -popup nur bei technischem Fehler. +(defun vfs-dialog-eingabe-basis (prefill / ergebnis) + (setq ergebnis (vfs-dialog-eingabe-basis-radio prefill)) + (if (eq ergebnis 'FEHLER) (vfs-dialog-eingabe-basis-popup prefill) ergebnis) +) + +;; Winkel/Verteilung-Eingabe (Dialog 2, Popup-Variante): Winkel-Popup aus den vorher ;; berechneten gueltigen Varianten (gueltige-winkel/ergebnis-liste, siehe ;; berechne-alle-winkel), plus L_GF-Verteilung vorne/hinten (analog Schritt ;; 8+9 in c:VarioFoerderer). ;; prefill: Assoziationsliste ("winkel" . best-winkel) ("verteilung-idx" . "0".."3") ;; ("lgf1" . mm) - oder nil fuer Vorbelegung mit dem kleinsten gueltigen Winkel. ;; Rueckgabe: (best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus) oder nil bei Abbruch. -(defun vfs-dialog-winkel-verteilung (gueltige-winkel ergebnis-liste staustrecke-basis prefill / +(defun vfs-dialog-winkel-verteilung-popup (gueltige-winkel ergebnis-liste staustrecke-basis prefill / dcl-pfad dat ergebnis w eintrag idx sel-idx init-verteilung dlg-winkel dlg-verteilung dlg-lgf1 - best-winkel L_GF L_VF verteilung-modus L_GF1 L_GF2) + best-winkel L_GF L_VF verteilung-modus L_GF1 L_GF2 lgf-paar) (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl")) (setq dat (load_dialog dcl-pfad)) (if (not (new_dialog "variofoerderer_winkel" dat)) @@ -1052,22 +1279,8 @@ (setq eintrag (assoc best-winkel ergebnis-liste)) (setq L_GF (nth 1 eintrag) L_VF (nth 2 eintrag)) (setq verteilung-modus dlg-verteilung) - (cond - ((= verteilung-modus "0") - (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) - ((= verteilung-modus "1") - (setq L_GF1 (float staustrecke-basis)) - (setq L_GF2 (max 0.0 (- L_GF (float staustrecke-basis))))) - ((= verteilung-modus "2") - (setq L_GF2 (float staustrecke-basis)) - (setq L_GF1 (max 0.0 (- L_GF (float staustrecke-basis))))) - ((= verteilung-modus "3") - (setq L_GF1 (atof dlg-lgf1)) - (if (or (null L_GF1) (< L_GF1 0)) (setq L_GF1 (/ L_GF 2.0))) - (if (> L_GF1 L_GF) (setq L_GF1 L_GF)) - (setq L_GF2 (max 0.0 (- L_GF L_GF1)))) - (t (setq L_GF1 (/ L_GF 2.0) L_GF2 (/ L_GF 2.0))) - ) + (setq lgf-paar (vfs-verteilung-berechnen verteilung-modus L_GF staustrecke-basis dlg-lgf1)) + (setq L_GF1 (car lgf-paar) L_GF2 (cadr lgf-paar)) (list best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus) ) nil @@ -1076,6 +1289,131 @@ ) ) +;; Winkel/Verteilung-Eingabe (Dialog 2, Radio-Button-Variante) - siehe +;; Kopfkommentar des DCL-DIALOG-Abschnitts. Gleiche prefill-Struktur/ +;; Rueckgabe wie -popup; 'FEHLER bei technischem Fehler. +(defun vfs-dialog-winkel-verteilung-radio (gueltige-winkel ergebnis-liste staustrecke-basis prefill / + zeilen dcl-pfad dat ergebnis w eintrag labels + sel-winkel sel-verteilung idx toggle-zeile i + dlg-winkel-idx dlg-verteilung-idx dlg-lgf1 + best-winkel L_GF L_VF verteilung-modus L_GF1 L_GF2 lgf-paar) + ;; Winkel-Labels vorab aufloesen - gleiche Texte wie im Popup. + (setq labels nil) + (foreach w gueltige-winkel + (setq eintrag (assoc w ergebnis-liste)) + (setq labels (append labels (list + (if (= w 0) + (ssg-textf "vfs-dlg-winkel-horizontal" + (list (rtos (nth 1 eintrag) 2 1) (rtos (nth 2 eintrag) 2 1))) + (ssg-textf "vfs-dlg-winkel-option" + (list (itoa w) grad-zeichen (rtos (nth 1 eintrag) 2 1) (rtos (nth 2 eintrag) 2 1))) + ))) + ) + ) + + ;; Vorbelegung: Winkel aus prefill (falls noch gueltig), sonst erster + ;; (kleinster) gueltiger Winkel - analog der automatischen Konsolen-Wahl. + (setq sel-winkel 0 idx 0) + (if prefill + (foreach w gueltige-winkel + (if (equal w (cdr (assoc "winkel" prefill))) (setq sel-winkel idx)) + (setq idx (1+ idx)) + ) + ) + (setq sel-verteilung + (if prefill (atoi (cdr (assoc "verteilung-idx" prefill))) 0)) + + (setq zeilen (list + "vfs_winkel_dyn : dialog {" + " label = \"VarioFoerderer (Standard) - Winkel / Verteilung\";" + " : column {")) + (setq zeilen (append zeilen (vfs-dcl-radio-gruppe-zeilen "winkel" "Winkel:" labels))) + (setq zeilen (append zeilen (list + " : boxed_column {" + " label = \"Verteilung Gefaellestrecken (vorne/hinten)\";"))) + (setq zeilen (append zeilen + (vfs-dcl-radio-gruppe-zeilen "verteilung" "Modus:" + (list (ssg-text "vfs-dlg-verteilung-1") (ssg-text "vfs-dlg-verteilung-2") + (ssg-text "vfs-dlg-verteilung-3") (ssg-text "vfs-dlg-verteilung-4"))))) + (setq zeilen (append zeilen (list + " : edit_box { key = \"lgf1_manuell\"; label = \"L_GF1 vorne (mm):\"; edit_width = 10; }" + " }" + " }" + " ok_cancel;" + "}"))) + + (setq dcl-pfad (ssg-dcl-temp-schreiben "vfswinkel" zeilen)) + (if (null dcl-pfad) + 'FEHLER + (progn + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "vfs_winkel_dyn" dat)) + (progn + (if (and dat (>= dat 0)) (unload_dialog dat)) + (vl-file-delete dcl-pfad) + 'FEHLER + ) + (progn + (set_tile (strcat "winkel_" (itoa sel-winkel)) "1") + (set_tile (strcat "verteilung_" (itoa sel-verteilung)) "1") + (set_tile "lgf1_manuell" + (if (and prefill (cdr (assoc "lgf1" prefill))) + (rtos (cdr (assoc "lgf1" prefill)) 2 1) "0")) + (mode_tile "lgf1_manuell" (if (= sel-verteilung 3) 0 1)) + + ;; Jedes der 4 Verteilung-Radio-Tiles braucht sein EIGENES + ;; action_tile (haengt bei Radio-Buttons nicht am Gruppen-Key wie + ;; bisher am popup_list-Key "verteilung"). + (setq toggle-zeile + "(mode_tile \"lgf1_manuell\" (if (= (get_tile \"verteilung_3\") \"1\") 0 1))") + (setq i 0) + (while (< i 4) + (action_tile (strcat "verteilung_" (itoa i)) toggle-zeile) + (setq i (1+ i)) + ) + + (action_tile "accept" + (strcat + "(setq dlg-winkel-idx " (vfs-dcl-radio-idx-cond "winkel" (length gueltige-winkel)) ")" + "(setq dlg-verteilung-idx " (vfs-dcl-radio-idx-cond "verteilung" 4) ")" + "(setq dlg-lgf1 (get_tile \"lgf1_manuell\"))" + "(done_dialog 1)" + ) + ) + (action_tile "cancel" "(done_dialog 0)") + + (setq ergebnis (start_dialog)) + (unload_dialog dat) + (vl-file-delete dcl-pfad) + + (if (= ergebnis 1) + (progn + (setq best-winkel (nth dlg-winkel-idx gueltige-winkel)) + (setq eintrag (assoc best-winkel ergebnis-liste)) + (setq L_GF (nth 1 eintrag) L_VF (nth 2 eintrag)) + (setq verteilung-modus (itoa dlg-verteilung-idx)) + (setq lgf-paar (vfs-verteilung-berechnen verteilung-modus L_GF staustrecke-basis dlg-lgf1)) + (setq L_GF1 (car lgf-paar) L_GF2 (cadr lgf-paar)) + (list best-winkel L_GF L_VF L_GF1 L_GF2 verteilung-modus) + ) + nil + ) + ) + ) + ) + ) +) + +;; Dispatcher: bevorzugt die Radio-Button-Variante (siehe Kopfkommentar des +;; DCL-DIALOG-Abschnitts), Rueckfall auf -popup nur bei technischem Fehler. +(defun vfs-dialog-winkel-verteilung (gueltige-winkel ergebnis-liste staustrecke-basis prefill / ergebnis) + (setq ergebnis (vfs-dialog-winkel-verteilung-radio gueltige-winkel ergebnis-liste staustrecke-basis prefill)) + (if (eq ergebnis 'FEHLER) + (vfs-dialog-winkel-verteilung-popup gueltige-winkel ergebnis-liste staustrecke-basis prefill) + ergebnis + ) +) + ;; ============================================================ ;; XDATA-Metadaten fuer den Edit-Nachbau (App "SSG_VF_EDIT"). ;; Markiert ein VF_n-INSERT als "mit dem Standard-Dialog erstellt" und diff --git a/dcl/variofoerderer.dcl b/dcl/variofoerderer.dcl index ef475a9..e47686c 100644 --- a/dcl/variofoerderer.dcl +++ b/dcl/variofoerderer.dcl @@ -5,12 +5,21 @@ // Konsolen-Liste am Befehlsanfang. Radio-Buttons statt Dropdown, daher // Labels FEST auf Deutsch (siehe Kommentar bei vfc_linienzug_modus). // vfc_linienzug_modus: NUR bei Typ "Linienzug" - Modus 1/2/3 waehlen. -// variofoerderer_basis/variofoerderer_winkel: Werteingabe fuer den -// Standardfall (anlage-typ "standard"): deltaL, deltaH, Foerderrichtung, -// Einfuegehoehe, Fahrtrichtung, Seite, Winkel, GF-Verteilung. -// Die 3D-Linie-Eingabe (Modus "3D-Linie"), der Etage-Typ und die -// Linienzug-Kette selbst (nach der Modus-Wahl) bleiben interaktiv -// (Kommandozeile bzw. eigener Wizard in vf_linienzug_wizard.dcl). +// vfc_startpunkt: Startpunkt der Anlage picken (Punktwahl-Button + +// X/Y/Z-Anzeige) - ersetzt den reinen Konsolen-getpoint fuer +// Standard UND Etage (vfc-dialog-startpunkt-waehlen, vf_core.lsp). +// variofoerderer_basis/variofoerderer_winkel: Popup-Fallback-Varianten +// der Werteingabe (deltaL, deltaH, Foerderrichtung, Einfuegehoehe, +// Fahrtrichtung, Seite, Motorseite, Dimension, Geruest, Winkel, +// GF-Verteilung) - gemeinsam genutzt von Standard UND Etage. Die +// bevorzugten Radio-Button-Varianten (vfs_basis_dyn/vfs_winkel_dyn) +// werden zur Laufzeit generiert (vfs-dialog-eingabe-basis-radio/ +// vfs-dialog-winkel-verteilung-radio in vf_standard.lsp) und stehen +// NICHT in dieser Datei - diese beiden Dialoge hier sind nur noch der +// Fallback, falls das Schreiben/Laden der Temp-DCL-Datei mal scheitert. +// Die 3D-Linie-Eingabe (Modus "3D-Linie") und die Linienzug-Kette selbst +// (nach der Modus-Wahl) bleiben interaktiv (Kommandozeile bzw. eigener +// Wizard in vf_linienzug_wizard.dcl). // ============================================================ // Anlagen-Typ waehlen (Standard/Etage/Linienzug). Radio-Buttons statt @@ -101,6 +110,45 @@ vfc_linienzug_modus : dialog { } } +// Startpunkt der Anlage waehlen - Punktwahl-Button + Anzeige, analog +// vflw_punkt_zahl (dcl/vf_linienzug_wizard.dcl): der Button schliesst den +// Dialog (done_dialog 2), DANACH laeuft getpoint auf der Kommandozeile +// (aus einem action_tile-Callback heraus funktioniert getpoint in BricsCAD +// nicht), der Dialog wird danach mit der Anzeige erneut aufgebaut. "kopf" +// und "pt_anzeige" werden per set_tile aus ssg-text befuellt (siehe +// vfc-dialog-startpunkt-waehlen, vf_core.lsp) - deshalb sprachunabhaengig +// nutzbar. Button-Chrome bleibt hart deutsch, wie im Rest dieser Datei. +vfc_startpunkt : dialog { + label = "VarioFoerderer - Startpunkt"; + + : column { + : text { + key = "kopf"; + label = ""; + width = 50; + } + : row { + : button { + key = "pick"; + label = "Punkt waehlen..."; + fixed_width = true; + width = 18; + } + : text { + key = "pt_anzeige"; + label = "(kein Punkt gewaehlt)"; + } + } + } + + : row { + alignment = centered; + : button { key = "accept"; label = "Ok Weiter"; is_default = true; fixed_width = true; width = 12; } + spacer; + : button { key = "cancel"; label = "Abbrechen"; is_cancel = true; fixed_width = true; width = 12; } + } +} + variofoerderer_basis : dialog { label = "VarioFoerderer (Standard) - Eingabe";