Jump to content

Recommended Posts

Posted
36 minutes ago, BIGAL said:

@rlx :beer:

Is it possible to type from right to left in edit_box ?

 

Posted
13 minutes ago, mohammadreza said:

Is it possible to type from right to left in edit_box ?

 

 

wow , that's a very good question ... to which I have no answer ... did some searching but found nothing to suggest this is possible with standard AutoCad / DCL

  • Like 2
Posted

Back of my mind says there was something somewhere but I have no idea where it was. Think it was gread, record the letters typed, reverse the order and replace in the edit box.. but  can't remember where I saw that of indeed if it was for something else!

Posted

Can only think of in the action_tile call a defun that keeps making a string in reverse order using strcat and set_tile value. Interesting problem. Not sure how fast the tile will update. 

 

This proves it may be possible I think need two edit boxes one for result and the first for only one character. It is buggy and not working correctly. Enter a character and select another edit box. It should auto update when you enter a character. Taking last character and putting it at start.

(defun wow ( / )
(defun doit ( / )
(setq oldstr (strcat (get_tile "name") oldstr))
(set_tile "name2" oldstr)
(set_tile "name" "")
)
(setq oldstr "")
(setq dcl_id (load_dialog "d:\\acadtemp\\test.dcl"))
(if (not (new_dialog "xxxx" dcl_id) )
(exit)
)
(action_tile "name" "(doit)")
(unload_dialog dcl_id)
(action_tile "accept" "(done_dialog)")
(action_tile "cancel" "(done_dialog)")
(start_dialog)
(unload_dialog dcl_id)
(princ)
)
(wow)

 

xxxx : dialog {
: boxed_column { fixed_width = true ;
      label = "test wow˜"; 
      : row {
       : edit_box { key = "name"; width = 25; }
	    : text { label = "type text "; alignment = right; }
      }
      : row {
    : edit_box { key = "name2"; width = 25; }
	 : text { label = "ätext 2"; alignment = right; }
      }
      : row {
        : edit_box { key = "personal_code"; width = 25; edit_limit = 10; }
		 : text { label = "˜text 3"; alignment = right; }
      }
      : row {
        : edit_box { key = "address"; width = 25; }
		  : text { label = "text4";  alignment = right; }
      }
spacer_1 ;
ok_cancel;
}
}

 

Posted
2 hours ago, mohammadreza said:

Is it possible to type from right to left in edit_box ?

 

 A direct answer is no.

 

You can trick AutoCAD though.

 

You might try using MText for the Right-to-Left input then capture that and add to the DCL.

 

Something like this, maybe...

 

(command "_mtext")
  ;; Types Right-to-Left in the MTEXT editor, then presses OK
  ;; Select the MTEXT
  (setq ent (entsel "\nSelect the MTEXT object: "))
  (if ent
    (progn
      (setq eData (entget (car ent)))
      (setq MtextContent (cdr (assoc 1 eData))) ; Extract content
      (setq RLText (strip-formatting MtextContent)) ; Formatting cleanup
      (display-in-dcl RLText)
    )

 

There might be some other tricks, you should check forums that use Right-to-Left.

 

Might want to look into higher level programming.

 

Untested Python version, though you see it's natively possible, tkinter (there are others like PyQt5 which may be what you need.) is a GUI for Python.

 

import win32com.client
import tkinter as tk
import re

def get_mtext_content():
    acad = win32com.client.Dispatch("AutoCAD.Application")
    doc = acad.ActiveDocument
    sel = doc.Utility.GetEntity("Select MTEXT object: ")
    mtext_obj = sel[0]
    return mtext_obj.TextString

def clean_mtext(text):
    return re.sub(r'\\[A-Za-z0-9]+', '', text)

def show_text_in_gui(text):
    root = tk.Tk()
    root.title("RTL Text Viewer")

    entry = tk.Entry(root, width=60, justify='right')
    entry.pack(padx=20, pady=20)
    entry.insert(0, text)

    root.mainloop()

if __name__ == "__main__":
    text = get_mtext_content()
    clean_text = clean_mtext(text)
    show_text_in_gui(clean_text)

 

Posted (edited)

Just an idea, will reverse the text as it is typed and enter into the command line, I've just put a repeat of 10 in for now, would usually do a while loop, while MyInput isn't a mouse click or something like that - I don't use Grread a lot to remember what to use, I'd need to think.

 

Instead of printing to the command line it could directly update an edit box, and call the routine with an action tile when you click into the edit box

 

 

(defun c:ReverseText ( / MyString MyInput MyText)
  (setq MyString "")
  (repeat 10
    (setq MyInput (grread nil 2))
    (setq MyText (chr (cadr MyInput)))
    (setq MyString (strcat MyText MyString))
    (princ MyString)
    (princ "\n")
  ) ; end repeat
  (princ)
)

 

 

Edit:

For edit box use I would put in a loop, (if (= endloopflag "No") ..... ) and (setq endloopflag "Yes") if (cadr MyIntput) is character 9 (tab), 13 (enter) or a list (mouse button). Set MyString to (get_tile "EditBoxName") at the beginning

Edited by Steven P
Posted

Steven P that is what I attempted to do, if you click in a Edit box can call a defun say reversetext but you can you use GRREAD or any type of input without closing the dcl, then reopen with the edit box filled in.

 

I know going back to my code I typed A B C D E and got EDCBA in next edit box. So could call a CHILD dcl to do the reverse with 2 edit boxes. I am sure it's just something I am missing that when I enter say "A" in edit box 1 it auto updates edit box 2 and reset edit box 1 back to "". Try the code and you will see the reverse occurs, without closing the dcl. Enter A box1 click box two go back to box1 type next character click box2 to see update, repeat.

 

So my question I am missing an auto do action_tile update when a single character entered. Could not find a reference to force update. Not sure if OpenDCL supports that action. Iwould think its there just a dcl setting.

  • Like 1
Posted

It is an interesting problem, and I am sure there is a solution. I couldn't find it last night though.

 

I couldn't get grread to work with a DCL open though, loop of doom, might have missed something, had a quick look at grread, close dcl, open dcl see if that worked but didn't really get far with that.

 

One thought I had was a loop while the DCL is open, set an end loop flag along with 'done_dialog', each loop test the edit box for a change, if change flip the last letter to the beginning. Not sure how / if this would work or if it would freeze everything.

Posted

I looked for a bit yesterday, there were a few reverse-string codes, never saw where they were usable in DCL, maybe.

 

I read one recommending using Unicode to do this. 

 

Some other issues is the computer's language and English or Arabic, etc., keyboard.

 

You have to make sure  the text style  supports Arabic characters, etc.

 

There might be a way with VBA, I don't have any method to test unless I set up my computer for Right-to-Left text.

 

I know we have at least a couple of LISPers that use  Right-to-Left languages, maybe they will chime in.

 

I need to make this a separate thread as it's not really in line with the OP. 

 

Here is the original thread if anyone needs to reference it.

 

 

  • Like 1
Posted

Think its a lot of trouble for litlle gain. But if I where to try something out of the box , I would create dynamic sized edit_boxes where after every input the dialog would need to be refreshed.

This would also mean app would need to have option to calibrate (once) for different fonts / resolutions. 

Maybe even put a dynamic white image in front of the edit_box to compensate for different edit_box lengths.

Just a thought...

 

🐉

Posted (edited)

@rlx " after every input the dialog would need to be refreshed." that was the issue I was having with reversing the text, I had to pick a different edit box each time to update an edit box value. In the code I posted it works and resets the 1st edit box displaying answer in a 2nd box. I can see a substring method of getting right character and moving it to left as part of the action_tile defun call. I tried to find an autoupdate an edit box variable. Maybe linked to node_tile.

Edited by BIGAL
Posted

this kinda works , but its far from perfect because computers can have different screen resolutions , different fonts etc. It works by adding spaces before or after string.

But some strings have al lot of i's and others a lot of W's so its nearly impossible to get this right.

Could count the number of i's in a string and for each one add double space etc.

It's just not worth the trouble , not for me that is. This is just academic , play , nice to have , not need to have.

 

;;; https://www.cadtutor.net/forum/topic/70013-vertical-alignment-dcl/

(defun c:mohammadreza ( / regkey regvar eb-list return OldErr
                          dialog-fn dialog-fp dialog-id Dialog-tl Dialog-rd
                          name father-name personal-code address align-factor)
  (mohammadreza_init)
  (mohammadreza_start_dialog)  
  (if (vl-consp return)(dplm return "Voila...")(alert "Dialog was cancelled"))
  return
)

(defun Mohammadreza_Err ($s) (princ $s)(Mohammadreza_Exit)(setq *error* OldErr)(princ))

(defun Mohammadreza_Exit ()
  (mapcar '(lambda (x) (if (not (null x)) (unload_dialog x))) (list dialog-id))
  (mapcar '(lambda (x) (if (not (null x)) (close x))) (list dialog-fp ))
  (mapcar '(lambda (x) (if (and (not (null x))(findfile x))(vl-file-delete x)))(list dialog-fn ))
  (term_dialog) (gc) (princ "\nDone") (terpri) (princ)
)


(defun mohammadreza_init ()
  (setq OldErr *error* *error* Mohammadreza_Err)
  (setq eb-list (list "name" "father-name" "personal-code" "address"))
  (InitDefaultRegistrySettings)(ReadSettingsFromRegistry)
)

;;; --- Registry Settings ------------------------------- Begin Registry Settings ------------------------------- Registry Settings --- ;;;

(defun InitDefaultRegistrySettings () (setq regkey "HKEY_CURRENT_USER\\SOFTWARE\\Mohammadreza\\")
  (setq regvar '(("name" "")("father-name" "")("personal-code" "")("address" "") ("align-factor" "1")))
  (mapcar '(lambda (x)(set (read (car x)) (cadr x))) regVar))

(defun ReadSettingsFromRegistry () (mapcar '(lambda (x / n v)
  (if (setq v (vl-registry-read regkey (setq n (car x)))) (set (read n) v) (vl-registry-write regkey n (cadr x)))) regvar))

(defun WriteSettingsToRegistry () (mapcar '(lambda (x) (vl-registry-write regkey (car x) (eval (read (car x))))) regvar))

;;; --- Registry Settings -------------------------------- End Registry Settings -------------------------------- Registry Settings --- ;;;


; SaveDialogData evaluates all vars from %tl and returns them as a list, reset does the opposite
(defun Save_Dialog_Data      (%tl) (mapcar '(lambda (x) (eval (car x))) %tl))
(defun Reset_Dialog_Data (%tl %rd) (mapcar '(lambda (x y) (set (car x) y)) %tl %rd))
(defun Set_Dialog_Tiles      (%tl) (mapcar '(lambda (x / v) (if (eq 'str (type (setq v (eval (car x))))) (set_tile (cadr x) v))) %tl))
(defun Cancel_Dialog            () (Reset_Dialog_Data Dialog-tl Dialog-rd) (WriteSettingsToRegistry))


(defun mohammadreza_start_dialog ( / drv )
  (mohammadreza_create_dialog)
  (if (not (and (setq dialog-id (load_dialog dialog-fn)) (new_dialog "mohammadreza" dialog-id)))
    (princ "\nUnable to start dialog")
    (progn
      (mohammadreza_init_dialog) (mohammadreza_update_dialog) (mohammadreza_action_dialog)
      (if (and fn (findfile fn)) (vl-file-delete (findfile fn))) (setq drv (start_dialog))
      (cond
        ((= drv 0) (Cancel_Dialog))
        ((= drv 1) (WriteSettingsToRegistry))
      )
    )
  )
  (princ)
)

(defun mohammadreza_create_dialog ()
  (if (and (setq dialog-fn (vl-filename-mktemp "mohammedreza.dcl")) (setq dialog-fp (open dialog-fn "w")))
    (mapcar '(lambda (x)(write-line x dialog-fp))
             (list
               "mohammadreza : dialog {label=\"Mohammadreza 5/'25\";"
               "  :boxed_row {label=\"ÇØáÇÚÇÊ ãÇá˜\";"
               ;;; "    :column {:eb {key=\"name\";}:eb {key=\"father_name\";}:eb {key=\"personal_code\";edit_limit=10;}:eb {key=\"address\";}}"
               "    :column {:ib {key=\"name\";}:ib {key=\"father-name\";}:ib {key=\"personal-code\";edit_limit=10;}:ib {key=\"address\";}}"
               "    :column {vertical_margin=none;children_fixed_width=true;children_alignment=right;"
               "      :tr {label=\"äÇã æ äÇã ÎÇäæÇÏí\";}:tr {label=\"äÇã ÏÑ\";}:tr {label=\"˜Ï ãáí\";}:tr {label=\"ÂÏÑÓ\";}}}"
               "  :concatenation {children_fixed_width=true;alignment=centered;"
               "    :button {fixed_width=true;width=3;key=\"bt_plus\";label=\"+\";}"
               "     ok_cancel;"
               "    :button {fixed_width=true;width=3;key=\"bt_min\";label=\"-\";}"
               "  }"
               "}"
               "eb :edit_box {fixed_width=true;width=25;vertical_margin=none;edit_width=25;}"
               "tr :text     {alignment=right;fixed_width=true;width=25;}"
               "ib :image_button {fixed_width_font=true;fixed_width=true;width=30;fixed_height=true;height=1.6;color=7;}"
             )
    )
  )
  (if dialog-fp (close dialog-fp))
  (gc)
)

(defun mohammadreza_init_dialog () (princ) )

(defun mohammadreza_update_dialog ( )
  (setq Dialog-tl '((name "name") (father-name "father-name") (personal-code "personal-code") (address "address") )  )
  (if (null Dialog-rd) (setq Dialog-rd (Save_Dialog_Data Dialog-tl))) (Set_Dialog_Tiles Dialog-tl)
  (RefreshImageButtonStrings)
)

(defun mohammadreza_action_dialog ()
  (mapcar '(lambda (x)(action_tile (car x) (cadr x)))
          '(("cancel" "(done_dialog 0)") ("accept" "(create_return_list)(done_dialog 1)")
            ("name" "(update_image_button $key)") ("father-name" "(update_image_button $key)")
            ("personal-code" "(update_image_button $key)") ("address" "(update_image_button $key)")
            ("bt_plus" "(update_align_factor 1)") ("bt_min"  "(update_align_factor -1)")
           )
  )
)

(defun update_align_factor ( i / f )
  (if (void align-factor)(setq f 1)(setq f (atoi align-factor)))
  ;(cond ((= i 1) (setq f (1+ f))) ((= i 0) (setq f (1- f)))(t (setq f 1)))
  ;(if (< f 1)(setq f 1))
  (if (minusp i) (setq f (1- f)) (setq f (1+ f)))
  (setq align-factor (itoa f))
  (RefreshImageButtonStrings)
)

(defun RefreshImageButtonStrings ( / s i l)
  (if (void align-factor)(setq align-factor "1"))
  (setq i (+ 30 (atoi align-factor)))
  (foreach tile eb-list
    (setq s (vl-string-trim " " (eval (read tile))) l (strlen s))
    (if (minusp (atoi align-factor))
      (while (< l i) (setq s (strcat s " ") l (strlen s)))
      (while (< l i) (setq s (strcat " " s) l (strlen s)))
    )
    (set (read tile) s) (wipe_ib tile 7) (set_tile tile s)
  )
)

;;; eb-list (list "name" "father-name" "personal-code" "address")
(defun create_return_list () (setq return (mapcar '(lambda (x)(vl-string-trim " " (eval (read x)))) eb-list)))

(defun void (x) (or (eq x nil) (and (listp x)(not (vl-consp x))) (and (eq 'STR (type x)) (eq "" (vl-string-trim " \t\r\n" x)))))

;;; display list + message (test function)
(defun dplm (l m / f p d w) (and (vl-consp l) (setq l (mapcar 'vl-princ-to-string l)) (setq w (+ 5 (apply 'max (mapcar 'strlen l))))
  (setq p (open (setq f (vl-filename-mktemp ".dcl")) "w")) (princ (strcat "cfl:dialog{label=\"" m "\";:list_box {key=\"lb\";"
   "width="(itoa w)";}ok_only;}") p)(not (setq p (close p)))(< 0 (setq d (load_dialog f)))(new_dialog "cfl" d)(progn (start_list "lb")
     (mapcar 'add_list l)(end_list)(action_tile "accept" "(done_dialog)")(start_dialog)(unload_dialog d)(vl-file-delete f))))

;;; simple dialog for getstring $tile is name of dcl tile like "name"
;;; $tile is also name of variable that holds value
(defun ask ( $tile / f p d r s v)
  (if (and (setq f (vl-filename-mktemp ".dcl"))(setq p (open f "w")))
    (progn
      (write-line (strcat "ask :dialog {label =\"" $tile "\";:edit_box {key=\"eb\";}spacer;ok_cancel;}") p)
      (close p)(gc)
      (setq d (load_dialog f))(new_dialog "ask" d)
      (mapcar '(lambda (x y)(action_tile x y)) '("eb" "accept" "cancel") '("(setq s $value)""(done_dialog 1)""(done_dialog 0)"))
      (setq v (vl-string-trim " " (eval (read $tile))))
      (set_tile "eb" v) (mode_tile "eb" 2)
      (setq r (start_dialog))(unload_dialog d)(vl-file-delete f)
    )
  )
  (if (and (= r 1) (= 'STR (type s)) (/= s "")) s "")
)

;;; get string (indirectly) from image_button (disguised as edit_box) through it variable name
;;; $k is name of dcl tile like "name" which is also variable name
(defun update_image_button ($k / s l i)
  (if (void align-factor) (setq align-factor "1"))
  (setq s (ask $k)) (set (read $k) s)
  ;;; 30 is width of image_button
  (setq i (+ 30 (atoi align-factor)) l (strlen s))
  ;;; length of image_button (edit_box in disguise) is 30
  (while (< l i) (setq s (strcat " " s) l (strlen s)))
  ;;; save back to variable
  (set (read $k) s)
  ;;; first wipe image button clean
  (wipe_ib $k 7)
  (set_tile $k s)
)

(defun wipe_ib (ib co) (start_image ib) (fill_image 0 0 (dimx_tile ib) (dimy_tile ib) co)(end_image))

(defun c:t1 () (c:mohammadreza) (princ))

;(c:t1)

 

🐉

Posted
On 5/20/2025 at 8:56 AM, rlx said:

Think its a lot of trouble for litlle gain. ...

?tfel ot thgir nettirw ylno s'taht egaugnal a kaeps uoy fi tahw tub ,seY

 

Yes, but what if you speak a language that's only written right to left?

  • Like 1
Posted

yeah , if you live in a mirror universe then you are !@#$%^ haha.

 

If I find the time I'll try to tweak it a little more. I believe Lee Mac has done something simular in his grtext routine.

By weighing all caracters it is possible to predict more precisely the width for each character.

And mayby it can be done even simpeler , using a text_part with a right alignment next to a white image.

Gonna be very busy this weekend , dusting of a program I wrote a year ago for my boss but suddenly no budget for the job,.

Now there might be a budget and suddenly all has to be done yesterday you know , but I have no more active memories to the program.

Must be karma or something... 😱

 

🐉

  • Like 1

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