Example - Text reads 4x6 next to a 4x6 recangle. When the user changes the
text to 6x8 it would modify to be 6x8.
Anyone? Thanks. :)
--
To reply via email remove 50 + 1 in my email address.
Sage,
This type of questions about Visual Lisp object reactors, are the ones most
of the collaborators to this customization newsgroup won't normally answer,
it can be because so many reasons...
Maybe those that have been in the past AU classes and took the ones about
reactors, will jump over here and show to us, what does they learn on there,
or maybe it was too classified and the information they got, that they are
not allowed to posted or share it over here or they do not visit this ng....
Sorry, I know this is not an answer to your question. btw: if I have time
this weekend I will make a reactor command for that...
Regards,
Luis.
Don
"Sage Cowsert" <scow...@pcsa51inc.com> wrote in message
news:40d1bd3a$1_3@newsprd01...
Tim
I can say that I have learn more about the basics of reactors usage and
implementation... and about the tutorial samples provided won't take anyone
into any direction.
Still, I would love to heard from someone that has been in the previous AU
and took some of the advanced or whatever reactors classes and want it to
heard from him/them if any out there please, teach us... please.
:-)
"Don Butler" <des...@nospam.superplumber.com> wrote in message
news:40d1caeb$1_3@newsprd01...
I have participated with some object reactor code for a Visual Lisp
programming book in Spanish.
Reactor implementation can be the key to powerful automated applications.
Don
"Luis Esquivel" <nos...@address.withheld> wrote in message
news:40d1cd86$1_3@newsprd01...
IDEA!
autodesk.autocad.customization-reactors
OK, I THOUGHT OF IT FIRST!!!
--
Ru...@Cadentity.com
AUTODESK
Authorized Developer
http://www.Cadentity.com
MASi
"Luis Esquivel" <nos...@address.withheld> wrote in message
news:40d1cd86$1_3@newsprd01...
"Rudy Tovar" <Ru...@cadentitynospam.com> wrote in message
news:40d1da39_3@newsprd01...
I think the reason you won't find people willing to "teach" this is that there is SO MUCH to teach, at least in a Discussion Group. Sure, you could write a quick and dirty program to do this or that, but there are so many ways a reactor program can turn into a major nightmare.
You should definitely check out the Garden Path tutorial, and if you don't have the patience to figure it out, you shouldn't be programming with reactors.
garcigj
"Luis Esquivel" <nos...@address.withheld> escribió en el mensaje
news:40d1ead0$1_3@newsprd01...
> Sage,
>
> Why wait to see at least a reactor command doing what you are asking...
> still it is not complete as I do not have to much time to play with it...
>
> and it is compiled, sorry..
>
> To test the command, please
>
> 1. open a new drawing
> 2. draw a rectangle
> 3. type a text object like: 100X100 - notice the X
> 4. load the separate namespace vlx and run the command: WXH
> 5. select the rectangle, and the text
> 6. modify the text ie: 100X100 -> 200X400
> 7. notice that the rectangle will modified accordingly.
>
> also, the sample provided does not have any error handler.
>
> remember this sample command is provided AS-IS no support et-al.
>
> Now, again I will like to see or know how the past seminars or labs about
> reactors in the AU had help to anyone that went to them, and if they are
> visited this ng. could tell us if it worth, and I was asking in the
previous
> post of mine about providing code, I will get even if I just heard about
> their experience..
>
> thanks
> le
>
>
>
;; finalize function
;; restore system variables, release activeX objects, restore error
(defun finalize ( / )
(setvar "OSMODE" osmode)
(setvar "ORTHOMODE" orthomode)
(mapcar 'vlax-release-object (list acadSpace acadDoc))
(setq *error* oerror)
)
;; myerror function
;; restore environment before ending
(defun myerror (msg / )
(princ msg)
(finalize)
)
;; 2d function
;; given coordinate list, returns 2d coordinates
(defun 2d (p / )
(list (car p) (cadr p))
)
;; DrawRectangle function
;; given a point, width and height,
;; return rectangle lwpolyline object
(defun DrawRectangle (centerPoint width height / cp returnObj)
;; calculate 4 corners of rectangle
(setq cp (2d centerPoint)
ul (polar cp (/ PI 2) (/ height 2))
ul (polar ul PI (/ width 2))
ur (polar ul 0 width)
lr (polar ur (/ (* 3 PI) 2) height)
ll (polar lr PI width)
;; create coordinate list in (x1 y1 x2 y2...) format for activex invoking
lstCoordinates (apply 'append (list ul ur lr ll))
)
(setq returnObj (vlax-invoke acadSpace "AddLightweightPolyline" lstCoordinates))
;; close lwpolyline
(vlax-put returnObj "Closed" :vlax-true)
returnObj
)
;; ObjectModified reactor function
;; called when dimension text is edited
;; receives text object, reactor object, parameter list
;; erases old lwpolyline rectangle, draws new rectangle at old centerpoint
;; edits reactor data to point to new rectangle
(defun ObjectModified (notifier-object reactor-object parameter-list)
;; if the reactor is still valid (wasn't removed in the ObjectErased reactor function)
;; (see ObjectErased reactor function description) then proceed.
(if (vlr-added-p reactor-object)
(progn
(prompt "\nDimension text edited--deleting old rectangle, creating new rectangle, updating reactor object with new handle.")
(initialize)
;; get text object (owner of reactor), new text string, new width & height
(setq textObj notifier-object
textString (vlax-get textObj "TextString")
lstWidthHeight (GetWidthHeight textString))
;; get handle and centerpoint stored in AttachReactor function
(setq lstHandleCenterpoint (vlr-data reactor-object)
rectangleHandle (car lstHandleCenterpoint)
rectangleCenterpoint (cadr lstHandleCenterpoint)
;; get activex object from handle
rectangleObj (vla-handletoobject acadDoc rectangleHandle))
;; delete old rectangle
(vla-delete rectangleObj)
;; draw new rectangle, get handle
(setq newRectangleObj (DrawRectangle rectangleCenterpoint (car lstWidthHeight) (cadr lstWidthHeight))
newRectangleHandle (vlax-get newRectangleObj "Handle"))
;; replace old handle with new handle
(vlr-data-set reactor-object (list newRectangleHandle rectangleCenterpoint))
(finalize)
(prompt "\nDone!")
); progn
); if
)
;; ObjectErased reactor function
;; called when dimension text is erased
;; receives textobject, reactor object, parameter list
;; erases lwpolyline rectangle, removes reactor
;; Note: Although the reactor is removed in this function, the ObjectModified function will still be called.
;; Since the ObjectModified function will try to erase the lwpolyline rectangle again,
;; I have added an "if" statement (vlr-added-p reactor-object) in the ObjectModified
;; function to test if the reactor is still valid by the time it gets to ObjectModified
;; function.
(defun ObjectErased (notifier-object reactor-object parameter-list)
(prompt "\nDimension text erased--removing reactor and associated rectangle.")
(initialize)
;; get handle and centerpoint stored in AttachReactor function
(setq lstHandleCenterpoint (vlr-data reactor-object)
rectangleHandle (car lstHandleCenterpoint)
rectangleObj (vla-handletoobject acadDoc rectangleHandle))
;; delete rectangle
(vla-delete rectangleObj)
;; remove reactor
(vlr-remove reactor-object)
;; Note: Although the reactor is removed, ObjectModified reactor has already been fired
(finalize)
(prompt "\nDone!")
)
;; AttachReactor function
;; receives text object, rectangle object and centerpoint
;; attaches the rectangle object's handle and centerpoint to the text object reactor
(defun AttachReactor (tObj rObj p / )
(setq rHandle (vlax-get rObj "Handle"))
(vlr-object-reactor (list tObj) (list rHandle p)
'((:vlr-modified . ObjectModified)
(:vlr-erased . ObjectErased)
)
)
)
;; GetWidthHeight function
;; receives text string in format "4x8"
;; returns width and height in list format (4.0 8.0)
(defun GetWidthHeight (txt / returnList)
(setq txt (strcase txt))
(if (setq xPosition (vl-string-search "X" txt))
(progn
(setq width (atof (substr txt 1 xPosition))
height (atof (substr txt (+ xPosition 2) (- (strlen txt) xPosition)))
returnList (list width height))
)
)
returnList
)
;; Main Program
;; asks user to select text entity containing text in format "4x8",
;; then prompts user for centerpoint for rectangle using dimensions in text
;; attaches an object reactor to text dimension so if dimensions are changed,
;; the rectange is updated (old rectangle deleted, new rectangle created)
(defun RectangleReactor ( / e textObj rectangleObj)
;; store/set system & global variables
(initialize)
;; get text entity selection
(while (null e)
(setq e (car (entsel "\nSelect text containing rectangle height and width in format \"4x8\" : ")))
(setq eType (cdr (assoc 0 (entget e))))
(if (not (or (= eType "TEXT") (= eType "MTEXT")))
(setq e nil)
)
)
;; get centerpoint for rectangle
(setq insPoint (getpoint "\nSelect centerpoint for rectangle: "))
;; get activex object from text entity, get text string, convert to width and height
(setq textObj (vlax-ename->vla-object e)
textString (vlax-get textObj "TextString")
lstWidthHeight (GetWidthHeight textString)
)
;; send width and height to DrawRectangle function and get new rectangle object
(setq rectangleObj (DrawRectangle insPoint (car lstWidthHeight) (cadr lstWidthHeight)))
;; send text, rectangle and centerpoint to AttachReactor function
(AttachReactor textObj rectangleObj insPoint)
;; release activex objects
(mapcar 'vlax-release-object (list textObj rectangleObj))
;; restore system variables, release objects
(finalize)
(princ)
)
;; rr shortcut to RectangleReactor
(defun rr ( / )
(RectangleReactor)
)
;; prompt user upon loading routine
(prompt "\nCreate a text entity with rectangle dimensions in the format \"4x8\"")
(prompt "\nand start RectangleReactor with command \"RR\"")
[/code]
So, make sure you have text in the drawing, like "20x30", and then run the routine.
Andrew
>
> and it is compiled, sorry..
>
Excuse me, but what is the point in compiling this "example" ?
Usually, requests for 'examples', are requests for
example source code, not a 'demo'.
AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005
http://www.acadxtabs.com
AutoCAD based Security Planning Solutions:
http://www.caddzone.com/securityplanning
Could you attach the file? I want to print it out and learn from it, but when i tried off the web site it cut off some of the text, and when I tried to copy/paste into note pad it came in as like only 4 lines (not with the beautiful spacing you did in your lisp).
Thanks for posting something we could read and learn from.
Tim
"Sage Cowsert" <scow...@pcsa51inc.com> wrote in message
news:40d1bd3a$1_3@newsprd01...
Something that might be considered:
1. Do not release the objects [in this particular case]
2. Use inside of your [modified event] callback something like:
(if (not (wcmatch (getvar "cmdnames") "U,UNDO,OOPS"))
(progn
;;; here do the update of your objects...
))
3. Also, have a look at the vla-put-coordinates instead of deleting the
polyline
> Excuse me, but what is the point in compiling this "example" ?
>
> Usually, requests for 'examples', are requests for
> example source code, not a 'demo'.
Most of the functions I am using for this are part of a commercial
application, that's the reason why.
I had post several times, a lot of open source code about the implementation
of visual lisp reactors.
Thanks.
Tim
Gary
"Luis Esquivel" <nos...@address.withheld> wrote in message
news:40d20e63$1_1@newsprd01...
Test your code in a start from stcratch drawing, and you will get a null
interface pointer.
> Aside from this being a quick response to the original poster, I didn't
make them persisent because...
> 1. I didn't want to assume the reactor functions would always be loaded
(i.e., drawing is shared with someone who does not have
rectanglereactor.lsp)
> 2. I have read many posts regarding the woes of persistent reactors.
>
> This leads into a question I have had regarding persistent reactors.
>
> Is there a way for me to attach an intelligent persistent reactor that
will automatically load the dependant reactor functions, even if lisp file
is not in the Directory Search Path (option), upon being triggered?
> I read that one solution was to NOT use persistent reactors, but to
instead, upon the drawing being closed, save all reactors in a drawing
dictionary and then release them all. When the drawing is opened and the
application is started again, the application reads in an reassigns all
reactors previously stored in the dictionary.
>
> Ideas?
Look for a template about usage of persistent reactors that I posted here as
open source code it has the workaround needed to make persistent reactors
[using: vlr-pers] work [I will try to find it and uploaded here - for all
benefit - no problema].
Anyway, I also use dictionaries to save and rebuild at loading time in order
to re-create the reactors.
There is a way to load automatically a separate namespace vlx the next time
you open a drawing where that application was loaded... without using
(load... or from appload... or anyother mean
Maybe Tony could gave to us a hint... if not I will posted here later...
Luis.
Here is the sample about vlr-pers... hth
;;; 5:20 PM 9/23/2003 - 9:14 AM 9/24/2003
;;;
;;; Permission to use, copy, modify, and distribute this file
;;; for any purpose and without fee is hereby granted, provided
;;; that the above copyright notice appears in all copies and
;;; that both that copyright notice and the limited warranty
;;; and restricted rights notice below appear in all supporting
;;; documentation.
;;;
;;; CADDXIMATION PROVIDES THIS PROGRAM "AS IS" AND WITH ALL
;;; FAULTS. CADDXIMATION SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY
;;; OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. CADDXIMATION
;;; SOFTWARE DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL
;;; BE UNINTERRUPTED OR ERROR FREE.
;;;
;;; PERSISTENT REACTORS TEMPLATE
;;;
;;; This code demostrates the usage of several "vlr-xxx" functions
;;; that are not well documented in the developers help file
;;; you can read from the in-line descriptions to understand what
;;; is the intention of the code, that I am proposing.
;;;
;;; By following this template you will be able to write persistant
;;; reactors and get the advantage of using the "vlr-pers" function
;;; of Visual Lisp.
;;;
;;; Author notes:
;;;
;;; 1. Place the code in your "xxx.mnl"
;;; 2. This is an academic code.
;;; 3. There is no error handler included.
;;; 4. If you want to make a separate namespace VLX, you must use
;;; "vlr-set-notification" to the active document only.
;;; 5. There is no "vlr-dwg-reactor" included with the begin close
;;; event, you must include also the reactors removal like:
;;; (vlr-remove-all)
;;;
;;; Hope that you can have a better trip around the Visual Lisp
;;; reactors, this is just a small part of them.
;;;
;;; Luis Esquivel.
;;; function to update the persistent reactors dictionary
;;; note: does not verifies for nil owners or' vlr-data
;;; also, is not used in this sample, but is provided
;;; in case is needed
(defun update-pers-list (/ pers)
(if (setq pers (vlr-pers-list))
(progn
(mapcar
(function
(lambda (r)
(cond
((and (equal (vlr-type r) :vlr-object-reactor)
(vl-some 'vlax-erased-p (vlr-owners r)))
(foreach owner (vlr-owners r)
(vlr-owner-remove r owner))
(vlr-data-set r nil)
(vlr-pers-release r))
((and (vlr-added-p r)
(not (equal (vlr-type r)
:vlr-object-reactor))
(vl-some 'vlax-erased-p (vlr-data r)))
(vlr-data-set r nil)
(vlr-pers-release r)))))
pers))))
;;; returns a list with the list of reactors or nil
;;; (list (list reactor) (list reactor) ...)
(defun attached-to (obj)
(vl-remove
nil
(mapcar
(function
(lambda (reactor_type)
(vl-remove-if-not
(function
(lambda (r)
(cond
((and (equal reactor_type :vlr-object-reactor)
(vl-position obj (vlr-owners r)))
r)
((and
(not (equal reactor_type
:vlr-object-reactor))
(vl-position obj (vlr-data r)))
r))))
(cdar (vlr-reactors reactor_type)))))
(vlr-types))))
;;; avoids the unwind message
;;; by doing this we are letting autocad to redo our reactors
(defun not-unwind ()
(not (wcmatch (getvar "cmdnames") "U,UNDO,REDO,OOPS")))
;;; callback function for the line modification event
(defun tst-modified-line (owner reactor params)
(if (not-unwind)
(prompt "\nLine modified... \n")))
;;; callback function for the circle modification event
(defun tst-modified-circle (owner reactor params)
(if (not-unwind)
(prompt "\nCircle modified... \n")))
;;; callback function for the erased event (for both objects in this sample)
;;; note: do not use (vlr-remove reactor)
;;; since this will not going to allow the removal from the (vlr-pers-list)
(defun tst-erased (owner reactor params / reactors)
(if (not-unwind)
(progn
;; search the reactor associated data
(foreach obj (vlr-data reactor)
;; get all the reactors attached to one
;; of the objects in the associated data
(if (setq reactors (attached-to obj))
(progn
;; steping through all the members in the reactors list
;; note: the use of "(mapcar 'car reactors)"
;; is because the (attached-to <obj>) returns a list of lists
;; like: (list (list reactor) (list reactor) ...)
(foreach r (mapcar 'car reactors)
;; if the reactor is an object-reactor?
(if (eq (vlr-type r) :vlr-object-reactor)
;; remove the owner
(vlr-owner-remove r obj))
;; make the reactor transient and at the same time
;; remove it from the (vlr-pers-list)
(vlr-pers-release r)
;; remove the associated data from the reactor
(vlr-data-set r nil)))))
;; remove the owner from the reactor
(vlr-owner-remove reactor owner)
;; remove the associated data from the reactor
(vlr-data-set reactor nil)
;; make the reactor transient and remove it from the (vlr-pers-list)
(vlr-pers-release reactor))))
;;; command test to make two persistent object-reactors for a line and
circle
;;; note: before running this test you need to draw the line and the circle
(defun C:TST (/ vla_line
vla_circle :tst-reactor-line
:tst-reactor-circle)
(setq vla_line
(vlax-ename->vla-object (car (entsel "\nLine: "))))
(setq vla_circle
(vlax-ename->vla-object (car (entsel "\nCircle: "))))
(setq :tst-reactor-line
(vlr-object-reactor
(list vla_line)
(list vla_circle)
'((:vlr-modified . tst-modified-line)
(:vlr-erased . tst-erased))))
(setq :tst-reactor-circle
(vlr-object-reactor
(list vla_circle)
(list vla_line)
'((:vlr-modified . tst-modified-circle)
(:vlr-erased . tst-erased))))
;; make the reactors persistent
(setq :tst-reactor-line (vlr-pers :tst-reactor-line))
(setq :tst-reactor-circle (vlr-pers :tst-reactor-circle)))
(princ)
Also have a look at the next function to read the activespace, in your
sample make a test while you are in inside of a floating viewport [being in
paper - and -> mspace] and noticed what happen with the reactangle... is
drawn on paper and the text left on model:
(defun rwiz-thisdwg () (vla-get-activedocument (vlax-get-acad-object)))
(setq
:rwiz_thisdwg
(cond (:rwiz_thisdwg)
((rwiz-thisdwg))))
(or :rwiz_model
(setq :rwiz_model
(vla-get-modelspace (rwiz-thisdwg))))
(defun rwiz-pspace () (vla-get-paperspace (rwiz-thisdwg)))
(defun rwiz-get-activespace ()
(if (= acmodelspace (vla-get-activespace (rwiz-thisdwg)))
:rwiz_model
(if (= (vla-get-mspace (rwiz-thisdwg)) :vlax-true)
:rwiz_model
(rwiz-pspace))))
Thanks for the input.
You are welcome...
The best option I have found is to re-create the reactors at loading time,
by saving the objects inside of dictionary.
And to make a separate namespace vlx for this type of commands... I will
wait until Tony or any orther of the masters here , could point about
loading a protected vlx automatically... [on each of the drawings where was
used]... as I mentioned in my previous post.
le.
Also, I posted a sample code open-source for this thing in particular some
time ago, I included all the sequence and functions for saving, appending
and enabling the reactors to emulate what vlr-pers does...
Don't remember the name of the thread... but I will look around for that...
I am about to leave now, see you guys Monday.
Have fun.
Luis.