InspectorView.st
author claus
Fri, 16 Jul 1993 11:44:07 +0200
changeset 0 571fd5eee315
child 3 9ff3765f06d0
permissions -rw-r--r--
Initial revision

"
 COPYRIGHT (c) 1989-93 by Claus Gittinger
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

View subclass:#InspectorView
       instanceVariableNames:'listView workspace 
                              inspectedObject selectedLine
                              inspectedValues nShown'
       classVariableNames:''
       poolDictionaries:''
       category:'Interface-Inspector'
!

InspectorView comment:'

COPYRIGHT (c) 1989-93 by Claus Gittinger
              All Rights Reserved

This class implements an graphical inspector.
Inspecting can be done on an object -
(where its instvarnames/values are inspected)
or a list of objects (where a namearray/valuesarray is inspected).
The later is used by the debugger to inspect method variables/args.

The system calls the inspector through the global variable "Inspector"
which is bound to this class (but could be redefined).

%W% %E%
written winter 89 by claus
'!

!InspectorView class methodsFor:'instance creation'!

for:anObject
    "create and launch a new inspector for anObject"

    ^ self openOn:anObject
!

inspect:anObject
    self openOn:anObject
!

openOn:anObject
    "create and launch a new inspector for anObject"

    |topView inspectorView|

    topView := StandardSystemView
                    label:(anObject class name)
                    icon:(Form fromFile:'Inspector.xbm' resolution:100)
                    minExtent:(100 @ 100).

    topView extent:(Display width // 3) @ (Display height // 3).

    inspectorView := self origin:(0.0 @ 0.0)
                          corner:(1.0 @ 1.0)
                             in:topView.

    inspectorView inspect:anObject.
    topView realize

    "InspectorView openOn:(5 @ 7)"
    "DictionaryInspectorView openOn:(IdentityDictionary new)"
! !

!InspectorView methodsFor:'initialization'!

initialize
    |v panel|

    super initialize.
    resources := ResourcePack fromFile:'Inspector.rs'.

    panel := VariableHorizontalPanel origin:(0.0 @ 0.0)
                                     corner:(1.0 @ 1.0)
                                         in:self.

    v := ScrollableView for:SelectionInListView in:panel.
    v origin:(0.0 @ 0.0) corner:(0.3 @ 1.0).
    listView := v scrolledView.
    listView action:[:lineNr | self showSelection:lineNr].

    workspace := CodeView origin:(0.3 @ 0.0) corner:(1.0 @ 1.0) in:panel.
    nShown := 100
!

initEvents
    ^ self enableKeyEvents
!

create
    super create.
    self initializeListViewMiddleButtonMenu
!

initializeListViewMiddleButtonMenu
    |labels|

    labels := resources array:#('inspect').
    listView middleButtonMenu:(PopUpMenu
                                   labels:labels
                                selectors:#doInspect
                                 receiver:self
                                      for:listView).
    workspace acceptAction:[:theText | self doAccept:theText]
! !

!InspectorView methodsFor:'accessing'!

noChoice
    "clear name and value views"

    inspectedObject notNil ifTrue:[
        inspectedObject removeDependent:self
    ].
    inspectedObject := nil.
    inspectedValues := nil.
    workspace contents:nil.
    listView contents:nil
!

listOfNames
    "return a list of names to show in the selectionList"

    |aList nShown cut|

    aList := Text new.
    aList add:'self'.
    (inspectedObject class allInstVarNames) do:[:instVarName |
        aList add:instVarName
    ].
    (inspectedObject class isVariable) ifTrue:[
        nShown := inspectedObject basicSize.
        (nShown > nShown) ifTrue:[
            nShown := nShown.
            cut := true
        ] ifFalse:[
            cut := false
        ].
        1 to:nShown do:[:index |
            aList add:(index printString)
        ].
        cut ifTrue:[
            aList add:' ... '
        ]
    ].
    ^ aList
!

inspect:anObject
    "define the object to be inspected"

    |aList nShown cut sameObject|

    sameObject := anObject == inspectedObject.
    sameObject ifFalse:[
        inspectedObject notNil ifTrue:[
            inspectedObject removeDependent:self
        ]
    ].
    inspectedObject := anObject.

    aList := self listOfNames.
    sameObject ifTrue:[
        listView setContents:aList
    ] ifFalse:[
        listView contents:aList
    ].

    workspace contents:nil.
    workspace doItAction:[:theCode |
        Compiler evaluate:theCode
                 receiver:inspectedObject 
                notifying:workspace
    ].

    sameObject ifFalse:[
        inspectedObject notNil ifTrue:[
            inspectedObject addDependent:self
        ]
    ].
    inspectedValues := nil
!

inspect:anObject values:valueArray names:nameArray
    listView contents:nameArray.
    workspace contents:nil.
    inspectedObject notNil ifTrue:[
        inspectedObject removeDependent:self
    ].
    inspectedObject := anObject.
    inspectedObject notNil ifTrue:[
        inspectedObject addDependent:self
    ].
    inspectedValues := valueArray
!

inspectValues:valueArray names:nameArray
    listView contents:nameArray.
    workspace contents:nil.
    inspectedObject notNil ifTrue:[
        inspectedObject removeDependent:self
    ].
    inspectedObject := nil.
    inspectedValues := valueArray
! !

!InspectorView methodsFor:'user interaction'!

keyPress:aKey x:x y:y
    "all my input is passed on to the workspace-field"

    workspace keyPress:aKey x:0 y:0
!

update:something
    "handle updates from other inspectors"

    |oldSelection|

    something == inspectedObject ifTrue:[
        oldSelection := listView selection.
        self inspect:inspectedObject.
        listView selection notNil ifTrue:[
            self showSelection:(listView selection)
        ]
    ]
!

destroy
    inspectedObject notNil ifTrue:[
        inspectedObject removeDependent:self.
        inspectedObject := nil
    ].
    inspectedValues := nil.
    super destroy
!

showSelection:lineNr
    "user clicked on an instvar - show value in workspace"

    |val string index|

    workspace contents:nil.
    inspectedValues isNil ifTrue:[
        lineNr == 1 ifTrue:[
            val := inspectedObject
        ] ifFalse:[
            index := lineNr - 1.
            (inspectedObject class isVariable) ifFalse:[
                val := inspectedObject instVarAt:index
            ] ifTrue:[
                index <= (inspectedObject class instSize) ifTrue:[
                    val := inspectedObject instVarAt:index
                ] ifFalse:[
                    index := index - inspectedObject class instSize.
                    val := inspectedObject basicAt:index
                ]
            ]
        ]
    ] ifFalse:[
        val := inspectedValues at:lineNr
    ].
    string := val displayString.
    workspace show:string.
    selectedLine := lineNr
!

doAccept:theText
    |value index|

    value := Compiler evaluate:theText
                      receiver:inspectedObject 
                     notifying:workspace.
    inspectedValues isNil ifTrue:[
        selectedLine notNil ifTrue:[
            selectedLine == 1 ifFalse:[
                index := selectedLine - 1.
                (inspectedObject class isVariable) ifFalse:[
                    inspectedObject instVarAt:index put:value
                ] ifTrue:[
                    index <= (inspectedObject class instSize) ifTrue:[
                        inspectedObject instVarAt:index put:value
                    ] ifFalse:[
                        index := index - inspectedObject class instSize.
                        inspectedObject basicAt:index put:value
                    ]
                ]
            ]
        ]
    ] ifFalse:[
        selectedLine notNil ifTrue:[
            inspectedValues at:selectedLine put:value
        ]
    ].
    inspectedObject changed
!

doInspect
    "user selected inspect-menu entry"
    |index objectToInspect|

    selectedLine notNil ifTrue:[
        inspectedValues isNil ifTrue:[
            (selectedLine == 1) ifTrue:[
                objectToInspect := inspectedObject
            ] ifFalse:[
                index := selectedLine - 1.
                (inspectedObject class isVariable) ifFalse:[
                    objectToInspect := inspectedObject instVarAt:index
                ] ifTrue:[
                    index <= (inspectedObject class instSize) ifTrue:[
                        objectToInspect := inspectedObject instVarAt:index
                    ] ifFalse:[
                        index := index - inspectedObject class instSize.
                        objectToInspect := inspectedObject basicAt:index
                    ]
                ]
            ]
        ] ifFalse:[
            objectToInspect := inspectedValues at:selectedLine
        ].
        objectToInspect inspect
    ]
! !