UISpecificationTool.st
author Claus Gittinger <cg@exept.de>
Wed, 26 Nov 2003 19:08:28 +0100
changeset 1769 8782d5b6dc24
parent 1677 e09bb60c396d
child 1781 d67090b1ad57
permissions -rw-r--r--
modified flag after edit operations

"
 COPYRIGHT (c) 1995 by eXept Software AG
              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.
"




"{ Package: 'stx:libtool2' }"

ApplicationModel subclass:#UISpecificationTool
	instanceVariableNames:'modifiedHolder aspects specification selection specChannel
		buildInView listOfSpecViews'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-UIPainter'
!

ViewScroller subclass:#BuildInView
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:UISpecificationTool
!

!UISpecificationTool class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 by eXept Software AG
              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.
"



!

documentation
"
    used by the UIPainter to manipulate the specifications of the selected component

    [author:]
        Claus Atzkern

    [see also:]
        UIPainter
        UILayoutTool
        UIHelpTool
"
! !

!UISpecificationTool class methodsFor:'help specs'!

helpSpec
    "This resource specification was automatically generated
     by the UIHelpTool of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIHelpTool may not be able to read the specification."

    "
     UIHelpTool openOnClass:UISpecificationTool    
    "

    <resource: #help>

    ^super helpSpec addPairsFrom:#(

#acceptCallBack
'0 or 1-arg message, sent when text is accepted (arg is text).'

#acceptChannel
'Aspect selector or binding for a triggerValue to force accept.'

#acceptIfUnchanged
'Accept even if text is unchanged.'

#acceptImmediate
'Enable sending of the entered string to the model with every key press.'

#acceptOnLeave
'Enable sending of the entered string to the model when field is left via a keyboard action.'

#acceptOnLostFocus
'Enable sending of the entered string to the model when the field looses its input focus.'

#acceptOnPointerLeaveFocus
'Enable sending of the entered string to the model when field is left via a mouse motion.'

#acceptOnReturn
'Enable sending of the entered string to the model when the RETURN key is pressed.'

#acceptOnTab
'Enable sending of the entered string to the model when the TAB key is pressed.'

#action
'Message sent to the application when the widget is activated.'

#actionArg
'Optional argument passed with the action message.'

#appletParamText
'Paste the complete appletTAGs HTML text here (i.e. all from <applet> up to and including the </applet>). Press parse to extract all parameters from it.'

#appletTextParse
'Parse the appletTAG and fill the parameters directory from it.'

#arbitraryView
'Message sent to ask the application for the view instance; or, if uppercase, the name of the view class.'

#archiveEntry
'The name of a zip-file archive, if the class(es) are to be loaded from a zip-archive.'

#arrowButtonDirection
'Defines the direction of the arrow.'

#autoHideScrollBars
'AutoHide mode (always / never / controlled by ViewStyle).'

#autoRepeat
'Enable auto-repeat of the action as long as the button is pressed (Must be Trigger-on-Down).'

#autoScrollHorizontal
'Enable horizontal auto-scrollability to show the selection.'

#backgroundChannel
'Aspect selector or binding for a background color holder.'

#backgroundColor
'Defines the background color of the widget.'

#barLevel
'Defines the 3D level of the separating bar between views.'

#barWidth
'Defines the width of the separating bar between views (in pixels).'

#beDefault
'Show a default (-return) bitmap after the label.'

#beDependentOfRows
'Make the widget dependent on each row (i.e. rows send change messages).'

#booleanHolder
'Aspect selector or binding for a boolean holder which enables the widget.'

#booleanModel
'Aspect selector or binding for a holder on the boolean state.'

#borderWidth
'Defines the width of the border (in pixels).'

#buttonModelArg
'Value stored into the model when the button is pressed.'

#canvas
'Aspect selector or binding for the widget placed into the notebook.'

#canvasArgument
'An optional argument passed with the message.'

#canvasInset
'Inset of canvas; a Point or Integer; leave blank for default.'

#canvasSelector
'Message sent after opening the canvas.'

#centerIcons
'Center icons horizontally.'

#chartHolder
'Value holder on a chart description.'

#chartLabel
'Label string shown with the chart.'

#clientHolder
'Aspect selector or binding for a holder on the client application to be opened.'

#clientKey
'Message sent to ask the master application for an application instance; (default: the master application itself).'

#codeBaseHolder
'The URL of the directory, where the classFile-file resides. If the classFile is located on the local machine, use\     file:/<fullPath>\ where fullPath is an absolute pathname. If its to be accessed via http, use\     http:/<host>/<relativePath>\ where relativePath is the path relative to the http''s top diretory on that host.'

#codeFileEntry
'The name of the java classFile which contains the applets code. For example: ''ArcTest.class'''

#columnAdaptor
'Name of a method in the application which returns a column adaptor.'

#columnButton
'Opens a Table Columns Builder.'

#columnHolder
'Aspect selector or binding for a holder on the list of the column descriptions.'

#componentsChangeSize
'Recompute layout when any component changes its size.'

#converter
'Method in the application returning a typeconverter.'

#createNewApplication
'Create a new appModel instance for the subCanvas (Client & clientHolder must be empty).'

#createNewBuilder
'Create a new builder instance for the subCanvas (subApp will use its own aspects).'

#dblClickChannel
'Aspect selector or binding for a holder on the double-clicked item.'

#defaultLabel
'Default label (used, if nothing selected).'

#documentText
'Aspect selector or binding for a holder of the html document itself.'

#documentURL
'Aspect selector or binding for a holder of the URL of the document.'

#doubleClickSelector
'Message sent upon double click.'

#downAction
'Message sent when the down(right)-button is pressed.'

#dragDisplayObjects
'1-arg (the dropSource) message, to get the list of Objects displayed during dragging'

#dragDropObjects
'1-arg (the dropSource) message, to get the list of DropObjects'

#dragFeedBack
'Optional 1-arg (dropContext) message, to give feedBack of a finished drag operation'

#dragStart
'Optional 2-arg (dropSource and view) message, called to start your own drag handler'

#dragStartArgument
'Optional user defined argument stored in the DropSource'

#drawBoxChannel
'Boolean aspect which controls box-display.'

#drawNormalsChannel
'Boolean aspect which controls normals-display.'

#dropArgument
'Optional user defined argument stored in the DropTarget'

#dropCanCheck
'1-arg (dropContext) message, to ask if drop is allowed'

#dropEnter
'Optional 1-arg (dropContext) message, sent when entering the widget'

#dropLeave
'Optional 1-arg (dropContext) message, sent when leaving the widget'

#dropOver
'Optional 1-arg (dropContext) message, sent while moving over the widget'

#dropSelector
'1-arg (dropContext) message, to drop the collection of DropObjects'

#enableChannel
'Aspect selector or binding for a boolean holder which enables the widget.'

#endMotionCallBack
'Message sent with end of thumb motion.'

#escapeIsCancelInDialog
'If on, and the window is opened modal, the ESC-Key acts like a Cancel-action'

#fileSelectionFilterClas
'The name of the item class used to create the entries into the hierarchical list.'

#fileSelectionTreeRoot
'Aspect selector or binding for a holder on the root directories path name.'

#fitLastRow
'Resize the last row to fit the width of the widget.'

#fontMenu
'Defines the font used by the widget.'

#forceRecursiveBackground
'If on, the background color is recursively set in all sub components.'

#foregroundChannel
'Aspect selector or binding for a foreground color holder.'

#foregroundColor
'Defines the foreground color of the widget.'

#galleryLabels
'Aspect selector or binding for a holder on the label list.'

#galleryModel
'Aspect selector or binding for the selected label.'

#gallerySelection
'Aspect selector or binding for a holder which gets the windowSpec of the selected widget.'

#gallerySelectors
'Message sent to ask the application for a list of resource spec selectors.'

#glxGraphXMax
'range end x'

#glxGraphXMin
'range start x'

#glxGraphXStep
'range step x'

#glxGraphYMax
'range end y'

#glxGraphYMin
'range start y'

#glxGraphYStep
'range step y'

#handlePosition
'The postion of the handle (Default means: as specified by viewStyle).'

#has3Dseparators
'Enable 3D-look row/column separators.'

#hasBorder
'Draw a border around the widget - ignored in 3D view styles (ST80 compatibility).'

#hierarchicalList
'Aspect selector or binding for a root item holder.'

#hierarchicalListButton
'Opens a Hierarchical List Editor on the application class and the defined selector.'

#highlightMode
'Defines how selected items are highlighted'

#holderToToggleVisibility
'Aspect selector or binding for a boolean to toggle visibility.'

#horizontalLayout
'Defines how sub components are arranged horizontally.'

#horizontalMiniScroller
'Use a mini-scroller as horizontal scrollbar.'

#horizontalScroller
'Enable horizontal scrollability.'

#horizontalSpace
'Horizontal space between sub components (in pixels).'

#id
'Unique symbolic name (ID) of the widget.'

#ignoreReselect
'Ignore user reselecting the same item.'

#indicatorClickSelector
'Message sent upon indicator click'

#initiallyDisabled
'Widget is initially disabled.'

#initiallyInvisible
'Widget is initially invisible.'

#inputFieldGroup
'Unique symbolic name (ID) for the group of the entry field.'

#isMultiSelect
'Enable/disable multiple selections.'

#isOpaque
'If on, the widget is displayed opaque; if off, its transparent.'

#isTriggerOnDown
'If on, the button triggers its action when pressed. If off, it triggers on release.'

#itemChildrenSelector
'Method in the application to return a block retrieveing nodes (lazy) children.'

#itemContentsSelector
'Method in the application to return a block retrieveing a nodes (lazy) contents.'

#itemIconSelector
'Method in the application to return a block retrieveing nodes (lazy) icon.'

#itemLabelSelector
'Method in the application to return a block retrieveing nodes (lazy) label.'

#keepCanvasAlive
'If on, the view is unmapped when switching; otherwise, its destroyed.'

#keyboardStep
'Defines the step used with cursor keys.'

#label
'The label of the widget.'

#labelAlignment
'Specifies how the labels logo is positioned within the Label.'

#labelChannel
'Aspect selector or binding for a labelString holder.'

#labelIsImage
'Label is actually the selector if a message providing an image-label.'

#labelPositionList
'Defines the position of the label.'

#lampColor
'Defines the lamps color.'

#level
'Level of the 3D-border (in pixels); take widgets default, if left empty.'

#listHolder
'Aspect selector or binding for the list holder.'

#majorKey
'Name of the class which provides the window spec. If empty, the application itself is used.'

#maxChars
'Maximum number of characters in the field.'

#maxSize
'Those two fields specify the windows maximum size. The user will not be allowed to resize it to a larger size.'

#maxValue
'An optional maximum value (if fieldType = numberInRange)'

#maxXField
'The maximum width of the applications topWindow.'

#maxYField
'The maximum height of the applications topWindow.'

#menuButton
'Open a Menu Editor on the menu.'

#menuId
'Aspect selector or binding providing the menu spec.'

#menuPerformer
'Aspect selector or binding providing the receiver of menu messages.'

#middleButtonPressed
'Message sent when the middle button is pressed.'

#minValue
'An optional minimum value (if fieldType = numberInRange)'

#minXField
'The minimum width of the applications topWindow.'

#minYField
'The minimum height of the applications topWindow.'

#minorKey
'Message sent to ask the class (major) for the window spec (default: #windowSpec).'

#model
'Aspect selector or binding providing the model of the widget.'

#modifiedChannel
'Aspect selector or binding for a holder for the modified-flag.'

#monitoring
'Enable automatic update whenever the directory is modified.'

#monitoringDelayTime
'Time in seconds between updates (if monitoring is enabled).'

#moveSelectedRow
'Enable/disable automatic movement of the row containing the selected tab item.'

#oneTabPerLine
'Arrange tabs vertically, with only one tab item per row.'

#openSubSpecGuiHelp
'Opens a GUI Builder on the defined class and selector.'

#orientation
'Defines the orientation (horizontal or vertical).'

#paramAdd
'Adds a name-value pair to the appletParameter collection.'

#paramList
'Lists defined parameters.'

#paramNameField
'The name of the appletParameter.'

#paramRemove
'Removes that appletParameter.'

#paramValueField
'The value of the appletParameter.'

#postBuildChannel
'1-arg message sent after creation of this widget (arg is widget).'

#progressValueHolder
'Aspect selector or binding for a holder on the indicators value.'

#radioButtonGroup
'Aspect selector or binding providing the radioButton group-model.'

#radioButtonValue
'Value passed to the radioButton group-model.'

#readOnly
'Make the contents be readOnly.'

#regionType
'Defines the shape of the widget.'

#resizeForLabel
'Enable/disable automatic resize after a label change.'

#resourceSelector
'Message sent to ask the application for a directory of keys and icons to register on the device'

#returnIsOKInDialog
'If on, and the window is opened modal, the Return/Enter-Key acts like an Accept-action'

#rowIfAbsent
'Message sent when an empty list entry is detected.'

#scrollerValueHolder
'Aspect selector or binding for a holder on the scrollers value.'

#selectConditionSelector
'Message sent to validate a selection (not selectable if false is returned).'

#selectInitially
'Text is initially selected.'

#selectOnButtomMenu
'Select item under mouse before opening the menu (always / never / controlled by ViewStyle).'

#selectRowOnDefault
'Select whole row, if unselectable column is selected.'

#selectionHolder
'Aspect selector or binding for a holder on the selection.'

#setMaxExtent
'Pick the maximum extent from the canvases current extent.'

#setMinExtent
'Pick the minimum extent from the canvases current extent.'

#showBox
'Display a bounding box.'

#showDirectoryIndicator
'Show/hide directory indicators for non-empty directories.'

#showDirectoryIndicatorForRoot
'Show/hide the indicator for the most left item.'

#showHandle
'Show resize-handles (Default means: as specified by viewStyle).'

#showIndicators
'Show/hide the indicators.'

#showLabels
'Show/hide column labels.'

#showLamp
'Show/hide the colored lamp.'

#showLines
'Show/hide connecting lines between tree items.'

#showNormals
'Display normals.'

#showPercentage
'Show/hide the percentage display.'

#showRoot
'Show/hide the root item.'

#showSeparatingLines
'Show/hide separated lines.'

#sizeAsDefault
'Size the widget to include space for the default-(return) bitmap.'

#sliderValueHolder
'Aspect selector or binding for a holder on the sliders value.'

#snapMode
'Show a quick-resize snap handle'

#specHolder
'Aspect selector or binding for holding the selector returning a window specification.'

#start
'Defines the ranges minimum.'

#startMotionCallBack
'Message sent with start of thumb motion.'

#step
'Defines the step within the range.'

#stop
'Defines the ranges maximum.'

#supportsExpandAll
'Enable/disable the expand-all function'

#tabIntern
'Tab into the widget; if off, TAB skips over the widgets fields'

#tabLabels
'Message sent to ask the application for a list of tab-item-labels.'

#tabLabelInset
'Inset of tab label; a Point or Integer; leave blank for default.'

#tabLevel
'3D Level (in pixels) of frame and tabs; take widgets default if left empty'

#tabMarginBottom
'Margin (in pixels) between tabs and canvas; take widgets default if left empty'

#tabMarginTop
'Margin (in pixels) between tabs and outer frame; take widgets default if left empty'

#tabOrientation
'Defines the side for the arrangement of the tab items.'

#tabWidget
'Defines the type of the border style of the tab items (Windows style vs. Mac style).'

#tabable
'Widget can be reached by pressing the TAB key.'

#tabbedOverEndAction
'Message sent when the end was reached by tabbing.'

#tabbedOverStartAction
'Message sent when the beginning was reached by tabbing.'

#textModel
'Aspect selector or binding providing the model of the widget; (string-valued, unless a type/converter is given).'

#translateLabel
'Translate the label via the resource mechanism to a national language string.'

#typeConverter
'Defines how the entry string is converted to an object which is passed to the model.'

#upAction
'Message sent when the up(left)-button is pressed.'

#useDefaultIcons
'If on, default icons are drawn for each item which donot provide its own icon.'

#useIndex
'If on, use the items index as selection; if off, use the items value.'

#usePreferredExtent
'If on, the window computes its preferred extent; if off, the layout-sections value is used.'

#validateDoubleClickSelector
'Message sent to the application to validate double click (no action if false is returned).'

#validateExpandabilitySelector
'Message sent to the application to validate expand on double click (no expand if false is returned).'

#valueChangeSelector
'Message sent to the application when the selection has changed.'

#verticalLayout
'Defines how sub components are vertically arranged.'

#verticalMiniScroller
'Use a mini-scroller as vertical scrollbar.'

#verticalScroller
'Enable vertical scrollability.'

#verticalSpace
'Vertical space between the sub components (in pixels).'

#viewChannel
'Aspect selector or binding for a holder provides the view to be embedded.'

#visibilityChannel
'Aspect selector or binding for a boolean holder which makes the widget visible.'

#whichViewIsToggled
'Which views visibility is toggled by the valueHolder.'

#windowIcon
'Message sent to ask the application for an icon image for the top window.'

#windowLabel
'Label of the top window.'

#xRotChannel
'Aspect providing x-Rotation value.'

#xTransChannel
'Aspect providing x-Translation value.'

#yRotChannel
'Aspect providing y-Rotation value.'

#yTransChannel
'Aspect providing y-Translation value.'

#zRotChannel
'Aspect providing z-Rotation value.'

#zTransChannel
'Aspect providing z-Translation value.'

)
! !

!UISpecificationTool class methodsFor:'interface specs'!

windowSpec
    "This resource specification was automatically generated
     by the UIPainter of ST/X."

    "Do not manually edit this!! If it is corrupted,
     the UIPainter may not be able to read the specification."

    "
     UIPainter new openOnClass:UISpecificationTool andSelector:#windowSpec
     UISpecificationTool new openInterface:#windowSpec
     UISpecificationTool open
    "

    <resource: #canvas>

    ^ 
     #(#FullSpec
        #name: #windowSpec
        #window: 
       #(#WindowSpec
          #label: 'unnamed canvas'
          #name: 'unnamed canvas'
          #bounds: #(#Rectangle 12 22 312 322)
        )
        #component: 
       #(#SpecCollection
          #collection: #(
           #(#ArbitraryComponentSpec
              #name: 'BuildInView'
              #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #hasVerticalScrollBar: true
              #miniScrollerVertical: true
              #autoHideScrollBars: true
              #hasBorder: false
              #component: #buildInView
            )
           )
         
        )
      )
! !

!UISpecificationTool methodsFor:'accessing-channels'!

modifiedHolder:aValueHolder
    "set the value holder set to true in case of modifying attributes
    "

    modifiedHolder removeDependent:self.

    (modifiedHolder := aValueHolder) notNil ifTrue:[
        modifiedHolder addDependent:self.
    ].

! !

!UISpecificationTool methodsFor:'accessing-specification'!

specification
    "gets current edit specification
    "
    ^ specification


!

specification:aSpec
    "sets current edit specification
    "
    aSpec notNil ifTrue:[
        "/ same type of spec - simply change the spec;  no need to setup everything
        specification class == aSpec class ifTrue:[
            specification := aSpec.
            specChannel value:specification.
          ^ self
        ]
    ].

    "/ release resources
    specChannel release.
    aspects     release.
    selection := listOfSpecViews := nil.
    buildInView destroyAllClientViews.

    (specification := aSpec) isNil ifTrue:[
        aspects := specChannel := nil.
      ^ self
    ].
    
    "/ some tricky specs need the builder during the addBindings phase.
    "/ This is passed down in a special UIBindingsDictionary
    "/ (remain backward compatible)

    aspects := UISpecification newBindingsDictionary.
    aspects builder:builder.
    aspects at:#modifiedChannel put:modifiedHolder.
    aspects at:#acceptChannel   put:self acceptChannel.

    specChannel := specification asValue.
    specification class addBindingsTo:aspects for:specification channel:specChannel.

    "/ arrange for being notified, if any aspect changes
    aspects do:[:el| el addDependent:self ].
! !

!UISpecificationTool methodsFor:'actions'!

setMaxExtent
    "set the windows maxExtent from its current extent"

    |canvas currentExtent|

    canvas := self masterApplication painter topView.
    currentExtent := canvas extent.
    (self aspectFor:#maxX) value:currentExtent x.
    (self aspectFor:#maxY) value:currentExtent y.

    "Modified: / 29.10.1997 / 18:29:17 / cg"
!

setMinExtent
    "set the windows minExtent from its current extent"

    |canvas currentExtent|

    canvas := self masterApplication painter topView.
    currentExtent := canvas extent.
    (self aspectFor:#minX) value:currentExtent x.
    (self aspectFor:#minY) value:currentExtent y.

    "Created: / 29.10.1997 / 18:17:55 / cg"
    "Modified: / 29.10.1997 / 18:28:53 / cg"
! !

!UISpecificationTool methodsFor:'bindings'!

acceptChannel
    "return the value of the instance variable 'acceptChannel' (automatically generated)"

    ^ masterApplication acceptChannel
!

aspectFor:aKey
    "returns aspect for a key or nil
    "
    aspects notNil ifTrue:[
        ^ aspects at:aKey ifAbsent:nil
    ].
    ^ super aspectFor:aKey

!

buildInView
    ^ buildInView
!

specificationFor:aKey
    "this is called if our current specification contains 
     subspecifications or subcanvases.
     Get the subspecification from the current specification"

    specification notNil ifTrue:[
        ^ specification class perform:aKey ifNotUnderstood:nil
    ].
    ^ nil
! !

!UISpecificationTool methodsFor:'change & update'!

update
    "reload specification
    "
    specChannel notNil ifTrue:[
        specChannel value:specification.
    ]


!

update:something with:someArgument from:someone
    "any attribute changed its state in the current specification
    "
    someone ~~ modifiedHolder ifTrue:[
        "/ any in the spec has changed.
        "/ update my modified holders value

        modifiedHolder value:true
    ]

    "Modified: / 16.7.1998 / 19:25:59 / cg"
! !

!UISpecificationTool methodsFor:'initialization'!

initialize
    super initialize.
    buildInView := BuildInView new.
    buildInView keepViews:true.
! !

!UISpecificationTool methodsFor:'selection'!

selection:something
    "selection changed
    "
    |slices index spec window|

    specification notNil ifTrue:[
        slices := specification class slices.
        index  := slices findFirst:[:aSlice| aSlice first = something ].

        index ~~ 0 ifTrue:[
            spec := specification class perform:((slices at:index) last)
        ]
    ].

    spec ~= selection ifTrue:[
        (selection := spec) notNil ifTrue:[
            listOfSpecViews isNil ifTrue:[
                listOfSpecViews := Array new:(slices size).
            ] ifFalse:[
                window := listOfSpecViews at:index
            ].
            window isNil ifTrue:[
                builder buildFromSpec:spec in:(window := SimpleView new).
                listOfSpecViews at:index put:window.
            ].
        ].
        buildInView scrolledView:window.
    ].
! !

!UISpecificationTool::BuildInView methodsFor:'accessing'!

scrolledView:aView
    "set the view to be scrolled"
    |wrapper y|

    scrolledView == aView ifTrue:[^ self].

    scrolledView notNil ifTrue:[scrolledView beInvisible].

    scrolledView := aView.

    (scrolledView notNil and:[scrolledView superView ~~ frame]) ifTrue:[
        scrolledView borderWidth:0; level:0.

        frame addSubView:scrolledView.

        scrolledView subViews size == 1 ifTrue:[
            wrapper := scrolledView subViews first.
            wrapper isScrollWrapper ifTrue:[
                "/ give it a full-relative size, and let it do
                "/ the scrolling itself.
                y := 1.0
            ]
        ].
        y isNil ifTrue:[
            y := scrolledView preferredExtent y
        ].
        scrolledView origin:0@0 corner:1.0 @ y.
        scrolledView allViewBackground:(self viewBackground).
    ].

    realized ifTrue:[
        scrolledView ifNotNil:[scrolledView beVisible].
        self sizeChanged:nil.
    ].
    model value:scrolledView.
! !

!UISpecificationTool::BuildInView methodsFor:'initialization'!

level:aLevel
    super level:0
!

realize

    super realize.
    superView notNil ifTrue:[superView level:0].
! !

!UISpecificationTool class methodsFor:'documentation'!

version
    ^ '$Header$'
! !