Author Topic: Classical way to use dialogs  (Read 100 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Bull Frog
  • Posts: 267
Classical way to use dialogs
« on: April 05, 2017, 01:33:16 pm »
Hi guys,
I just wanted to leave this classical template to load & display & get inputs from dialog.

The reason is because I didn't have enough experience about looking for the actual .dcl file, loading it and displaying it
I was always creating my dialogs on the fly, since Lee Mac has revealed his strategy/method - which is perfect BTW.

Another reason was because I'm always forgetting where the *_tile functions must be located - in this clear sample code the set/get/mode/action_tile
are between the new_dialog and start_dialog.
My memory fails and I'm confusing the load_dialog/new_dialog/start_dialog order, and between which ones I had to use the tile functions.  :uglystupid2:

Code - Auto/Visual Lisp: [Select]
  1. ; Learning the classical way to load and run dialogs - without creating them on the fly:
  2. (defun C:test ( / *error* dcp dcl dch dcf side len wid radius )
  3.  
  4.  (defun *error* ( msg )
  5.    (and (< 0 dch) (unload_dialog dch)) ; Unloads the DCL file associated with dcl_id (obtained from a previous new_dialog call) from memory. Always return nil
  6.    (and msg (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\nError: " msg)) ))
  7.    (princ)
  8.  ); defun *error*
  9.  
  10.  (cond
  11.    ( (not (setq dcp (findfile "Rectangle.dcl"))) ; trusted path and filename with extension
  12.      (princ "\nUnable to find the DCL file.")
  13.    )
  14.    (
  15.      (progn
  16.        (setq dcl (apply 'strcat (cdr (fnsplitl dcp)))) ; filename with extension, example: "Rectangle.dcl"
  17.        (> 0 (setq dch (load_dialog dcl))) ; 1
  18.                                           ; Returns: A positive integer value (dcl_id) if successful, or a negative integer if load_dialog can't open the file.
  19.                                           ; The dcl_id is used as a handle in subsequent new_dialog and unload_dialog calls.
  20.      ); progn
  21.      (princ "\nUnable to load the DCL file.")
  22.    )
  23.    ( (not (new_dialog "rect" dch)) ; (new_dialog dlgname dcl_id [action [screen-pt]]) ; Display ; Returns: T, if successful, otherwise nil.
  24.      (princ "\nUnable to display the dialog")
  25.    )
  26.    (
  27.      (progn
  28.        ; Set Default values for the tiles:
  29.        (set_tile "CE" "1") ; rectangle justification centered - enable
  30.        (set_tile "X" "300") ; length
  31.        (set_tile "Y" "600") ; width
  32.        (set_tile "FT" "0") ; fillet toggle - disable
  33.        (set_tile "FR" "60") ; Fillet radius
  34.        ; Set Default values for the lisp symbols - AFTER the default values for the tiles are set:
  35.        (setq side "CE")
  36.        (setq len (get_tile "X"))
  37.        (setq wid (get_tile "Y"))
  38.        (setq radius (get_tile "FR"))
  39.        ; Set Default mode for the fillet tile:
  40.        (mode_tile "FR" (if (= "1" (get_tile "FT")) 0 1)) ; check the toggle's value and enable/disable accordingly
  41.        ; Set Default actions for the tiles:
  42.        (action_tile "LS" "(setq side $key)")
  43.        (action_tile "CE" "(setq side $key)")
  44.        (action_tile "RS" "(setq side $key)")
  45.        (action_tile "X" "(setq len $value)")
  46.        (action_tile "Y" "(setq wid $value)")
  47.        (action_tile "FR" "(setq radius $value)")
  48.        (action_tile "FT" ; action for the fillet's toggle
  49.          (vl-prin1-to-string
  50.            '(cond
  51.              ( (= "1" (get_tile "FT")) (mode_tile "FR" 0) ) ; Enabled
  52.              ( (= "0" (get_tile "FT")) (mode_tile "FR" 1) ) ; Disabled
  53.            ); cond
  54.          ); vl-prin1-to-string
  55.        ); action_tile "FT"
  56.        (action_tile "accept"
  57.          (vl-prin1-to-string
  58.            '(cond
  59.              ( (not (numberp (read len))) (set_tile "error" "Invalid Length value!") )
  60.              ( (not (numberp (read wid))) (set_tile "error" "Invalid Width value!") )
  61.              ( (and (= "1" (get_tile "FT")) (not (numberp (read radius)))) ; tile is enabled and not numerical
  62.                (set_tile "error" "Invalid Radius value!")
  63.              )
  64.              (T
  65.                (if (= "0" (get_tile "FT")) (setq radius nil) ) ; set radius to nil if the fillet's toggle is disabled
  66.                (done_dialog 1)
  67.              )
  68.            ); cond
  69.          ); vl-prin1-to-string
  70.        ); action_tile "accept"
  71.        (/= 1 (setq dcf (start_dialog))) ; Display the dialog and begin accepting the user inputs
  72.      ); progn
  73.      (princ "\nUser cancelled the dialog.")
  74.    )
  75.    (T ; User finished with dialog, proceed with the inputs
  76.      (alert
  77.        (strcat
  78.          "\nUser has chosen:"
  79.          "\nSide: " side
  80.          "\nLength: " len
  81.          "\nWidth: " wid
  82.          "\nRadius: " (if (eq 'STR (type radius)) radius "")
  83.        ); strcat
  84.      ); alert
  85.    )
  86.  ); cond
  87.  (*error* nil) (princ)
  88. ); defun


DCL (Rectangle.dcl) :
Code: [Select]
rect : dialog
{ label = "Draw a Rectangle";
  : boxed_radio_row
  { label = "Select placement method";
    : radio_button { key = "LS"; label = "Left Side"; }
    : radio_button { key = "CE"; label = "Center"; }
    : radio_button { key = "RS"; label = "Right Side"; }
  }
  : row
  { : boxed_column
    { label = "Size";
      : edit_box { key = "X"; label = "Length"; edit_width = 6; }
      : edit_box { key = "Y"; label = "Width"; edit_width = 6; }
    }
    : boxed_column
    { label = "Fillet";
      : toggle { key = "FT"; label = "Fillet corners?"; }
      : edit_box { key = "FR"; label = "Radius"; }
    }
  }
  spacer; ok_cancel;
  : text { label = ""; key = "error"; }
}

I'll continue write from scratch some useless lisp codes that are using dialogs - so hopefully I'll memorize the methodology/technique.


Although one question appeared, how can I stack multiple dialogs? Maybe like this? :
Code - Auto/Visual Lisp: [Select]
  1. ; Will this run and display 3 nested dialogs at once?
  2. (setq dch (load_dialog dcl_file_with_3_dialogs))
  3.  
  4. (new_dialog "dialog1" dch)
  5. (set_tile ...)
  6. (get_tile ...)
  7.  
  8. (new_dialog "dialog2" dch)
  9. (set_tile ...)
  10. (get_tile ...)
  11.  
  12. (new_dialog "dialog3" dch)
  13. (set_tile ...)
  14. (get_tile ...)

And will such thing work? :
Code - Auto/Visual Lisp: [Select]
  1. ; By pressing that button will it display the nested dialog?
  2. (action_tile "MoreOptions"
  3.    '(progn
  4.      (new_dialog "dialog2" dch)
  5.      (set_tile ...)
  6.      (get_tile ...)
  7.      (action_tile ...)
  8.      (start_dialog)
  9.    )
  10.  )
  11. )
  12.  

roy_043

  • Swamp Rat
  • Posts: 1419
  • BricsCAD 16
Re: Classical way to use dialogs
« Reply #1 on: April 06, 2017, 03:05:34 am »
Two remarks:

Why don't you use:
Code - Auto/Visual Lisp: [Select]

You have:
Code - Auto/Visual Lisp: [Select]
  1. (set_tile "X" "300")
  2. (setq len (get_tile "X"))
I would use:
Code - Auto/Visual Lisp: [Select]
  1. (setq len "300")
  2. (set_tile "X" len)

Grrr1337

  • Bull Frog
  • Posts: 267
Re: Classical way to use dialogs
« Reply #2 on: April 06, 2017, 08:03:36 am »
Why don't you use:
Code - Auto/Visual Lisp: [Select]

Hmm.. I did not realise that load_dialog acts like findfile, so this first cond block is redundant:
Code - Auto/Visual Lisp: [Select]
  1.   ( (not (setq dcp (findfile "Rectangle.dcl"))) ; trusted path and filename with extension
  2.      (princ "\nUnable to find the DCL file.")
  3. )
I thought (without testing) that load_dialog might check the dcl file's content, and if theres invalid dialog it would return negative int.

You have:
Code - Auto/Visual Lisp: [Select]
  1. (set_tile "X" "300")
  2. (setq len (get_tile "X"))
I would use:
Code - Auto/Visual Lisp: [Select]
  1. (setq len "300")
  2. (set_tile "X" len)

Technically both seem correct, but I think your suggestion is more "classical" (didn't thought about it, while writing this code).

Thanks for your input, Roy!
Two or more brains are better than one. :)