List Box Functions

Function Syntax (LM:listtop / listup / listdown / listbottom <idx> <lst>)
Current Version 1.0
Download ListBoxFunctionsV1-1.lsp
View HTML Version ListBoxFunctionsV1-1.html
Donate
Arguments
Symbol Type Description
idx List List of zero-based indexes of items to be shifted
lst List List in which items reside
Returns
Type Description
List List of new indexes and repositioned items of the form ((idx) (lst))

Function Description

There are many programs which involve providing the ability for the user to reorder a list of items to suit their requirements, such as arranging layouts, layers or blocks.

In my experience, the most intuitive way to approach this situation is through utilisation of a DCL List Box coupled with a set of controls to manipulate the listed items. Indeed, I followed this approach with my TabSort program, which allows the user to reorder (among other functionalities) the layout tabs in a drawing; and also with my Layer Draw Order program, allowing the user to manipulate the relative draw-order of objects on each layer in a drawing.

To this end, I offer a set of functions which may be used to manipulate the order of multiple items in a DCL List Box. Each function requires a list of indexes of the items which are to be reordered, and a list of all items to be displayed in the DCL List Box. Following the reordering operation, the functions will each return a list of two elements: the first, a list of the indexes at which the reordered items are now located; and the second, the list of all items following the rearrangement operation.

The program file includes my Remove Items function.

An example program and several examples demonstrating how these functions may be used are included below.

Example Function Calls

_$ (setq lst '(0 1 2 3 4 5 6 7 8))
(0 1 2 3 4 5 6 7 8)

_$ (LM:listup '(2 4 6) lst)
((1 3 5) (0 2 1 4 3 6 5 7 8))

_$ (LM:listdown '(2 4 6) lst)
((3 5 7) (0 1 3 2 5 4 7 6 8))

_$ (LM:listtop '(2 4 6) lst)
((0 1 2) (2 4 6 0 1 3 5 7 8))

_$ (LM:listbottom '(2 4 6) lst)
((6 7 8) (0 1 3 5 7 8 2 4 6))

Example Program

Select all
(defun c:test ( / *error* dch dcl dcl-list des key-mode lst )

    (defun *error* ( msg )
        (if (< 0 dch) (unload_dialog dch))
        (if (= 'file (type des)) (close des))
        (if (and (= 'str (type dcl)) (findfile dcl)) (vl-file-delete dcl))
        (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )

    (setq lst
       '(
            "Item 0"
            "Item 1"
            "Item 2"
            "Item 3"
            "Item 4"
            "Item 5"
            "Item 6"
            "Item 7"
            "Item 8"
            "Item 9"
        )
    )

    (if
        (and
            (setq dcl (vl-filename-mktemp nil nil ".dcl"))
            (setq des (open dcl "w"))
            (foreach str
               '(
                    "listbox : dialog"
                    "{"
                    "    label = \"List Box Example\";"
                    "    spacer;"
                    "    : row"
                    "    {"
                    "        : list_box"
                    "        {"
                    "            key = \"lst\";"
                    "            width = 35;"
                    "            height = 15;"
                    "            fixed_width = true;"
                    "            fixed_height = true;"
                    "            multiple_select = true;"
                    "        }"
                    "        : column"
                    "        {"
                    "            fixed_height = true;"
                    "            : button { key = \"top\";    label = \"Top\";    }"
                    "            : button { key = \"up\";     label = \"Up\" ;    }"
                    "            : button { key = \"down\";   label = \"Down\";   }"
                    "            : button { key = \"bottom\"; label = \"Bottom\"; }"
                    "        }"
                    "    }"
                    "    spacer;"
                    "    ok_only;"
                    "}"
                )
                (write-line str des)
            )
            (not (setq des (close des)))
            (< 0 (setq dch (load_dialog dcl)))
            (new_dialog "listbox" dch)
        )
        (progn
            (defun dcl-list ( key lst )
                (start_list key)
                (foreach itm lst (add_list itm))
                (end_list)
            )
            (defun key-mode ( idx lst / foo )
                (setq foo (lambda ( a b / r ) (repeat a (setq r (cons (setq b (1- b)) r)))))
                (cond
                    (   (or (null idx) (= (length idx) (length lst)))
                       '(1 1 1 1)
                    )
                    (   (equal idx (foo (length idx) (length idx)))
                       '(1 1 0 0)
                    )
                    (   (equal idx (foo (length idx) (length lst)))
                       '(0 0 1 1)
                    )
                    (  '(0 0 0 0))
                )
            )
            (dcl-list "lst" lst)
            (mapcar 'mode_tile '("top" "up" "down" "bottom") '(1 1 1 1))
            (mapcar
                (function
                    (lambda ( key fun )
                        (action_tile key
                            (vl-prin1-to-string
                                (list 'if 'idx
                                    (list 'apply
                                      ''(lambda ( idx lst )
                                            (dcl-list "lst" lst)
                                            (set_tile "lst" (vl-string-trim "()" (vl-princ-to-string idx)))
                                            (mapcar 'mode_tile '("top" "up" "down" "bottom") (key-mode idx lst))
                                        )
                                        (list 'mapcar ''set ''(idx lst) (list fun 'idx 'lst))
                                    )
                                )
                            )
                        )    
                    )
                )
               '("top" "up" "down" "bottom")
               '(LM:listtop LM:listup LM:listdown LM:listbottom)
            )
            (action_tile "lst"
                (vl-prin1-to-string
                   '(progn
                        (setq idx (read (strcat "(" $value ")")))
                        (mapcar 'mode_tile '("top" "up" "down" "bottom") (key-mode idx lst))
                    )
                )
            )
            (start_dialog)
        )
        (princ "\nUnable to write/load/display dialog.")
    )
    (*error* nil)
    (princ)
)

Demonstration of Example Program

List Box Functions Demo

textsize

increase · reset · decrease

Designed & Created by Lee Mac © 2010