AfraLISP - Learn AutoLISP for AutoCAD productivity

DCL Progress Bar

by Nir sullam & anySOFT

This short tutorial will teach you how to create a nifty little Progress Bar in your dialog box. (such as the one in the PLOT dialog box).

This is needed when your program reports the user about its operation and progress when it usually takes some time.

One example is when you select a large amount of objects and the program makes some changes to them. If the process consumes time — the program needs to inform the user in percentage or in numbers.

First we create the DCL box for this example: It will have an EDIT_BOX to enter the MAX number, and also a "Start" BUTTON to start the loop function. The IMAGE tile is the tile where the progress bar will show.

dcltut : dialog {
    fixed_width = true;
    label = "DCL Progress Bar Tutorial 1.0";
    key = "br-label";
    : row {
       : button {
          key = "start";
          label = "Start";
          mnemonic = "S";
       }
       : edit_box {
          key = "max";
          label = "Max:";
          mnemonic = "M";
       }
    }
    : image {
       key = "progbar";
       fixed_width  = 50;
       height = 1;
    }
    /// This Tile may also be put below the OK_Cancel buttons
    : row {
       : button {
          label = "OK";
          mnemonic = "O";
          key = "ok";
       }
       : button {
          label = "Cancel";
          mnemonic = "C";
          key = "cancel";
          is_cancel = true;
       }
    }
    : row {
       : errtile {
          label = "";
          key = "error";
          width = 26;
       }
    }
}

The resulting DCL is as below: (the screenshot was taken while running)

Progress bar in action

The LISP file code is as follows:

;;; DCL Tutorial
;;; Subject: Creating a ProgressBar in DCL.
;;; This Tutorial is CopyRighted by Nir sullam and anySOFT 1999.
;;; It is free to use and free for distrubution

(defun C:PROGRESS (/ loopmax dcltut_dat)
   (setq dcltut_dat (load_dialog "c:\\dcltut.dcl"))
   ;; Put the DCL file where you want but make sure it is found by AutoCAD!!
   (new_dialog "dcltut" dcltut_dat)
   ;; if no maximum is set -Set the default to 100.
   (if (null loopmax)(setq loopmax 100))
   ;; color the image tile with the background color
   (setq fillx (dimx_tile "progbar"))
   (setq filly (dimy_tile "progbar"))
   (start_image "progbar")
   (fill_image 0 0 fillx filly -15)
   (end_image)
   ;; Set the edit_box tile to its value
   (set_tile "max" (itoa loopmax))
   ;; Assign the loopfunc to the start button
   (action_tile "start" "(loopfunc)")
   (action_tile "ok" "(done_dialog)")
   (action_tile "cnacel" "(done_dialog)")
   (start_dialog)
   (UNLOAD_DIALOG dcltut_dat)
)
;----------------------------------------------

(defun loopfunc (/ fillx filly loopfunc loopmax loop-counter)
   ;; Get the Horizontal length of the "progbar" tile
   (setq fillx (dimx_tile "progbar"))
   ;; Get the Vertical length of the "progbar" tile
   (setq filly (dimy_tile "progbar"))
   ;; Start the tile
   (start_image "progbar")
   ;; Initiate the -15 color as a background (-15 = Dialog Background  color)
   (fill_image 0 0 fillx filly -15)
   ;; end the initializing
   (end_image)
   ;; rewind the counter to 0
   (setq loop-counter 0)
   ;; get the value that is used as the maximum limit for the progress bar
   ;; in your application you may use it to show the progressing of a function that
   ;; processes a selction set so if your selection set length is 544 - the loopmax
   ;; will have to be assigned the value 544.(instead of using an edit_box tile as
   ;; I did in this example.)
   (setq loopmax (atoi (get_tile "max")))
   ;; As long as the counter is smaller than the maximum - fill the tile
   (while (<= loop-counter loopmax)
      (start_image "progbar")
      ;; The horizontal length is divided to "loopmax" times slices
      ;; It is the same as calculating a percent :
      ;; To get the 115% of 1250 you would do: (/ (* 115 1250) 100) but in this case,
      ;; the 100% is the MAXIMUM so we use a value other than 100.
      (fill_image 0 0 (/ (* loop-counter fillx) loopmax) filly 5)
      (end_image)
      ;; print the advance in the error tile
      (set_tile "error" (rtos loop-counter))
      ;; increment the counter
      (setq loop-counter (1+ loop-counter))
   )
)

One last note: To create a vertical Progress Bar just modify the FILLY instead of the FILLX !