AdamW Posted August 17, 2018 Share Posted August 17, 2018 Can Anyone tell me where Ive gone wrong. Im newish to lisp and very new to DCL. A colleague from work has helped me and I have also read Lee Macs website and Afra Lisps website to get me to this point, but now Im a little stuck. Every time I hit the cancel button button i get this error ; error: bad argument type: consp "Canceled" The Ultimate goal would be when the cancel button is hit it would cancel the dialogue and print a message "Cancelled by User" The Lisp is as follows (defun c:Material-sizes () ;Get Initial Values if set to nil (if (= timber_length nil) (setq timber_length "4800")) (if (= Ply_length nil) (setq Ply_length "2400")) (defun DControl () (setq dcl-id (load_dialog (findfile "Materials.dcl"))) (if (not (new_dialog "Materials" dcl-id "" '(-1 -1)) ) (exit) (progn (setq Output "Canceled") (set_tile "eb1" timber_length) (set_tile "eb2" Ply_length) (action_tile "accept" "(result)(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (defun result () (setq Output (list "v1.0" (get_tile "eb1")(get_tile "eb2") ) )) (start_dialog) )) Output) (setq Output (DControl)) (setq timber_length (atof (nth 1 Output)) Ply_length (atof (nth 2 Output)) ) ;Do the calculations ;This lengthy section has been removed ;reset Variables to strings (setq timber_length (rtos timber_length 2 2)) (setq Ply_length (rtos Ply_length 2 2)) ;clean exit (princ) ) The DCL is as follows //---------------------------------// cbut : retirement_button { alignment = centered ; key = "cancel" ; label = "Cancel" ; is_cancel = true ; fixed_width = true ; width = 12 ; } okbut : retirement_button { alignment = centered ; key = "accept" ; label = "Update" ; is_default = true ; fixed_width = true ; width = 12 ; } edbox : edit_box { fixed_width = true; edit_width = 6; } //---------------------------------// tile_a :boxed_column { label = "Defaults" ; :edbox {key = "eb1"; label = "Timber length"; alignment = right;} :edbox {key = "eb2"; label = "Ply Length"; alignment = right;} } //---------------------------------// Materials : dialog { fixed_width = true; width = 40; label = "Materials"; tile_a; cbut; okbut; } //---------------------------------// Thanks in advance Quote Link to comment Share on other sites More sharing options...
BIGAL Posted August 17, 2018 Share Posted August 17, 2018 I am no expert on dcl's but the ok_cancel combo returns as you say the variable "Cancel" so wether you click ok or cancel you can save these two answers and do a if outside the dcl. The problem may be trying to do to much inside the dcl. You dont appear to be saving the click on these buttons. This is just an example of the way I do it. Ps I need to add the cancel to my code. (setq dcl_id (load_dialog fname)) (if (not (new_dialog "ddgetval2" dcl_id)) (exit)) (mode_tile "key1" 3) (set_tile "key1" (setq val1 def1)) (action_tile "key1" "(setq val1 $value)") (mode_tile "key2" 3) (set_tile "key2" (setq val2 def2)) (action_tile "key2" "(setq val2 $value)") ; put the action tile ok and cancel here as a saved variable (action_tile "cancel" "(setq action "Yes")") (start_dialog) (done_dialog) (unload_dialog dcl_id) ; returns the value of val1 and val2 as strings (vl-file-delete fname) ) Quote Link to comment Share on other sites More sharing options...
rlx Posted August 17, 2018 Share Posted August 17, 2018 (edited) (defun c:Material-sizes () ;Get Initial Values if set to nil (if (= timber_length nil) (setq timber_length "4800")) (if (= Ply_length nil) (setq Ply_length "2400")) (defun DControl () (setq dcl-id (load_dialog (findfile "Materials.dcl"))) (if (not (new_dialog "Materials" dcl-id "" '(-1 -1))) (exit) (progn (setq Output "Canceled") (set_tile "eb1" timber_length) (set_tile "eb2" Ply_length) (action_tile "accept" "(result)(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (defun result () (setq Output (list "v1.0" (get_tile "eb1") (get_tile "eb2")))) (start_dialog) ) ) Output ) (setq Output (DControl)) (if (not (eq Output "Canceled")) (progn (setq timber_length (atof (nth 1 Output)) Ply_length (atof (nth 2 Output))) ;Do the calculations ;This lengthy section has been removed ;reset Variables to strings (setq timber_length (rtos timber_length 2 2)) (setq Ply_length (rtos Ply_length 2 2)) ) (princ "\nCanceled by User") ) ;clean exit (princ) ) FWIW Materials : dialog {label="Materials";fixed_width=true;width=40; :boxed_row {label="Defaults"; :column {:text {label="Timber Length";} :text {label="Ply Length";}} :column {:edit_box {key="eb1";} :edit_box {key="eb2";}}} ok_cancel; } Edited August 19, 2018 by rlx Quote Link to comment Share on other sites More sharing options...
Jef! Posted August 21, 2018 Share Posted August 21, 2018 (edited) On 8/17/2018 at 5:50 PM, AdamW said: Can Anyone tell me where Ive gone wrong... ; error: bad argument type: consp "Canceled" Basically in DControl you setq your result to "Canceled", and if the tile hit is accept, you override it in the result function. If you hit cancel (hence skip the override), the value stored is still the string "Cancelled", which triggers the error when you try to get (nth 1 Output) of a string. A simple modification would be to check whether the variable contains a list, and if not exit after displaying the string you want ie "The user has cancelled" (defun c:Material-sizes () ;Get Initial Values if set to nil (if (= timber_length nil) (setq timber_length "4800")) (if (= Ply_length nil) (setq Ply_length "2400")) (defun DControl () (setq dcl-id (load_dialog (findfile "Materials.dcl"))) (if (not (new_dialog "Materials" dcl-id "" '(-1 -1)) ) (exit) (progn (setq Output "Canceled") (set_tile "eb1" timber_length) (set_tile "eb2" Ply_length) (action_tile "accept" "(result)(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (defun result () (setq Output (list "v1.0" (get_tile "eb1")(get_tile "eb2") ) ) ) (start_dialog) ) ) Output) (setq Output (DControl)) ;(alert (vl-princ-to-string output)) (if (not (listp Output)) (progn (alert "Cancelled by User") (exit) ) ) (setq timber_length (atof (nth 1 Output)) Ply_length (atof (nth 2 Output)) ) ;Do the calculations ;This lengthy section has been removed ;reset Variables to strings (setq timber_length (rtos timber_length 2 2)) (setq Ply_length (rtos Ply_length 2 2)) ;clean exit (princ) ) Cheers! edit: I just saw that rlx offered a working solution... I'll still leave my reply as the original question was "Why...". Edited August 21, 2018 by Jef! Quote Link to comment Share on other sites More sharing options...
ronjonp Posted August 22, 2018 Share Posted August 22, 2018 Just a nitpicky thing but: ;;This (if (= timber_length nil) (setq timber_length "4800") ) (if (= ply_length nil) (setq ply_length "2400") ) ;; Could be this (or timber_length (setq timber_length "4800")) (or ply_length (setq ply_length "2400")) 1 Quote Link to comment Share on other sites More sharing options...
Grrr Posted August 22, 2018 Share Posted August 22, 2018 6 hours ago, ronjonp said: ;; Could be this (or timber_length (setq timber_length "4800")) (or ply_length (setq ply_length "2400")) or this: (setq timber_length (cond ( timber_length ) ( "4800") ) ) (setq Ply_length (cond ( Ply_length ) ( "2400") ) ) or even: ; (mapcar 'AssignFirstVal '((timber_length "4800")(Ply_length "2400"))) ; (mapcar 'AssignFirstVal '((a 1)(b 2)(c 3))) ; (AssignFirstVal '(x 123)) (defun AssignFirstVal ( L / sym val ) (mapcar 'set '(sym val) L) (set sym (cond ( (eval sym) ) ( val ) ) ) ) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted August 22, 2018 Share Posted August 22, 2018 1 hour ago, Grrr said: (set sym (cond ( (eval sym) ) ( val ) ) ) Why set the value of the variable to itself? How about - (cond ((eval sym)) ((set sym val))) Quote Link to comment Share on other sites More sharing options...
Jef! Posted August 22, 2018 Share Posted August 22, 2018 Lee has a good point here. Despite that for an average user it can become hard to spot all variables to localize them when they are declared like that. If someones writes (if (= timber_length nil) (setq timber_length "4800") ) the next logic step would be that (if (null timber_length) (setq timber_length "4800") ) After that, as mentioned by ronjonp the or approach looks like a concept that can be understood by the OP and brings a bite size of new material. I'm not sure the OP is at a level to grasp concepts that use mapcars/set/eval since the original request for help was to find out why (nth 1 "calcelled") was bombing. Nitpicky thingy too Quote Link to comment Share on other sites More sharing options...
Grrr Posted August 23, 2018 Share Posted August 23, 2018 8 hours ago, Lee Mac said: Why set the value of the variable to itself? How about - (cond ((eval sym)) ((set sym val))) Goot point indeed, but now looking at it, the line could be reduced a bit with the or function, just like Ron did - (or (eval sym) (set sym val)) Talking about the AssignFirstVal subfoo 7 hours ago, Jef! said: Lee has a good point here. Despite that for an average user it can become hard to spot all variables to localize them when they are declared like that. I agree, but as far I see here the intention is to keep timber_length and Ply_length global 7 hours ago, Jef! said: I'm not sure the OP is at a level to grasp concepts that use mapcars/set/eval No one requires from him to understand the subfoo that uses these functions. The only thing needed is to know what this does: (mapcar 'AssignFirstVal '((timber_length "4800")(Ply_length "2400"))) Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted August 23, 2018 Share Posted August 23, 2018 No one has mentioned this: The standard practice is to use the return value of the start_dialog function to determine which button (or other tile) was used to close the dialog. The return value will be the integer specified in the done_dialog call. Quote Link to comment Share on other sites More sharing options...
rlx Posted August 23, 2018 Share Posted August 23, 2018 (edited) well if we're all nutpicking , I see no action tile for the edit boxes so if you're nut want to change them , you might as well leave them out or make them part of this party. (defun c:Material-sizes ( / f p d r drv otbr oply) (defun Go_Process_Yourself () ; needs data verification (setq timber_length (atof timber_length) Ply_length (atof Ply_length)) ; calcy calcy (princ "\nCalculating.........Timber!!!") (setq timber_length (rtos timber_length 2 2) Ply_length (rtos Ply_length 2 2)) ) (and (or timber_length (setq timber_length "4800")) (or Ply_length (setq Ply_length "2400")) (setq p (open (setq f (vl-filename-mktemp ".dcl")) "w")) (mapcar ''((x)(princ x p)) '("M:dialog {label=\"Materials\";fixed_width=true;width=40;" ":boxed_row {label=\"Defaults\";" ":column {:text {label=\"Timber Length\";} :text {label=\"Ply Length\";}}" ":column {:edit_box {key=\"eb1\";} :edit_box {key=\"eb2\";}}} ok_cancel;}")) (not (setq p (close p)))(< 0 (setq d (load_dialog f)))(new_dialog "M" d) (progn (set_tile "eb1" (setq otbr timber_length)) (set_tile "eb2" (setq oply Ply_length)) (action_tile "eb1" "(setq timber_length $value)");verify data (action_tile "eb2" "(setq Ply_length $value)");verify data (action_tile "accept" "(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (setq drv (start_dialog))(unload_dialog d)(vl-file-delete f) ) ) (cond ((= drv 0) (setq timber_length otbr Ply_length oply) (princ "\nCanceled by User")) (t (Go_Process_Yourself)) ) (princ) ) but I think you've all scared OP away with your mapcar's & evals haha Edited August 24, 2018 by rlx Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted August 23, 2018 Share Posted August 23, 2018 @rlx: Call it nitpicking or call it fundamental: In the latest version of your code the globals timber_length and Ply_length can change even if the user hits the Cancel button. Quote Link to comment Share on other sites More sharing options...
rlx Posted August 23, 2018 Share Posted August 23, 2018 (edited) correct and if OP types instead of a number in one of the edit boxes I still won't get drunk... but ok , fixed it even though OP hasn't responded anymore Edited August 24, 2018 by rlx 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.