:vlr-SysVarWillChange

Discussion in 'AutoCAD' started by John Uhden, Feb 23, 2004.

  1. John Uhden

    John Uhden Guest

    Is it just a VisualLisp limitation that many sysvars won't fire a reaction, such
    as "ctab" "viewctr" "viewsize?" Are there other programming languages that can
    recognize their change?

    I realize that the vlr-AcDb-Reactor will fire on many things (still excepting
    "viewctr" and "viewsize"), but that's exactly why you can't use it in real
    life... way too many reactions.
     
    John Uhden, Feb 23, 2004
    #1
  2. Tony Tanzillo, Feb 23, 2004
    #2
  3. John Uhden

    Doug Broad Guest

    Hi John,

    How've you been?

    CTAB should react if ctab is changed explicitly by the user.
    At least it does when I try. Other variables typically change
    when a user clicks other layout tabs so the CTAB change can be
    tracked that way.

    What is your application for tracking viewctr and viewsize?

    Regards,
    Doug
     
    Doug Broad, Feb 23, 2004
    #3
  4. John Uhden

    John Uhden Guest

    Hi, Doug. Thanks for the interest. I really don't care about VIEW*; I know
    that's pointless.

    LAYOUT_CONTROL doesn't report any change in the value of CTAB, and the Sysvar
    reactor doesn't fire at all if you just rename a layout. (LDT4)
     
    John Uhden, Feb 23, 2004
    #4
  5. John Uhden

    Doug Broad Guest

    John,

    You're right about nothing happening when someone renames the tab.
    Seems strange.

    If you want to trap those kinds of changes, you could always use
    an object reactor tied to the activelayout(which will definitely work)
    or to the dictionary (I think) that keeps track of the layoutlist.

    The real limitation is not being able to act on the info or access the
    object during the reactor. You still need to wait till the event is
    over and the object released to act on it. This is one are that
    Autodesk should have improved by now.
     
    Doug Broad, Feb 24, 2004
    #5
  6. John Uhden

    Mark Propst Guest

    something i was playing with once in response to a question on the ng a
    while back.
    a clumsy workaround to be sure...
    (defun C:WatchLayouts( / oldlist newlist)
    (defun MakeLayoutChangeReactor (data)
    (if (/= (type *LayoutChangeReactor*) 'VLR-Editor-Reactor)
    (setq *LayoutChangeReactor*
    (vlr-editor-reactor
    data
    '
    (
    :)vlr-commandwillstart . editor::vlr-commandwillstart)
    :)vlr-commandended . editor::vlr-commandended)
    )
    )
    )
    );if
    (if (not (vlr-added-p *LayoutChangeReactor*))
    (vlr-add *LayoutChangeReactor*)
    )
    );
    (defun editor::vlr-commandwillstart(vlaobject parameterlist)
    (if(= "LAYOUT_CONTROL" (car parameterlist))
    (setq oldlist (layoutlist))
    )
    (princ)
    )
    (defun editor::vlr-commandended(vlaobject parameterlist)
    (if(= "LAYOUT_CONTROL" (car parameterlist))
    (progn
    (setq newlist(layoutlist))
    (checklists oldlist newlist)
    )
    )
    (princ)
    )
    (defun checklists(oldlist newlist / newname)
    (cond
    ((/=(length oldlist)(length newlist))
    (if
    (>(length oldlist)(length newlist))
    (progn
    (princ"\nLayout deleted: ")
    (mapcar(function(lambda(nme)
    (if(not(member nme newlist))
    (princ nme))))oldlist)
    )
    (progn
    (princ"\nLayout added: ")
    (mapcar(function(lambda(nme)
    (if(not(member nme oldlist))
    (princ nme))))newlist)
    )
    )
    )
    ((=(length oldlist)(length newlist))
    (mapcar (function (lambda(x)
    (if(not(member x oldlist))
    (setq newname x))))
    newlist
    )
    (if newname
    (princ(strcat"\nLayout renamed: " newname))
    )
    );c2
    );coned
    );def
    (MakeLayoutChangeReactor nil)
    )
    not what you're looking for I'm sure but at least peripheral to the
    question.
     
    Mark Propst, Feb 24, 2004
    #6
  7. John Uhden

    John Uhden Guest

    Thanks, Doug and Mark. Been down those dusty roads.

    I've had a LayoutSwitching reactor for some time (as opposed to the past tense
    LayoutSwitched reactor). It uses the :vlr-SysVarChanged reaction, but it
    doesn't respond to renaming a layout. Now the vlr-Command-Reactor could report
    what I want if the LAYOUT_CONTROL or CTAB command is invoked, but there are
    other ways a layout can change, and you'd never know it.

    I had tried Doug's idea of attaching an object reactor to the Layouts collection
    (dictionary), but it's apparently tongue-tied in letting you know what's
    happening. In fact, there is no response when creating a new layout by copying
    from another. That's why I was asking if other languages can receive
    notifications that VisualLisp can not.

    So I could use an Object-Reactor on the layouts so long as I can read the data I
    want (VPlayer) and write it somewhere else in the drawing (dictionary), but it
    appears it will be just a hodge-podge of potentially dueling reactors to cover
    the switches, copies, renames, additions, deletions.

    Unless someone can recommend a magic elixir, I guess I'm stuck with my
    LayoutSwitching concoction and deal with new/deleted layouts when they show up.
    :/




    Not so. That's pretty good.
     
    John Uhden, Feb 25, 2004
    #7
  8. John Uhden

    James Buzbee Guest

    Well maybe there is a different approach altogether (or not). You mentioned
    VPLayer - does this have to do with matricing(sp) layers to come up with
    different civil plans, ie geometry layout, utilitiy, landscape etc. If so,
    why not look into another way of dealing with this scenario . . . if this is
    the case I can help.

    jb
     
    James Buzbee, Feb 25, 2004
    #8
  9. John Uhden

    John Uhden Guest

    Hi, James.

    Since you're either psychic or remembered I'm a civil type, maybe what you have
    to offer in that context would be a revelation. Sorry, but I lied about
    VPlayer. It's really about tying named Layer_States to a layout. The missing
    link is the name, of which I can't be sure if a layout is renamed or copied from
    another. I have alternate methods in mind, but they're a little extruded (not
    that that has ever held me back). Anyway, feel free to point me in any
    direction, and thanks.
     
    John Uhden, Feb 26, 2004
    #9
  10. John Uhden

    Doug Broad Guest

    Have you thought about handles instead of names?
    Layouts have handles which don't change.
     
    Doug Broad, Feb 26, 2004
    #10
  11. What about placing an Extension dictionary on the layout. Seems to be I've
    done this code already...


    --
    R. Robert Bell, MCSE
    www.AcadX.com


    Hi, James.

    Since you're either psychic or remembered I'm a civil type, maybe what you
    have
    to offer in that context would be a revelation. Sorry, but I lied about
    VPlayer. It's really about tying named Layer_States to a layout. The
    missing
    link is the name, of which I can't be sure if a layout is renamed or copied
    from
    another. I have alternate methods in mind, but they're a little extruded
    (not
    that that has ever held me back). Anyway, feel free to point me in any
    direction, and thanks.
     
    R. Robert Bell, Feb 26, 2004
    #11
  12. Yup... this is from a thread I participated in on VBDesign. I think I got
    all the parts here <g>. You ought to be able to fill in any missing pieces.
    Note that this was written for 2004. 2002 needs to have LayoutRegenCtl set
    to 0 before restoring the layer state.


    ' Below is the TuFer version
    ' No change to LayoutRegenCtl is req'd
    ' Written by: R. Robert Bell

    Private Sub AcadDocument_LayoutSwitched(ByVal LayoutName As String)
    If LayoutName = "Model" Then
    RestoreLState "all"
    Else
    RestoreLState GetTabLState()
    End If
    End Sub


    Private Sub RestoreLState(Name As String)
    Dim LSMan As AcadLayerStateManager
    Set LSMan = GetInterfaceObject("AutoCAD.AcadLayerStateManager.16")
    LSMan.SetDatabase ThisDrawing.Database
    LSMan.Restore Name
    ThisDrawing.Regen (acAllViewports)
    Set LSMan = Nothing
    End Sub


    Private Function GetTabLState() As String
    Dim Layout As AcadLayout
    Set Layout = ThisDrawing.ActiveLayout

    If Not (Layout.HasExtensionDictionary) Then SetTabLState

    Dim XRec As AcadXRecord
    Set XRec = Layout.GetExtensionDictionary("TabHasLState")

    Dim dxfCodes, dxfData
    XRec.GetXRecordData dxfCodes, dxfData

    Dim Name As String
    Dim i As Integer
    For i = LBound(dxfCodes) To UBound(dxfCodes)
    If dxfCodes(i) = 1 Then
    Name = dxfData(i)
    Exit For
    End If
    Next i

    GetTabLState = Name

    Set XRec = Nothing
    Set Layout = Nothing
    End Function


    Public Sub SetTabLState()
    Dim Name As String
    Name = InputBox("Name", "Specify LayerState for Layout")

    Dim XRec As AcadXRecord
    Set XRec =
    ThisDrawing.ActiveLayout.GetExtensionDictionary.AddXRecord("TabHasLState")

    Dim dxfCodes(0) As Integer
    Dim dxfData(0) As Variant
    dxfCodes(0) = 1: dxfData(0) = Name

    XRec.SetXRecordData dxfCodes, dxfData

    Set XRec = Nothing
    End Sub
     
    R. Robert Bell, Feb 26, 2004
    #12
  13. John Uhden

    John Uhden Guest

    Yep. But I still have to have a lasting relationship between the Handle and the
    LayoutName so that the user can restore a LayerState in ModelSpace that he can
    recognize by the LayoutName. Programmatically I'll have no idea if the user has
    just renamed a layout without having switched layouts, unless of course I run a
    command-ended reactor as well as my LayoutSwitching reactor, which maybe I'll
    have to do. :/
     
    John Uhden, Feb 26, 2004
    #13
  14. John Uhden

    John Uhden Guest

    I get it. But what if the LayerState is renamed or deleted? Plus aren't you
    causing an additional regen by waiting until after the layout is switched?
     
    John Uhden, Feb 26, 2004
    #14
  15. John Uhden

    Doug Broad Guest

    When the user types the name or picks it from a list, look
    up the layout and then find its handle. Of course the extension
    dictionary sounds like a natural solution.

    For my layer manager, I used individual viewports rather than
    layouts as the source of layer settings and stored the layer states
    in external files. That way I could restore them if the drawings
    were xrefed into other drawings. For me, I would rather store
    the layer state name as a functional name (Plan, RCP, P1,...)
    Since I sometimes have more than one layer state per layout,
    that seemed to make sense.

    Hope that's not irrelevant. ;-)

    Regards,
    Doug
     
    Doug Broad, Feb 26, 2004
    #15
  16. This was just a bare-bones sample of how it could be done. After all, I
    didn't want to write the whole tamale for the original poster in that
    thread.

    That being said, James approach sounds really interesting!

    --
    R. Robert Bell, MCSE
    www.AcadX.com


    I get it. But what if the LayerState is renamed or deleted? Plus aren't
    you
    causing an additional regen by waiting until after the layout is switched?
     
    R. Robert Bell, Feb 26, 2004
    #16
  17. John Uhden

    James Buzbee Guest

    John, here's what I do . . . maybe you can use this logic for your
    application (logic - I flatter myself ;-) )

    I have Layer States defined in a "remote" drawing for Floor Plan,
    Dimensioned Floor Plan, Reflected Ceiling Plan, etc. as many as I want. I
    then use ObjectDBX to open and change the layerstate in the remote drawing
    to say "Floor Plan". Then I "read" the state of the layers and make a list.
    Now I compare the list from the remote drawing to the active documents
    layers changing them as needed.

    This accomplishes several things. 1. I have a centrally located place were
    all the "Office Standard" layerstates reside and can be easily modified on
    the fly. 2. In this remote drawing I have over 700 layers. If I were to
    import a layer state it would import all those layers. 3. By "reading" the
    remote drawing and making a list to compare I'm free to manipulate the
    layers in the active drawing however I need. Example: I have an xref that
    has Layout Geometry, Utilities, Landscape, and Survey information. Instead
    of using layouts and vplayer I xref in the drawing multiple times changing
    it's name (and moving it over): X_Util, X_Layout, etc. Now I have Multiple
    blocks with unique layers that can be manipulated separately.

    A fourth benefit to my method is that I've created a Layer Modifier Object
    (there I go flattering myself again). It changes the annotation layer for
    each Layer State related to the reactors I have set up. So say text for
    Geometry Layout is on A-Anno-Text-GL whereas Utilities are on
    A-Anno-Text-UT. So in my layer states in my remote drawing I freeze
    annotation layers I don't want to show up. I'm also hooked into ADT's
    LayerKeyStyles so that when a layerstate changes the layerkey changes as
    well.

    If you would like to see what I've done and play around with it let me know
    .. . . we can barter for information! ;-)

    jb
     
    James Buzbee, Feb 26, 2004
    #17
  18. John Uhden

    John Uhden Guest

    Sorry for the delay. Somehow it's always real work interrupting my fun. :/
    James, you should flatter yourself. That's quite an ambitious scheme you've got
    going there, but I kinda think it's more than I need.

    To all who have graciously contributed, thanks.
    For the record, the need for this solution is due to the mentality of the people
    with whom I work a lot these days. They are accustomed to working only in
    ModelSpace because they are are barely aware of locking viewports. So to see
    the objects particular to a certain layout, they need to work with named
    LayerStates that they can recognize by name and update as required as Land
    Desktop continues to create new layers associated with such things as pipe runs,
    alignments, and DTM surface objects. While the use of VPLAYER is an alternative
    option, I have to agree that the lack of a dialog interface makes it cumbersome
    to use, plus it's really annoying when the current layer is frozen in the
    current viewport. :(

    I think I've derived that the solution is...
    1. Provide a mechanism to let the user create LayerStates and select which one
    they want to associate with a Layout, i.e. one LayerState may serve multiple
    Layouts that are intended to display the same information, the obvious
    difference between such similarly related Layouts being that they each display a
    different region (view) of a site that requires more than one layout because of
    size and scale.
    2. Tie the selected LayerState to the Layout by virtue of the LayerState's
    handle being stored in a dictionary, thereby making it name-independent.
    3. Use my LayoutSwitching reactor to restore the LayerState for the activated
    Layout (if both the association and the LayerState exist). LayoutSwitching can
    reduce all the display changes to one regen upon completion of the layout
    switch.
    4. Do not use a persistent reactor as it needs to fire only when a layout is
    switched.
    5. Try not to invoke the creation of an association if it would conflict with a
    command such as plotting multiple layouts.
    6. If possible, provide a mechanism to optionally save back to the associated
    LayerState if layers were altered/created while working in any given layout.
    7. Live with the reality that a user could delete a LayerState.
    8. Teach them that VPLAYER is still required for viewport differences within
    the same layout.

    All constructive criticism is welcomed.
     
    John Uhden, Feb 28, 2004
    #18
  19. John Uhden

    James Buzbee Guest

    1. Provide a mechanism to let the user create LayerStates and select which one
    they want to associate with a Layout, i.e. one LayerState may serve multiple
    Layouts that are intended to display the same information, the obvious
    difference between such similarly related Layouts being that they each display a
    different region (view) of a site that requires more than one layout because of
    size and scale.
    Annotation seperated by layers based on plot scale controlled by a layer state - right.

    2. Tie the selected LayerState to the Layout by virtue of the LayerState's
    handle being stored in a dictionary, thereby making it name-independent.
    I've linked ADT display properties and layer states by simply using the same name: When "Floor Plan" display is set restore "Floor Plan" layer state. This would have obvious limitations.

    If you choose to define your layer states remotely as I've outlined, you don't have to worry about them being deleted in the active document, just keep track via dictionary or xdata which layer state is associated with which layout.

    3. Use my LayoutSwitching reactor to restore the LayerState for the activated
    Layout (if both the association and the LayerState exist). LayoutSwitching can
    reduce all the display changes to one regen upon completion of the layout
    switch.
    4. Do not use a persistent reactor as it needs to fire only when a layout is
    switched.
    5. Try not to invoke the creation of an association if it would conflict with a
    command such as plotting multiple layouts.

    6. If possible, provide a mechanism to optionally save back to the associated
    LayerState if layers were altered/created while working in any given layout.
    Not a problem with remotely defined layer states

    7. Live with the reality that a user could delete a LayerState.
    Ditto

    8. Teach them that VPLAYER is still required for viewport differences within
    the same layout.
    Teach them . . . right! :/


    jb
     
    James Buzbee, Mar 1, 2004
    #19
  20. John Uhden

    John Uhden Guest

    Thanks, James, for taking the time to read and respond.
    I guess I'm just a little leary of saving drawing data externally. I'm not
    going to be running a forced standard system. There are just too many variables
    (what with the drawings we receive from other clients and their requirements) to
    try to police.

    As it is with Land Desktop, you'd think that the LDT flavor of AutoCAD would
    include in the ETRANSMIT search all the .DFM and .CGX files particular to a
    drawing. But not so. The best I can do to prevent such losses is to store the
    data in the drawing itself. Yeah, there's a good chance that any user can trash
    the data, or that I hinder my plan from the ability to read/write from/to a
    notifying object, but I have to give the users some latitude. Training them is
    the primary key to quality control.

    As to #1, I meant that a site might often be too big to display in one layout,
    so we cut it up into multiple layouts, say 2 Grading, 2 Utility, 2 Landscaping,
    etc. with say "Grading1" looking at the western half of the site and "Grading2"
    looking at the eastern half. So one (1) "Grading" LayerState is then applicable
    to the two (2) "Grading#" layouts, and so on. Nope, I'm not trying to
    create/control differently sized copies of textual or symbolic entities in the
    same drawing. They do know to create separate drawings for sufficiently
    different purposes and to xref as much of the base drawings as possible. I
    suppose that consistency of textual data could be automated via OLE objects or
    RTEXT, but once again I'm not sure I have confidence in storing too much data
    externally (maybe *I* neeed some training!) Anyway, I say that because user's
    tend to leave full paths attached, or there is no option to simplify the path,
    either of which can leave a drawing in the "ConstrDocs" folder referring to info
    in the "Site Plan" folder, both of which are still being revised as the client
    is pursuing alternatives and approvals after starting construction (these are
    real situations).

    As to plot scale, yes, my current LayoutSwitching reactor was developed to
    adjust LTSCALE to the ratio of the layout's CustomScale to the LDT drawing
    scale, which works even when plotting multiple layouts. So the LayerStates
    automation becomes just an add-on to the mechanism (if it works, and I actually
    haven't yet tried the theory).



    1. Provide a mechanism to let the user create LayerStates and select which one
    they want to associate with a Layout, i.e. one LayerState may serve multiple
    Layouts that are intended to display the same information, the obvious
    difference between such similarly related Layouts being that they each display a
    different region (view) of a site that requires more than one layout because of
    size and scale.
    << Annotation seperated by layers based on plot scale controlled by a layer
    state - right. >>

    2. Tie the selected LayerState to the Layout by virtue of the LayerState's
    handle being stored in a dictionary, thereby making it name-independent.
    << I've linked ADT display properties and layer states by simply using the same
    name: When "Floor Plan" display is set restore "Floor Plan" layer state. This
    would have obvious limitations. >>

    << If you choose to define your layer states remotely as I've outlined, you
    don't have to worry about them being deleted in the active document, just keep
    track via dictionary or xdata which layer state is associated with which layout.
    3. Use my LayoutSwitching reactor to restore the LayerState for the activated
    Layout (if both the association and the LayerState exist). LayoutSwitching can
    reduce all the display changes to one regen upon completion of the layout
    switch.
    4. Do not use a persistent reactor as it needs to fire only when a layout is
    switched.
    5. Try not to invoke the creation of an association if it would conflict with a
    command such as plotting multiple layouts.

    6. If possible, provide a mechanism to optionally save back to the associated
    LayerState if layers were altered/created while working in any given layout.
    Not a problem with remotely defined layer states

    7. Live with the reality that a user could delete a LayerState.
    << Ditto >>

    8. Teach them that VPLAYER is still required for viewport differences within
    the same layout.
    << Teach them . . . right! :/ >>


    << jb>>
     
    John Uhden, Mar 2, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.