davidbonge Posted October 8, 2011 Posted October 8, 2011 hey I was wondering if anyone can help me modify a layer creator program I downloaded. Its an awesome program by 't.spangler' (full credit to him) but i want to add one tiny bit to it and im not sure how. I want to create a filter so if I start typing 'plas' in the exit box the only layers I want to see are eg. plasterboard wall, plasterboad elevation, plasterboard roof (or what ever other layer description have the letters plas in them. make sense? hope so! haha basically i added the line... initial_focus = "textval"; } :boxed_column{ : edit_box { key = "textval"; label = " Quick Select -->"; edit_width = 30; value = ""; } this works in the dcl file - when I run the program in CAD the edit box comes up, and now i just need to know the coding in the lsp file to do the filtering. thanks heaps in advance for your help and time. Quote
Lee Mac Posted October 9, 2011 Posted October 9, 2011 You will need to include an expression in the action_tile statement of the edit_box that will repopulate the list_box with only those items that match the filter. Here is an example of such functionality: (defun c:test ( / d l ) (while (setq d (tblnext "LAYER" (null d))) (setq l (cons (cdr (assoc 2 d)) l)) ) (_GetLayerSelection (acad_strlsort l)) ) (defun _GetLayerSelection ( layerlist / _PopulateListBox dch file layers return tmp ) ;; Example by Lee Mac 2011 - www.lee-mac.com (defun _PopulateListBox ( key alist ) (start_list key) (mapcar 'add_list alist) (end_list) alist ) (cond ( (not (and (setq file (open (setq tmp (vl-filename-mktemp nil nil ".dcl")) "w")) (write-line (strcat "layers : dialog { label = \"Select Layer\"; spacer;" " : list_box { key = \"layers\"; width = 50; fixed_width = true; height = 15; fixed_height = true; allow_accept = true; }" " : edit_box { key = \"filter\"; width = 50; fixed_width = true; value = \"*\"; label = \"Filter:\"; }" " spacer; ok_cancel;" "}" ) file ) (not (close file)) (< 0 (setq dch (load_dialog tmp))) (new_dialog "layers" dch) ) ) ) ( t (_PopulateListBox "layers" (setq layers layerlist)) (set_tile "layers" (setq return "0")) (set_tile "filter" "*") (action_tile "layers" "(setq return $value)") (action_tile "filter" (vl-prin1-to-string (quote (progn (setq filter (strcat "*" (strcase $value) "*")) (_PopulateListBox "layers" (setq layers (vl-remove-if-not '(lambda ( layer ) (wcmatch (strcase layer) filter)) layerlist) ) ) (set_tile "layers" (setq return (cond ( (< (atoi return) (length layers)) return ) ( "0" )))) ) ) ) ) (setq return (if (= 1 (start_dialog)) (nth (atoi return) layers))) ) ) (if (< 0 dch) (unload_dialog dch)) (if (setq tmp (findfile tmp)) (vl-file-delete tmp)) return ) Quote
davidbonge Posted October 9, 2011 Author Posted October 9, 2011 thanks heaps lee mac! i actually used your website a week ago with the tutorials! (shows how much of a newbie i am to the whole lisp programming, i completed tutorials at a few different sites but i know i am still ages away from writing my own programs - gave me a great start tho!) i gave your code example a try in the .lsp file but didnt have much success. im really really keen to learn tho but i think maybe that code was still a bit too advanced for me. do you reckon you can show me how to apply that code example in the following lsp file? LAYER_CREATOR.lsp Quote
ColinHolloway Posted August 27, 2012 Posted August 27, 2012 Hi Lee, I have designed a dialog box that has the same fucnctionality as your Layer List Box example (where there is an Edit_box for the filter string). I would like this filter string to act like a .net form where there is a TextChanged event that can be used to update the list in real time based on the filter string. I have tried several options (while loops, if statements etc) but have not been able to get this to work. Can you please confirm if this is possible and supply a code snippet to guide me in the correct direction. Thanks in advance, Colin Holloway Sedgman Limited Quote
Lee Mac Posted August 27, 2012 Posted August 27, 2012 Hi Colin, The functionality that you have described is unfortunately not possible to achieve using standard DCL since the edit_box tiles in DCL only register two events (callback reasons): 1=user pressed enter / 2=tile loses focus. Here is an example to demonstrate these events: DCL Code (save as test.dcl): test : dialog { spacer; : edit_box { key = "edit"; width = 30; fixed_width = true; alignment = centered; } spacer; ok_only; } LISP Code: (defun c:test ( / id ) (cond ( (<= (setq id (load_dialog "test.dcl")) 0) (princ "\ntest.dcl not found.") ) ( (new_dialog "test" id) (action_tile "edit" "(alert (strcat \"$reason: \" (itoa $reason)))") (start_dialog) ) ) (if (< 0 id) (unload_dialog id)) (princ) ) Quote
ColinHolloway Posted August 28, 2012 Posted August 28, 2012 Hi Lee, Thank you for the quick response. I have investigated further and have decided to go with OpenDCL http://www.opendcl.com/ to solve this issue. Colin Holloway Sedgman Limited Quote
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.