Jump to content

Recommended Posts

Posted

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.

Posted

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
)

Posted

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

  • 10 months later...
Posted

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

Posted

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)
)

Posted

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

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...