;;;Código fuente del libro "Experto AutoCAD con Visual LISP"
;;; (c) Ediciones ARTUAL, S.L. Barcelona, España.
;;; (c) 2012-2020 Reinaldo Togores. Todos los derechos reservados
;;; Se permite su uso mencionando la obra y su autor.
;;;CapÃtulo 22. DCL: La Interfaz Gráfica del Usuario.
(defun inicia-dialogo (nombredialogo archivodcl /)Â
  (if (not *Posicion*)Â
    (setq *Posicion* '(-1 -1)))
  (if (= -1 (setq dcl_id (load_dialog archivodcl)))Â
    (alert (strcat "No se encuentra el archivo\nde diálogo " archivodcl))
    (if (not (new_dialog nombredialogo dcl_id "" *Posicion*))Â
      (alertÂ
        (strcat "No se encuentra la \ndefinición de diálogo "Â
                nombredialogo))
      t)))
;;;Listado 22.2. Función para iniciar un diálogo cualquiera.
(defun inicia-imagen (clave imagen)Â
  (start_image clave)
  (fill_image 0 0 (dimx_tile "img") (dimy_tile "img") -2)
  (slide_image 0 0 (dimx_tile clave) (dimy_tile clave) imagen)
  (end_image))Â
;;;Listado 22.3. Función que carga una imagen SLD en un diálogo.
(defun formato-param (clave valor /)Â
  (set_tile clave (rtos (abs (atof valor)) 2 2)))Â
;;;Listado 22.4. Función que comprueba y da formato al valor introducido en la casillaÂ
(defun param-edit (clave valor razon / forma)Â
  (formato-param clave valor)
  (if (or (= razon 1) (= razon 2))Â
    (condÂ
      ((= (get_tile "nor") "1") ;caso Normal
       (test-normal clave))
      ((= (get_tile "nor") "0") ; otros casos
       (setq forma (form-sel))
       (test-otros forma)))))Â
;;;Listado 22.5. Acción de respuesta a las casillas de edición de parámetros.
(defun test-otros (forma / rad-a dim-x dim-y rad-c)Â
  (condÂ
    ((= forma "esf")
     (setq rad-a (atof (get_tile "ra")))
     (if (<= rad-a 0)Â
       (setq ok nil)
       (progn (setq ok t)Â
              (set_tile "dx" (rtos rad-a 2 2))
              (set_tile "dy" (rtos (* rad-a 2) 2 2)))))
    ((= forma "bar")
     (setq dim-x (atof (get_tile "dx"))
           dim-y (atof (get_tile "dy")))
     (if (or (<= dim-x 0) (<= dim-y 0))Â
       (setq ok nil)
       (setq ok t)))
    ((= forma "tub")
     (setq dim-x (atof (get_tile "dx"))
           dim-y (atof (get_tile "dy"))
           rad-c (atof (get_tile "rc")))
     (if (or (<= dim-x 0) (<= dim-y 0) (<= rad-c 0))Â
       (setq ok nil)
       (setq ok t))))
  (if okÂ
    (progn (mode_tile "accept" 0) (set_tile "error" ""))
    (progn (mode_tile "accept" 1)Â
           (set_tile "error"Â
                     "Los parámetros deben ser mayores que 0"))))Â
;;;Listado 22.6. Función test-otros.
(defun test-1 (rad-a /)Â
  (if (<= rad-a 0)Â
    (progn (setq msj "RadioAcuerdo debe ser mayor que 0")Â
           (setq ok1 nil))
    (setq ok1 t)))Â
(defun test-2 (rad-a dim-y /)Â
  (if (> (* rad-a 2) dim-y)Â
    (prognÂ
      (setq msj (strcat "DimY debe ser mayor que "Â
                        (rtos (* rad-a 2) 2 2)))
      (setq ok2 nil))
    (setq ok2 t)))Â
(defun test-3 (rad-a dim-x)Â
  (if (> rad-a dim-x)Â
    (prognÂ
      (setq msj (strcat "DimX debe ser mayor que "Â
                        (rtos rad-a 2 2)))
      (setq ok3 nil))
    (setq ok3 t)))Â
;;;Listado 22.7. Funciones de prueba test-1, test-2 y test-3.
(defun test-normal (clave / dim-x dim-y rad-a msj ok1 ok2 ok3)Â
  (setq dim-x (atof (get_tile "dx"))
        dim-y (atof (get_tile "dy"))
        rad-a (atof (get_tile "ra")))
  (test-1 rad-a)
  (test-2 rad-a dim-y)
  (test-3 rad-a dim-x)
  (condÂ
    ((= clave "ra") (test-1 rad-a))
    ((= clave "dx") (test-3 rad-a dim-x))
    ((= clave "dy") (test-2 rad-a dim-y)))
  (if (and ok1 ok2 ok3)Â
    (progn (mode_tile "accept" 0) (set_tile "error" ""))
    (progn (mode_tile "accept" 1) (set_tile "error" msj))))Â
;;;Listado 22.8. Función test-normal.
(defun ops-forma (clave valor / dim-x dim-y rad-a rad-c)Â
  (condÂ
    ((and (= clave "nor") (= valor "1")) ; FORMA NORMAL
     (setq dim-x (atof (get_tile "dx"))
           dim-y (atof (get_tile "dy"))
           rad-a (atof (get_tile "ra")))
     (mode_tile "dx" 0)
     (mode_tile "dy" 0)
     (mode_tile "ra" 0)
     (mode_tile "rc" 0)
     (if (= rad-a 0)Â
       (set_tile "ra" (rtos (/ dim-x 2) 2 2)))
     (if (< dim-y (* rad-a 2))Â
       (set_tile "dy" (rtos (* rad-a 2) 2 2)))
     (inicia-imagen "img" "./img/nor")
     (test-normal "dx"))
    ((and (= clave "esf") (= valor "1")) ; FORMA ESFERA
     (setq dim-x (atof (get_tile "dx"))
           rad-a (atof (get_tile "ra")))
     (if (= rad-a 0)Â
       (progn (set_tile "ra" (get_tile "dx"))Â
              (setq rad-a dim-x))
       (set_tile "dx" (get_tile "ra")))
     (set_tile "dy" (rtos (* rad-a 2) 2 2))
     (set_tile "rc" "0.00")
     (mode_tile "dx" 1)
     (mode_tile "dy" 1)
     (mode_tile "ra" 0)
     (mode_tile "rc" 1)
     (inicia-imagen "img" "./img/esf")
     (test-otros clave))
    ((and (= clave "bar") (= valor "1")) ; FORMA BARRA
     (set_tile "ra" "0.00")
     (set_tile "rc" "0.00")
     (mode_tile "dx" 0)
     (mode_tile "dy" 0)
     (mode_tile "ra" 1)
     (mode_tile "rc" 1)
     (inicia-imagen "img" "./img/bar")
     (test-otros clave))
    ((and (= clave "tub") (= valor "1")) ; FORMA TUBO
     (setq rad-c (atof (get_tile "rc")))
     (set_tile "ra" "0.00")
     (if (= rad-c 0)Â
       (set_tile "rc" (get_tile "dx")))
     (mode_tile "dx" 0)
     (mode_tile "dy" 0)
     (mode_tile "ra" 1)
     (mode_tile "rc" 0)
     (inicia-imagen "img" "./img/tub")
     (test-otros clave)))
  ;;;Listado 22.9. Función de respuesta a las casillas de selección de forma predefinida.
  (defun form-sel (/)Â
    (condÂ
      ((= (get_tile "nor") "1") "nor")
      ((= (get_tile "esf") "1") "esf")
      ((= (get_tile "bar") "1") "bar")
      ((= (get_tile "tub") "1") "tub"))
    ;;;Listado 22.10. Detectar el radio_button seleccionado para la forma predefinida.
    (defun sel-rotacion (clave valor razon / forma)Â
      (condÂ
        ((= clave "ang")
         (if (or (= razon 3) (= razon 2) (= razon 1))Â
           (set_tile "inf" valor)))
        ((= clave "inf")
         (if (or (= razon 2) (= razon 1))Â
           (if (numberp (read valor))Â
             (set_tile "ang" valor)
             (set_tile "inf" (get_tile "ang"))))))
      (setq forma (form-sel))
      (if (= forma "nor")Â
        (test-normal "ra")
        (test-otros forma)))
    ;;;Listado 22.11. Función de respuesta asociada al cursor deslizante.
    (defun tipo-modelo (/)Â
      (if (= (get_tile "sol") "1")Â
        "_SO"
        "_SU"))
    ;;;Listado 22.12. Función que determina el tipo de modelo a crear.
   Â
    (defun asigna-acciones (/)Â
      (action_tile "nor" "(ops-forma $key $value)")
      (action_tile "esf" "(ops-forma $key $value)")
      (action_tile "bar" "(ops-forma $key $value)")
      (action_tile "tub" "(ops-forma $key $value)")
      (action_tile "dx" "(param-edit $key $value $reason)")
      (action_tile "dy" "(param-edit $key $value $reason)")
      (action_tile "ra" "(param-edit $key $value $reason)")
      (action_tile "rc" "(param-edit $key $value $reason)")
      (action_tileÂ
        "ang"
        "(sel-rotacion $key $value $reason)")
      (action_tileÂ
        "inf"
        "(sel-rotacion $key $value $reason)")
      (action_tileÂ
        "accept"
        "(setq dim-x (atof (get_tile \"dx\"))
               dim-y (atof (get_tile \"dy\"))
               rad-a (atof (get_tile \"ra\"))
               rad-c (atof (get_tile \"rc\"))
               ang-r (atof (get_tile \"ang\"))
               forma (form-sel)
               tipo (tipo-modelo)
               *Posicion* (done_dialog 1)))")
      (action_tileÂ
        "cancel"
        "(setq *Posicion* (done_dialog 0))"))
    ;;;Listado 22.13. Asignación de acciones a los componentes.
    (defun dialogo-param (/ accion)Â
      (setvar "DIMZIN" 1)
      (if (inicia-dialogo "parametrico" "./dcl/parametrico.dcl")Â
        (progn (inicia-imagen "img" "./img/nor")Â
               (asigna-acciones)
               (setq accion (start_dialog))
               (if (= accion 1)Â
                 (dib-param tipo dim-x dim-y rad-a rad-c ang-r))
               (unload_dialog dcl_id))))
    ;;;Listado 22.14. Función que activa el cuadro de diálogo.
    (defun curv (ang /)Â
      (/ (sin (/ ang 4)) (cos (/ ang 4))))
    ;;;Listado 22.15. Función para el cálculo el factor de curvatura (bulge).
    (defun perfil-rev (max-x med-x max-y min-y rad-c / pts)Â
      (setq pts (list (list rad-c min-y)Â
                      (list med-x min-y)
                      (list max-x (+ min-y rad-a))
                      (list max-x (- max-y rad-a))
                      (list med-x max-y)
                      (list rad-c max-y)))
      (ifÂ
        (entmakeÂ
          (list '(0 . "LWPOLYLINE")Â
                '(100 . "AcDbEntity")
                '(100 . "AcDbPolyline")
                (cons 90 (length pts))
                '(70 . 1)
                (cons 10 (nth 0 pts))
                (cons 10 (nth 1 pts))
                (cons 42 (curv (/ pi 2)))
                (cons 10 (nth 2 pts))
                (cons 10 (nth 3 pts))
                (cons 42 (curv (/ pi 2)))
                (cons 10 (nth 4 pts))
                (cons 10 (nth 5 pts))
                '(210 0.0 0.0 1.0)))
        (setq perfil (entlast))))
    ;;;Listado 22.16. Función que dibuja el perfil como una LWPOLYLINE.
    (defun dib-param (modo dim-x dim-y rad-a rad-c ang-r / max-y min-y max-x med-xÂ
                      pts perfil)Â
      (setq max-y (/ dim-y 2)
            min-y (- max-y)
            max-x (+ rad-c dim-x)
            med-x (- max-x rad-a))
      (perfil-rev max-x med-x max-y min-y rad-c) ; Perfiles
      (if perfilÂ
        (prognÂ
          (if (= modo "_SU")  ; Modelo
            (progn (setvar "SURFACEMODELINGMODE" 0)Â
                   (setvar "SURFACEASSOCIATIVITY" 1)
                   (vl-cmdf "_AutoConstrain" perfil "")))
          (vl-cmdf "_REVOLVE" "_MOde" modo perfil "" "_Y" ang-r)
          (ax-SOsup))))
    ;;;Listado 22.17. Función que crea el modelo.
    (defun C:DCL-PARAM (/ *error*)Â
      (defun *error* ()Â
        (cmd-salir)
        (command-s "_UNDO" "_End"))
      (cmd-entrar)
      (command-s "_UNDO" "_Begin")
      (if (= (getvar "WORLDUCS") 0)Â
        (vl-cmdf "_UCS" "_W"))
      (dialogo-param)
      (command-s "_UNDO" "_End")
      (cmd-salir))
    ;;;Listado 22.18. Función principal C:DCL-PARAM.