NewInspectorPanelView.st
author Patrik Svestka <patrik.svestka@gmail.com>
Wed, 14 Nov 2018 12:07:51 +0100
branchjv
changeset 3630 5e718e0a754e
parent 2621 285fa261cbcb
permissions -rw-r--r--
Issue #239: Fix all Smalltak/X source files to be in unicode (UTF8 without BOM) and prefixed by "{ Encoding: utf8 }" when any unicode character is present

- All source *.st files are now Unicode UTF8 without BOM
Files are in two groups (fileOut works this way in Smalltalk/X):
- containing a unicode character have "{ Encoding: utf8 }" at the header
- ASCII only are without the header
     1 "
     2  COPYRIGHT (c) 1997 by eXept Software AG
     3 	      All Rights Reserved
     4 
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    11 "
    12 "{ Package: 'stx:libtool2' }"
    13 
    14 "{ NameSpace: Tools }"
    15 
    16 SimpleView subclass:#NewInspectorPanelView
    17 	instanceVariableNames:'frames labelViews listViews scrollBar maxDepth leftHistory
    18 		rightHistory hzpView actionBlock valueChangedAction'
    19 	classVariableNames:''
    20 	poolDictionaries:''
    21 	category:'Interface-NewInspector'
    22 !
    23 
    24 !NewInspectorPanelView class methodsFor:'documentation'!
    25 
    26 copyright
    27 "
    28  COPYRIGHT (c) 1997 by eXept Software AG
    29 	      All Rights Reserved
    30 
    31  This software is furnished under a license and may be used
    32  only in accordance with the terms of that license and with the
    33  inclusion of the above copyright notice.   This software may not
    34  be provided or otherwise made available to, or used by, any
    35  other person.  No title to or ownership of the software is
    36  hereby transferred.
    37 "
    38 
    39 
    40 !
    41 
    42 examples
    43 "
    44     example 1
    45     =========
    46 
    47 									[exBegin]
    48     |top slv|
    49 
    50     top := StandardSystemView new extent:600@400.
    51     slv := Tools::NewInspectorPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
    52     slv inspect:top.
    53     slv action:[:el|Transcript showCR:el].
    54     top open.
    55 									[exEnd]
    56 
    57 
    58     example 2
    59     =========
    60 									[exBegin]
    61     |top slv edt a vvp|
    62 
    63     a := Array new:5.
    64     a at:4 put:(Array new:6).
    65 
    66     top := StandardSystemView new extent:600@400.
    67     vvp := VariableVerticalPanel origin:0.0@0.0  corner:1.0@1.0 in:top.
    68 
    69     slv := Tools::NewInspectorPanelView origin:0.0@0.0 corner:1.0@0.5 in:vvp.
    70     edt := Workspace origin:0.0 @ 0.5 corner:1.0 @ 1.0 in:vvp.
    71     edt acceptAction:[:theText|slv accept:theText notifying:edt].
    72     edt   doItAction:[:theCode|slv doIt:theCode   notifying:edt].
    73 
    74     slv action:[:el| Transcript showCR:(el printString)].
    75     slv inspect:a.
    76 
    77     top open.
    78 									[exEnd]
    79 "
    80 ! !
    81 
    82 !NewInspectorPanelView class methodsFor:'constants'!
    83 
    84 minDepth
    85     "returns the minimum of views assigned to a panel
    86     "
    87     ^ 4
    88 ! !
    89 
    90 !NewInspectorPanelView methodsFor:'accessing'!
    91 
    92 depth
    93     "returns number of listViews
    94     "
    95   ^ listViews size
    96 !
    97 
    98 depth:aDepth
    99     "change the number of existing listViews
   100     "
   101     |sz min|
   102 
   103     min := self class minDepth.
   104 
   105     aDepth > min ifTrue:[
   106 	sz := aDepth min:maxDepth.
   107 
   108 	sz < listViews size ifTrue:[
   109 	    sz := listViews size
   110 	]
   111     ] ifFalse:[
   112 	sz := min
   113     ].
   114 
   115     listViews size == sz ifTrue:[
   116 	sz == aDepth ifFalse:[self moveContentsLeft:1].
   117     ] ifFalse:[
   118 	[self createViewWithoutRedraw. listViews size ~~ sz] whileTrue.
   119 	self computeExtentOfFrames.
   120 
   121 	(self topView shown) ifTrue:[
   122 	    hzpView sizeChanged:nil.
   123 	    hzpView realizeAllSubViews.
   124 	]
   125     ]
   126 !
   127 
   128 maxDepth
   129     ^ maxDepth
   130 !
   131 
   132 maxDepth:aNumber
   133     "change max depth for instance
   134     "
   135     aNumber > listViews size ifTrue:[
   136 	aNumber >= (self class minDepth) ifTrue:[
   137 	    maxDepth := aNumber.
   138 
   139 	    maxDepth < listViews size ifTrue:[
   140 		self depth:maxDepth
   141 	    ]
   142 	]
   143     ]
   144 ! !
   145 
   146 !NewInspectorPanelView methodsFor:'accessing actions'!
   147 
   148 action:aOneArgBlock
   149     "set the single click action block.
   150      If non-nil, that one is evaluated on single click, passing the
   151      selected instance as argument
   152     "
   153     actionBlock := aOneArgBlock
   154 
   155 
   156 !
   157 
   158 valueChangedAction:aOneArgBlock
   159     "evaluated if an instnace changed its value; passing
   160      the instance as argument
   161     "
   162     valueChangedAction := aOneArgBlock
   163 ! !
   164 
   165 !NewInspectorPanelView methodsFor:'accessing selections'!
   166 
   167 inspectedObject
   168     "returns the current inspected object
   169     "
   170     ^ self findLastValidListWithSelection inspectedObject
   171 !
   172 
   173 selectedInstanceVar
   174     "returns the current selected instance var
   175     "
   176     ^ self findLastValidListWithSelection selectedInstanceVar
   177 ! !
   178 
   179 !NewInspectorPanelView methodsFor:'actions'!
   180 
   181 accept:aText notifying:aView
   182     "evaluating aText on the last selected instance var. on success the views
   183      are updated.
   184     "
   185     self doItOrAccept:[:aList|aList accept:aText notifying:aView]
   186 !
   187 
   188 doIt:aCode notifying:aView
   189     "evaluating aCode on the selected instance var; on success the views
   190      are updated.
   191     "
   192     ^ self doItOrAccept:[:aList|aList doIt:aCode notifying:aView]
   193 !
   194 
   195 inspect:anObject
   196     "change the inspected object and all views
   197     "
   198     |view|
   199 
   200     view := listViews first.
   201     leftHistory  removeAll.
   202     rightHistory removeAll.
   203 
   204     view inspect:anObject.
   205     listViews from:2 do:[:v|v inspect:nil].
   206     self update.
   207 ! !
   208 
   209 !NewInspectorPanelView methodsFor:'event handling'!
   210 
   211 handlesKeyPress:key inView:someView
   212     "all keys are handled by this instance itself
   213     "
   214     ^ true
   215 
   216 !
   217 
   218 keyPress:key x:x y:y view:someView
   219     "handle some special keys
   220     "
   221     key == #CursorLeft  ifTrue:[^ self moveContentsRight:1].
   222     key == #CursorRight ifTrue:[^ self moveContentsLeft:1 ].
   223 
   224     someView keyPress:key x:x y:y.
   225 
   226 !
   227 
   228 singleClickAt:anIndex
   229     "the view at an index changed its selection caused by a single click
   230     "
   231     |view start sivar|
   232 
   233     rightHistory removeAll.
   234 
   235     view  := listViews at:anIndex.
   236     start := anIndex + 1.
   237     sivar := view selectedInstanceVar.
   238 
   239     start > listViews size ifTrue:[
   240 	start >= maxDepth ifTrue:[
   241 	    self moveContentsLeft:1.
   242 	  ^ actionBlock value:sivar.
   243 	].
   244     ].
   245 
   246     (view selectedInstanceType) == #directory ifTrue:[
   247 	(listViews at:start) setSelection:nil.
   248 	(listViews at:start) inspect:sivar.
   249 
   250 	start := start + 1.
   251     ].
   252 
   253     listViews from:start do:[:v|v inspect:nil].
   254     self update.
   255     actionBlock value:sivar.
   256 ! !
   257 
   258 !NewInspectorPanelView methodsFor:'initializing'!
   259 
   260 initialize
   261     "initialize instance
   262     "
   263     super initialize.
   264 
   265     frames       := OrderedCollection new.
   266     listViews    := OrderedCollection new.
   267     labelViews   := OrderedCollection new.
   268     leftHistory  := OrderedCollection new.
   269     rightHistory := OrderedCollection new.
   270     maxDepth     := self class minDepth.
   271 
   272     actionBlock := [:el| ].
   273 
   274     hzpView    := VariableHorizontalPanel origin:0.0@0.0 corner:1.0@1.0 in:self.
   275     scrollBar  := HorizontalScrollBar origin:0.0@1.0 corner:1.0@1.0 in:self.
   276     "/ scrollBar asynchronousOperation.
   277 
   278     hzpView bottomInset:(scrollBar preferredExtent y).
   279 
   280     scrollBar topInset:(scrollBar preferredExtent y) negated.
   281     scrollBar thumbHeight:100.
   282     scrollBar scrollAction:[:percent | self scrollTo:percent].
   283     scrollBar scrollRightAction:[self moveContentsLeft:1].
   284     scrollBar scrollLeftAction:[self moveContentsRight:1].
   285 
   286     self depth:maxDepth.
   287 ! !
   288 
   289 !NewInspectorPanelView methodsFor:'menu - labels & actions'!
   290 
   291 browse:anIndex
   292     self classAtLabel:anIndex do:[:cls| cls browserClass openInClass:cls selector:nil ]
   293 
   294 !
   295 
   296 browseClassHierarchy:anIndex
   297     self classAtLabel:anIndex do:[:cls| cls browserClass browseClassHierarchy:cls ]
   298 
   299 !
   300 
   301 browseFullClassProtocol:anIndex
   302     self classAtLabel:anIndex do:[:cls| cls browserClass browseFullClassProtocol:cls ]
   303 
   304 !
   305 
   306 classAtLabel:anIndex do:anAction
   307     "evaluate action on class assigned to label
   308     "
   309     |cls|
   310 
   311     anIndex <= labelViews size ifTrue:[
   312 	(cls := Smalltalk classNamed:((labelViews at:anIndex) label)) notNil ifTrue:[
   313 	    anAction value:cls
   314 	]
   315     ]
   316 
   317 !
   318 
   319 labelMenu
   320     "popup menu required by any label. Delegate the request to the corresponding label
   321     "
   322     |sqNr view|
   323 
   324     view := (WindowGroup lastEventQuerySignal query) view.
   325     sqNr := labelViews findFirst:[:v| v == view].
   326 
   327     sqNr ~~ 0 ifTrue:[
   328 	view := labelViews at:sqNr.
   329 
   330 	view label notEmpty ifTrue:[
   331 	    ^ self labelMenu:sqNr
   332 	]
   333     ].
   334     ^ nil
   335 !
   336 
   337 labelMenu:anIndex
   338     "popup menu required for a label identified by its sequence number
   339     "
   340     |menu|
   341 
   342     menu := PopUpMenu labels:#(
   343 			      'browse'
   344 			      'browse class hierarchy'
   345 			      'browse full class protocol'
   346 			      )
   347 		   selectors:#(
   348 			      browse:
   349 			      browseClassHierarchy:
   350 			      browseFullClassProtocol:
   351 			      )
   352 		    receiver:self.
   353 
   354    menu args:(Array new:(menu labels size) withAll:anIndex).
   355  ^ menu
   356 
   357 ! !
   358 
   359 !NewInspectorPanelView methodsFor:'menu - views & actions'!
   360 
   361 doTrace:anInstance
   362     "place a trace on messages sent to the instance
   363     "
   364     |selectors|
   365 
   366     selectors := self messageMenu:anInstance.
   367 
   368     selectors notNil ifTrue:[
   369 	self topView withWaitCursorDo:[MessageTracer trace:anInstance selectors:selectors]
   370     ].
   371 
   372 !
   373 
   374 doTraceAll:anInstance
   375     "place a trace on all messages sent to the instance
   376     "
   377     self topView withWaitCursorDo:[MessageTracer traceAll:anInstance]
   378 !
   379 
   380 doTrap:anInstance
   381     "place a trap on a message sent to the instance
   382     "
   383     |selectors|
   384 
   385     selectors := self messageMenu:anInstance.
   386 
   387     selectors notNil ifTrue:[
   388 	self topView withWaitCursorDo:[MessageTracer trap:anInstance selectors:selectors]
   389     ]
   390 !
   391 
   392 doTrapAll:anInstance
   393     "place a trap on all messages sent to the instance
   394     "
   395     self topView withWaitCursorDo:[MessageTracer trapAll:anInstance]
   396 
   397 !
   398 
   399 doUntrace:anInstance
   400     "remove all traps and traces to the instance
   401     "
   402     self topView withWaitCursorDo:[MessageTracer untrace:anInstance].
   403 
   404 !
   405 
   406 messageMenu:anInstance
   407     "open menu to select messages; on accepted a list of messages is returned
   408     "
   409     |sll acl lst inset top hzp slv acv dblClcAct btp b1 b2 accepted viewSpacing|
   410 
   411     top := StandardSystemView new.
   412     top extent:500 @ 400.
   413     top label:(anInstance printString).
   414 
   415     (Label origin:(0.0 @  0.0) corner:(0.5 @ 20) in:top) label:'messages'.
   416     (Label origin:(0.5 @  0.0) corner:(1.0 @ 20) in:top) label:'selected'.
   417     hzp := VariableHorizontalPanel origin:(0.0 @ 20) corner:(1.0 @ 1.0) in:top.
   418     btp := HorizontalPanelView origin:(0.0 @1.0) corner:(1.0 @ 1.0) in:top.
   419 
   420     b1 := Button abortButtonIn:btp.
   421     b2 := Button okButtonIn:btp.
   422     accepted := false.
   423 
   424     b1 action:[accepted := false. top destroy].
   425     b2 action:[accepted := true.  top destroy].
   426 
   427     btp horizontalLayout:#fitSpace.
   428     viewSpacing := top class viewSpacing.
   429     inset       := (b2 preferredExtent y) + viewSpacing.
   430     viewSpacing := viewSpacing // 2.
   431 
   432     hzp bottomInset:inset.
   433     btp topInset:((inset - viewSpacing) negated).
   434     btp bottomInset:viewSpacing.
   435 
   436     slv := ScrollableView for:SelectionInListView
   437 		miniScrollerV:true
   438 		       origin:(0.0 @ 0.0)
   439 		       corner:(0.5 @ 1.0)
   440 			   in:hzp.
   441 
   442     acv := ScrollableView for:SelectionInListView
   443 		miniScrollerV:true
   444 		       origin:(0.5 @ 0.0)
   445 		       corner:(1.0 @ 1.0)
   446 			   in:hzp.
   447 
   448     slv := slv scrolledView.
   449     acv := acv scrolledView.
   450 
   451     sll := (MessageTracer realClassOf:anInstance) selectors.
   452     acl := OrderedCollection new.
   453 
   454     (MessageTracer wrappedSelectorsOf:anInstance) do:[:el|
   455 	el notNil ifTrue:[
   456 	    acl add:el.
   457 	    sll remove:el ifAbsent:nil
   458 	]
   459     ].
   460 
   461     slv list:(sll copy).
   462     acv list:(acl copy).
   463 
   464     dblClcAct := [:from :to|
   465 	to add:(from selectionValue).
   466 	from removeIndex:(from selection).
   467 	from redraw.
   468     ].
   469 
   470     slv doubleClickAction:[:index| dblClcAct value:slv value:acv].
   471     acv doubleClickAction:[:index| dblClcAct value:acv value:slv].
   472 
   473     top openModal.
   474 
   475     accepted ifFalse:[
   476 	^ nil
   477     ].
   478     lst := acv list.
   479 
   480 "undo existing traps            HACK: removes traps and traces"
   481 
   482     acl notEmpty ifTrue:[
   483 	MessageTracer untrace:anInstance
   484     ].
   485 
   486     lst notEmpty ifTrue:[^ lst]
   487 		ifFalse:[^ nil]
   488 !
   489 
   490 viewMenu
   491     "popup menu required by any view. Delegate the request to the corresponding view
   492     "
   493     |sqNr view|
   494 
   495     view := (WindowGroup lastEventQuerySignal query) view.
   496     sqNr := listViews findFirst:[:v| v == view].
   497 
   498     sqNr notNil ifTrue:[^ self viewMenu:sqNr]
   499 	       ifFalse:[^ nil]
   500 !
   501 
   502 viewMenu:anIndex
   503     "popup menu required for a view identified by its sequence number
   504     "
   505     |view menu inst args lbls|
   506 
   507     view := listViews at:anIndex.
   508     view hasSelection ifFalse:[^ nil].
   509     inst := view selectedInstanceVar.
   510 
   511     menu := PopUpMenu labels:#( 'update' )
   512 		   selectors:#( #update  )
   513 		    receiver:self.
   514 
   515     menu actionAt:#update put:[
   516 	view update.
   517 
   518 	listViews from:(anIndex + 1) do:[:v|
   519 	    (view selectedInstanceType) ~~ #directory ifTrue:[
   520 		v inspect:nil
   521 	    ] ifFalse:[
   522 		v inspect:(view selectedInstanceVar).
   523 		view := v.
   524 	    ]
   525 	].
   526 	self update
   527     ].
   528 
   529     (NewInspectorList isTraceable:inst) ifFalse:[
   530 	^ menu
   531     ].
   532 
   533     menu  addLabels:#(
   534 		      '-'
   535 		      'trace'
   536 		      'trap'
   537 		      'untrace / untrap'
   538 		     )
   539 	  selectors:#(
   540 		      nil
   541 		      trace
   542 		      trap
   543 		      untrace
   544 		     ).
   545 
   546     menu actionAt:#untrace put:[self doUntrace:inst].
   547 
   548     args := Array new:2 withAll:inst.
   549     lbls := Array with:'message'
   550 		  with:((Text string:' all ' emphasis:#underline), ' messages').
   551 
   552     menu subMenuAt:#trace put:(
   553 	PopUpMenu labels:lbls selectors:#(doTrace: doTraceAll:) args:args
   554     ).
   555 
   556     menu subMenuAt:#trap put:(
   557 	PopUpMenu labels:lbls selectors:#(doTrap: doTrapAll:) args:args
   558     ).
   559 
   560   ^ menu
   561 
   562 
   563 ! !
   564 
   565 !NewInspectorPanelView methodsFor:'private'!
   566 
   567 doItOrAccept:aBlock
   568     "handle a doIt or accept action; on success all the folloed views are
   569      updated
   570     "
   571     |index list result instVar|
   572 
   573     list    := self findLastValidListWithSelection.
   574     result  := aBlock value:list.
   575     instVar := list selectedInstanceVar.
   576     index   := listViews findLast:[:v|v == list].
   577 
   578     (index ~~ 0 and:[index ~~ listViews size]) ifTrue:[
   579 	index := index + 1.
   580 	(list selectedInstanceType) == #directory ifTrue:[
   581 	    (listViews at:index) inspect:instVar
   582 	] ifFalse:[
   583 	    (listViews at:index) inspect:nil
   584 	].
   585 	self update
   586     ].
   587     valueChangedAction notNil ifTrue:[
   588 	valueChangedAction value:instVar
   589     ].
   590     ^ result
   591 !
   592 
   593 findLastValidListWithSelection
   594     "returns last valid list with a selection; if no selection exists in any
   595      view, the list assigned to the inspected object is returned
   596     "
   597     |index|
   598 
   599     rightHistory notEmpty ifTrue:[
   600 	^ rightHistory first
   601     ].
   602     index := listViews findLast:[:v| v hasSelection ].
   603 
   604     index ~~ 0 ifTrue:[
   605 	^ listViews at:index
   606     ].
   607 
   608     leftHistory notEmpty ifTrue:[^ leftHistory last]
   609 			ifFalse:[^ listViews at:1]
   610 !
   611 
   612 update
   613     "update labels and scrollbar
   614     "
   615     |pview cview stop index ispObj label|
   616 
   617 "UPDATE LABELS
   618 "
   619     index := 1.
   620     stop  := listViews size.
   621 
   622     [   cview  := listViews at:index.
   623 	ispObj := cview inspectedObject.
   624 	label  := labelViews at:index.
   625 	index  := index + 1.
   626 
   627 	ispObj notNil ifTrue:[
   628 	    label label:(ispObj class name asString).
   629 	    pview := cview.
   630 	] ifFalse:[
   631 	    [index <= stop] whileTrue:[
   632 		(labelViews at:index) label:''.
   633 		index := index + 1
   634 	    ].
   635 
   636 	    (pview isNil or:[pview selectedInstanceType == #normal]) ifTrue:[
   637 		pview notNil ifTrue:[ispObj := pview selectedInstanceVar].
   638 		label label:ispObj class name asString
   639 	    ] ifFalse:[
   640 		label label:''
   641 	    ]
   642 	].
   643 	index > stop
   644 
   645     ] whileFalse.
   646 
   647 "UPDATE SCROLLBARS
   648 "
   649     index := listViews size + leftHistory size + rightHistory size.
   650 
   651     (listViews last) selectedInstanceType notNil ifTrue:[
   652 	index := index + 1
   653     ].
   654     scrollBar thumbHeight:(stop / index) * 100.
   655     scrollBar thumbOrigin:(100  / index * leftHistory size).
   656 
   657 ! !
   658 
   659 !NewInspectorPanelView methodsFor:'private frames'!
   660 
   661 computeExtentOfFrames
   662     "compute the extent of all frames (origin/corner)
   663     "
   664     |orig corn offset newX|
   665 
   666     orig := ( 0.0 @ 0.0 ).
   667     corn := ( 0.0 @ 1.0 ).
   668 
   669     offset := 1.0 / (frames size).
   670     newX   := 0.0.
   671 
   672     frames do:[:frame|
   673 	(newX := newX + offset) > 1.0 ifTrue:[ newX := 1.0 ].
   674 	corn  := newX @ corn y.
   675 	frame origin:orig corner:corn.
   676 	orig  := newX @ orig y.
   677     ].
   678 
   679 
   680 !
   681 
   682 createViewWithoutRedraw
   683     "add a new view at end of the panel
   684     "
   685     |view frame label index|
   686 
   687     frame := SimpleView in:hzpView.
   688 
   689     label := Label origin:0.0@0.0 corner:1.0@20 in:frame.
   690     label  leftInset:15.
   691     label rightInset:2.
   692 
   693     view  := ScrollableView for:NewInspectorListView miniScroller:true origin:0.0@20
   694 			 corner:1.0@1.0 in:frame.
   695 
   696     view := view scrolledView.
   697 
   698     frames add:frame.
   699     labelViews add:label.
   700     listViews  add:view.
   701 
   702     index := listViews size.
   703 
   704     index == 1 ifTrue:[
   705 	view includesSelf:true
   706     ].
   707 
   708     label adjust:#left.
   709     label label:''.
   710     label level:1.
   711     label menuHolder:self; menuMessage:#labelMenu; menuPerformer:self.
   712 
   713     view action:[:el|self singleClickAt:index].
   714 
   715     view delegate:self.
   716     view menuHolder:self; menuMessage:#viewMenu; menuPerformer:self.
   717 
   718 ! !
   719 
   720 !NewInspectorPanelView methodsFor:'scrolling-basic'!
   721 
   722 moveContentsLeft:nTimes
   723     "move the contents of all views one position left
   724     "
   725     |fView stop pView index|
   726 
   727     (nTimes < 1 or:[listViews last isEmpty]) ifTrue:[
   728 	^ self
   729     ].
   730 
   731     index := nTimes.
   732     stop  := (listViews size) - 1.
   733     fView := listViews first.
   734     pView := listViews at:stop.
   735 
   736 
   737     [   leftHistory add:(fView list).
   738 
   739 	1 to:stop do:[:i|
   740 	    (listViews at:i) list:(listViews at:(i+1))
   741 	].
   742 
   743 	rightHistory notEmpty ifTrue:[
   744 	    (listViews last) list:(rightHistory removeLast)
   745 	] ifFalse:[
   746 	    (listViews last) inspect:(pView selectedInstanceVar)
   747 	].
   748 	((index := index - 1) == 0 or:[listViews last isEmpty])
   749 
   750     ] whileFalse.
   751 
   752     self update.
   753 
   754 
   755 
   756 !
   757 
   758 moveContentsRight:nTimes
   759     "move the contents of all views one position right
   760     "
   761     |size index lView fView|
   762 
   763     size := leftHistory size.
   764 
   765     (nTimes > 0 and:[size ~~ 0]) ifTrue:[
   766 	nTimes > size ifFalse:[index := nTimes]
   767 		       ifTrue:[index := size].
   768 
   769 	size  := listViews size.
   770 	lView := listViews last.
   771 	fView := listViews first.
   772 
   773 	1 to:index do:[:i|
   774 	    lView hasSelection ifTrue:[
   775 		rightHistory add:(lView list)
   776 	    ].
   777 	    size to:2 by:-1 do:[:i|
   778 		(listViews at:i) list:(listViews at:(i-1))
   779 	    ].
   780 	    fView list:(leftHistory removeLast)
   781 	].
   782 	self update
   783     ]
   784 
   785 !
   786 
   787 scrollTo:nPercent
   788     "set views and contents dependant on scroll bar
   789     "
   790     |dY no noScr pR|
   791 
   792     noScr := listViews size + leftHistory size + rightHistory size.
   793 
   794     (listViews last) selectedInstanceType notNil ifTrue:[
   795 	noScr := noScr + 1
   796     ].
   797     dY := 100 / noScr.
   798     pR := nPercent roundTo:dY.
   799 
   800     no := ((dY * leftHistory size) - pR) / dY.
   801 
   802     no == 0 ifTrue:[
   803 	(nPercent - pR) > 0 ifTrue:[no := -1]
   804 			   ifFalse:[no :=  1]
   805     ].
   806     no < 0 ifTrue:[self moveContentsLeft:(no negated)]
   807 	  ifFalse:[self moveContentsRight:no]
   808 ! !
   809 
   810 !NewInspectorPanelView class methodsFor:'documentation'!
   811 
   812 version
   813     ^ '$Header$'
   814 ! !