Jump to content

Create search bar for dialog box


Charpzy

Recommended Posts

I've got a dialog box which displays 100+ blocks which can be quick frustrating scrolling through to navigate a specific block, how could I create a search bar so i can search for block or a block with similar name for example:

search: Tes

return: Test

 

so far i've added the search box but the can search for exact names but it always grabs the list number value rather than the actual logo name if that makes sense so its it returns the value 0 

my code:

(defun c:INSERTLOGO (/ p MSpace *error*)
  
  (defun *error* ( msg )
      (princ " error: ")
      (princ msg)
      (princ)
  )
  
  (setq folderList (vl-directory-files "Z:\\LOGOS" "*.dwg" 1)
        Path "Z:\\LOGOS\\"
  )
  
  (If (setq fn (findfile "MACROS\\DIALOGS\\LOGOS.dcl")) 
    (setq dlg_id (load_dialog fn))
    (alert "Dialog LOGOS.dcl not found")
  )
  (new_dialog "LOGOS" dlg_id)
  
  (defun searchbar (keyword)
    (setq search_list (vl-directory-files "Z:\\LOGOS" (strcat keyword".dwg") 1))
    ()
    (start_list "folderlist" 3)
    (mapcar 'add_list (mapcar 'vl-filename-base search_list))
    (end_list)
  )

  
  (start_list "folderlist")
  (mapcar 'add_list (mapcar 'vl-filename-base folderList))
  (end_list)
  (action_tile "folderlist" "(setq item (nth (atof $value) folderList))")
  ;(action_tile "search" "(searchbar (get_tile \"search\"))")
  (action_tile "accept" "(done_dialog)")
  (start_dialog)
  
  (setq pt (Getpoint "\nInsertion point")
        MSpace (vla-get-paperspace (vla-get-activedocument (vlax-get-acad-object)))
  )
  (vla-insertblock MSpace pt (strcat Path item) 1 1 1 0)
  (princ)
)

 

DCL:

LOGOS :dialog {
  label = "Select a Logo";

  : column {  
    : boxed_row {
      label= "Search";
      : edit_box {
        key = "search";
        label="";
        edit_width = 35;}
    }
    
    : boxed_column {
      label = "Logos";
      : list_box {
        height = 10;
        width  = 35;
        key    = "folderlist";
        multiple_select = false ;
      }
    }
  }
  spacer;
  ok_only;
}

 

Link to comment
Share on other sites

;;; declare ALL GLOBAL variables
;;; If you don't they can bite you (take it from an old dragon like despicable me)
(defun c:INSERTLOGO (/ actApp actDoc actSpace folderList resetList Path dlg_id fn pt search_list item  b )
  
  (defun *error* (s)(princ " error: ")(princ s)(princ))

  ;;; will use this when inserting block
  (setq actApp (vlax-get-acad-object) actDoc (vla-get-activedocument actApp))
  
  ;;; retrieve the current / active space (model or paper)
  (if (= (getvar 'tilemode) 1)
    (setq actSpace (vla-get-ModelSpace actDoc))
    (setq actSpace (vla-get-PaperSpace actDoc))
  )

  ;;; *** change to your own path
  (setq Path "d:\\Temp\\Lisp\\Cad-tutor\\Charpzy\\dwgs\\"
        folderList (vl-directory-files Path "*.dwg" 1)
        resetList folderList)

  ;;; give message when dialog can't be found (or create it automaticaly)
  (if (not (setq fn (findfile "d:\\Temp\\Lisp\\Cad-tutor\\Charpzy\\LOGOS.dcl")))
    (alert "Dialog LOGOS.dcl not found")
    (progn
      (setq dlg_id (load_dialog fn))
      (new_dialog "LOGOS" dlg_id)
      (if (not (vl-consp folderList)) (setq folderlist (list "no drawings in folder")))
      (start_list "folderlist")
        (mapcar 'add_list (mapcar 'vl-filename-base folderList))
          (end_list)
      ;;; dont use atof but atoi for nth
      (action_tile "folderlist" "(setq item (nth (atoi $value) folderList))")
      (action_tile "search" "(setq search-string $value)")
      (action_tile "bt_search" "(filter)")
      (action_tile "bt_reset" "(reset_listbox)")
      (action_tile "accept" "(done_dialog 1)")
      (action_tile "cancel" "(done_dialog 0)")

      ;;; dialog return value
      (setq drv (start_dialog))
      (cond
        ((= drv 1)
         ;;; check as much as possible and try to catch errors and report them
         (if (and item (setq pt (getpoint "\nInsertion point"))
                 (not (vl-catch-all-error-p (setq b (vl-catch-all-apply 'vla-InsertBlock
                    (list ActSpace (vlax-3D-point pt) (strcat Path item) 1.0 1.0 1.0 0.0))))))
           (princ (strcat "\nInserted block " item))
           (if b (princ (strcat "\n*Error: " (vl-catch-all-error-message b))))
         )
        )
        (t (princ "\nDialog cancelled"))
      )
    )
  )
  (princ)
)

(defun filter ( / match result-list)
  (cond
    ((or (null search-string)(eq search-string ""))
     (alert "Nothing in search box"))
    ((not (vl-consp folderList))
     (alert "no items in list box"))
    (t
     (setq match (strcase (strcat "*" search-string "*")))
     (foreach x folderList
       (if (wcmatch (strcase x) match) (setq result-list (cons x result-list))))
     (if (not (vl-consp result-list))
       (alert "Computer says no : sorry no match was found")
       (progn (start_list "folderlist")(mapcar 'add_list (setq folderList result-list))(end_list))
     )
    )
  )
)

(defun reset_listbox () (set_tile "search" (setq search-string ""))
  (start_list "folderlist")(mapcar 'add_list (setq folderList resetList))(end_list))

 

LOGOS :dialog {
  label = "Select a Logo";
  : column {  
    : boxed_row { label= "Search";
      : edit_box { edit_width = 35; key = "search";}
      : button { key = "bt_search"; label = "Search";}
      : button { key = "bt_reset"; label = "Reset";}
    }
    
    : boxed_column { label = "Logos";
      : list_box { height = 10; width  = 35; key = "folderlist"; multiple_select = false ;}
    }
  }
  spacer;
  ok_cancel;
}

 

🐉

 

 

  • Like 2
Link to comment
Share on other sites

Split your blocks into logical categories and you dont need a lisp you can do it with a menu, the same with tool palettes group them. The menu has a next function built in, so if exceed 20 can go next screen.

 

image.thumb.png.54592b1c4f418f50fc807d879c87ab38.png

 

 

Edited by BIGAL
Link to comment
Share on other sites

Legend this is perfect! thank you

15 hours ago, rlx said:
;;; declare ALL GLOBAL variables
;;; If you don't they can bite you (take it from an old dragon like despicable me)
(defun c:INSERTLOGO (/ actApp actDoc actSpace folderList resetList Path dlg_id fn pt search_list item  b )
  
  (defun *error* (s)(princ " error: ")(princ s)(princ))

  ;;; will use this when inserting block
  (setq actApp (vlax-get-acad-object) actDoc (vla-get-activedocument actApp))
  
  ;;; retrieve the current / active space (model or paper)
  (if (= (getvar 'tilemode) 1)
    (setq actSpace (vla-get-ModelSpace actDoc))
    (setq actSpace (vla-get-PaperSpace actDoc))
  )

  ;;; *** change to your own path
  (setq Path "d:\\Temp\\Lisp\\Cad-tutor\\Charpzy\\dwgs\\"
        folderList (vl-directory-files Path "*.dwg" 1)
        resetList folderList)

  ;;; give message when dialog can't be found (or create it automaticaly)
  (if (not (setq fn (findfile "d:\\Temp\\Lisp\\Cad-tutor\\Charpzy\\LOGOS.dcl")))
    (alert "Dialog LOGOS.dcl not found")
    (progn
      (setq dlg_id (load_dialog fn))
      (new_dialog "LOGOS" dlg_id)
      (if (not (vl-consp folderList)) (setq folderlist (list "no drawings in folder")))
      (start_list "folderlist")
        (mapcar 'add_list (mapcar 'vl-filename-base folderList))
          (end_list)
      ;;; dont use atof but atoi for nth
      (action_tile "folderlist" "(setq item (nth (atoi $value) folderList))")
      (action_tile "search" "(setq search-string $value)")
      (action_tile "bt_search" "(filter)")
      (action_tile "bt_reset" "(reset_listbox)")
      (action_tile "accept" "(done_dialog 1)")
      (action_tile "cancel" "(done_dialog 0)")

      ;;; dialog return value
      (setq drv (start_dialog))
      (cond
        ((= drv 1)
         ;;; check as much as possible and try to catch errors and report them
         (if (and item (setq pt (getpoint "\nInsertion point"))
                 (not (vl-catch-all-error-p (setq b (vl-catch-all-apply 'vla-InsertBlock
                    (list ActSpace (vlax-3D-point pt) (strcat Path item) 1.0 1.0 1.0 0.0))))))
           (princ (strcat "\nInserted block " item))
           (if b (princ (strcat "\n*Error: " (vl-catch-all-error-message b))))
         )
        )
        (t (princ "\nDialog cancelled"))
      )
    )
  )
  (princ)
)

(defun filter ( / match result-list)
  (cond
    ((or (null search-string)(eq search-string ""))
     (alert "Nothing in search box"))
    ((not (vl-consp folderList))
     (alert "no items in list box"))
    (t
     (setq match (strcase (strcat "*" search-string "*")))
     (foreach x folderList
       (if (wcmatch (strcase x) match) (setq result-list (cons x result-list))))
     (if (not (vl-consp result-list))
       (alert "Computer says no : sorry no match was found")
       (progn (start_list "folderlist")(mapcar 'add_list (setq folderList result-list))(end_list))
     )
    )
  )
)

(defun reset_listbox () (set_tile "search" (setq search-string ""))
  (start_list "folderlist")(mapcar 'add_list (setq folderList resetList))(end_list))

 

LOGOS :dialog {
  label = "Select a Logo";
  : column {  
    : boxed_row { label= "Search";
      : edit_box { edit_width = 35; key = "search";}
      : button { key = "bt_search"; label = "Search";}
      : button { key = "bt_reset"; label = "Reset";}
    }
    
    : boxed_column { label = "Logos";
      : list_box { height = 10; width  = 35; key = "folderlist"; multiple_select = false ;}
    }
  }
  spacer;
  ok_cancel;
}

 

🐉

 

 

 

Link to comment
Share on other sites

BigAl it looks like rlx provided a nice routine for what the OP requested but I would use your method instead.  Grouping the blocks is a logical way to speed the selection process.  Just using a list of block names seems a bit tough. How can you remember what 100+ blocks look like?  I like the thumbnails your method provides.

Link to comment
Share on other sites

all blocks are logos, wouldn't be able to break them down into groups otherwise i would have gone down this route. in future if i'm using blocks which don't have a good identifying name i'm going to break them into groups

On 11/11/2022 at 03:07, JerryFiedler said:

BigAl it looks like rlx provided a nice routine for what the OP requested but I would use your method instead.  Grouping the blocks is a logical way to speed the selection process.  Just using a list of block names seems a bit tough. How can you remember what 100+ blocks look like?  I like the thumbnails your method provides.

 

Link to comment
Share on other sites

Charpzy why not select logos via choose A or  B or C and so on that would significantly reduce the number to be displayed ? Like Rlx you can make like a 100 slides in one go using a script. There is just a little issue about screen resolution now but that is easy to get around. You can easily choose which set to use for me a menu or could do a dcl choose group.

Edited by BIGAL
Link to comment
Share on other sites

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