<?xml version="1.0"?>

<st-source>
<!-- 
Name: SparingScrollbars(7.10.1)
Notice: Copyright © 2010-1999 Cincom Systems, Inc.  All Rights Reserved.
BundleName: SparingScrollbars
BundleStructure: a Store.BundleForParcel
Comment: SparingScrollbars is a temporary bundle in response to AR50314.  It contains extensions to UI classes and extensions to the UIPainter package to implement optional dynamic scrollbars which appear and disappear depending on the actual and visible bounds of the content the scrollbars wrap.  There are also some test and sample classes which demonstrate the usage of this new behavior.

NOTE: 
The contents of this bundle will soon be merged, as appropriate, into the Base VisualWorks  bundle and the UIPainter package, and some selected examples will be upgraded to support optional dynamic scrollbars, or additional examples will be added to demonstrate this usage.

The following comments from the AR discuss the changes in this bundle and how to configure applications to use this new behavior.
- - - - - - - -

A widget with optional dynamic scroll bars should show scroll bars only when there is more content than can be seen for its size.  That means the scroll bars should be visible if the size of the window or widget is shrunk or if content is added.

The BorderDecorator wrapper controls scroll bars.  Messages such as #noHorizontalScrollBar or #useHorizontalScrollBar are sent to it to remove or add scrollbars.  A ScrollWrapper appears as a component of a BorderDecorator and it translates and models scroll position of its view component.  Only a ScrollWrapper may know if scroll is unnecessary.  A ScrollWrapper will need to notify its container BorderDecorator if the BorderDecorator is to control scroll bar visibility.

The widgetFlags instance variable of BorderDecorator and flags instance variable of all the widget specs named above retains the state of border, scroll, disabled, and visibility settings.  The widgetFlags or flags instance variable encodes the boolean state of each option to one bit position using :

bit 6 (32) =	Disabled
bit 5 (16) =	Invisible
bit 4 (8) =	Has border
bit 3 (4) =	Has menu bar
bit 2 (2) =	Has H scroll bar
bit 1 (1) =	Has V scroll bar

This bundle adds two new bit positions to interpret whether scroll bars are used "sparingly" and shown only when needed.  These may be set in the UIPainter from the Details tab for the widget.

bit 8 (128) =	Use H scroll bar sparingly
bit 7 (64) =	Use V scroll bar sparingly

When widgetFlags "Use H scroll bar sparingly" (bit 7) is set, the BorderDecorator will toggle "Has V scroll bar" (bit 1) as necessary to make the vertical scroll bar visible when needed.  BorderDecorator will change its answer to #hasVerticalScrollBar based on whether the vertical scroll bar is currently visible.  Settings and use of the horizontal scroll bar are similar.

The current visibility of a scroll bar does not change bitwise assignments to the flags variable of a widget's spec instance.  If a widget spec is set to show a scroll bar it will always show the scroll bar by default.  The spec must set both bits for the scroll bar to show, and to show sparingly, in order to have the scrollbar appear only when necessary.

Parcel: nil
ParcelName: SparingScrollbars(7.10.1)
PrerequisiteParcels: #(#('UIPainter' '') #('ImageReaders' ''))
Version: 7.10.1 - 1
Date: 6:10:40 PM July 1, 2015
 -->
<time-stamp>From VisualWorks®, 7.10.1 of 6 February 2014 on 1 July 2015 at 18:10:40</time-stamp>


<do-it>(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned.  Choose terminate or close.']</do-it>

<class>
<name>TestWindow</name>
<environment>Smalltalk</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>TestWindow</class-id>
<body>TestWindow is used by TestSubcanvas2.
</body>
</comment>

<class>
<name>ClassCommentEditor</name>
<environment>Smalltalk</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>classSelection selectionSubclasses </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>ClassCommentEditor</class-id>
<body>ClassCommentEditor demonstrates use of dynamic scrollbars in a TextEditor.

Instance Variables:
	classSelection	&lt;ValueModel&gt;	the combo box class selector
	selectionSubclasses	&lt;SelectionInList&gt;		a list of subclasses for the selected class

</body>
</comment>

<class>
<name>TableLabelsExample</name>
<environment>Examples</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>tableInterface sightingsTable </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Examples-Help</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>Examples.TableLabelsExample</class-id>
<body>TableLabelsExample demonstrates use of dynamic scrollbars with a Table widget to display data, including row and column labels.

Instance Variables:

	tableInterface	holding table data for the widget
	sightingsTable	a SelectionInTable holding a TwoDList and a cell coordinates
	cellContents	holds the contents of the entry field to put in the table</body>
</comment>

<class>
<name>TreeList1Example</name>
<environment>Examples</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>treeList </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>HierarchicalList-Examples</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>Examples.TreeList1Example</class-id>
<body>I demonstrate how an class hierarchy and its elements may be displayed 
and selected in a HierarchicalList.

Instance Variables:

treeList        &lt;IndentedTreeSelectionInList&gt;   Class tree</body>
</comment>

<class>
<name>GIFImageViewer</name>
<environment>Smalltalk</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>gifFiles imageWrapper </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>GIFImageViewer</class-id>
<body>GIFImageViewer demonstrated use of sparing scrollbars on a display Image.

Instance Variables:
	gifFiles	&lt;SelectionInList&gt;		a list of image files (.gif format)
	imageWrapper	&lt;Wrapper&gt;	the display image wrapper

</body>
</comment>

<class>
<name>TestSubcanvas1</name>
<environment>Smalltalk</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>TestSubcanvas1</class-id>
<body>TestSubcanvas1 demonstrates use of sparing scrollbars in a subcanvas.
</body>
</comment>

<class>
<name>SparingTable1Example</name>
<environment>Examples</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>tableInterface sightingsTable cellContents </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Examples-Help</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>Examples.SparingTable1Example</class-id>
<body>SparingTable1Example demonstrates using a Table widget to display data.
This example demonstrates the absence of dynamic scrollbars on open since the table is small.

Instance Variables:

	tableInterface	holding table data for the widget
	sightingsTable	a SelectionInTable holding a TwoDList and a cell coordinates
</body>
</comment>

<class>
<name>ScrollConstructor</name>
<environment>UI</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>specChannel </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIBuilder-Support</category>
<attributes>
<package>Sparing Scrollbars UIEdit</package>
</attributes>
</class>

<comment>
<class-id>UI.ScrollConstructor</class-id>
<body>ScrollConstructor supports the UIPainterTool by providing the Details slice user interface for vertical and horizontal scroll bar option selections.

Instance Variables:
	specChannel	&lt;ValueHolder&gt;		ValueHolder on spec of component selected in UIPainterTool.  

</body>
</comment>

<class>
<name>SparingTable3Example</name>
<environment>Examples</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>tableInterface sightingsTable </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Examples-Help</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>Examples.SparingTable3Example</class-id>
<body>SparingTable3Example demonstrates using a Table widget to display data.
This example demonstrates the presence of dynamic scrollbars on open since the table is large.

Instance Variables:

	tableInterface	holding table data for the widget
	sightingsTable	a SelectionInTable holding a TwoDList and a cell coordinates
</body>
</comment>

<class>
<name>TreeList2Example</name>
<environment>Examples</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>classComment rootClass treeList </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>Examples.TreeList2Example</class-id>
<body>I display a HierarchicalList of classes as an indented list.

Instance Variables:

treeList        &lt;IndentedTreeSelectionInList&gt;   Class tree
classComment    &lt;String&gt;        Class comment of selection
rootClass       &lt;AspectAdaptor on: IndentedTreeSelectionInList&gt; Root class 
of treeList</body>
</comment>

<class>
<name>BorderDecorator</name>
<environment>UI</environment>
<super>Graphics.CompositePart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>component policy hasBorder hasHorizontalScrollbar hasVerticalScrollbar widgetFlags </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIBasics-Support</category>
<attributes>
<package>Sparing Scrollbars</package>
</attributes>
</class>

<comment>
<class-id>UI.BorderDecorator</class-id>
<body>BorderDecorator is a CompositePart that has a distinguished component.  All of its other components are created dynamically, based on a layout policy and on various boolean attributes such as whether it wants its component to be accompanied by a vertical scrollbar.

Instance Variables
	component	&lt;ScrollWrapper&gt;  a wrapper on an arbitrary VisualComponent, which allows the VisualComponent to be scrolled within the BorderDecorator's data area.
	hasBorder 	&lt;Boolean&gt; whether or not to add a border
	hasHorizontalScrollbar	&lt;Boolean&gt; should a horizontal scrollbar be added
	hasVerticalScrollbar	&lt;Boolean&gt; should a vertical scrollbar be added
	policy		&lt;BorderDecorationPolicy | nil&gt; policy used to control the look of the border decorations


Object Reference
A BorderDecorator is a composite part that has a main component for which it supplies commonly used subsidiary components, optionally including a border, menu bar and scroll bars. It is only used directly by applications that build interfaces programmatically, rather than using painted interfaces. 
A BorderDecorator is created by sending #on: to this class, with the main visual component as argument. The subsidiary components can then be added or removed, via messages such as #useBorder and #noBorder. By default, a BorderDecorator has a border, a menu bar and a vertical scroll bar, but no horizontal scroll bar. 
The BorderDecorator class is typically referenced indirectly, by sending #edgeDecorator to the LookPreferences class. This strategy allows for future substitution of a specialized subclass of BorderDecorator without having to change each method that creates a decorator. 
BorderDecorator relies on a policy object to render its subsidiary components as they would appear on a particular operating system. By default, the policy is shared with other visual components in the same window and even with other windows' components. 
BorderDecorator has one subclass, TableDecorator, which adds subsidiary components needed by a TableView. 
</body>
</comment>

<class>
<name>TestSubcanvas2</name>
<environment>Smalltalk</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIApplications-New</category>
<attributes>
<package>Sparing Scrollbar Samples</package>
</attributes>
</class>

<comment>
<class-id>TestSubcanvas2</class-id>
<body>TestSubcanvas2 demonstrates use of dynamic scrollbars with a subcanvas containing an ApplicationModel.
</body>
</comment>

<methods>
<class-id>ClassCommentEditor</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">classSelection
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^classSelection isNil
		ifTrue:
			[classSelection := nil asValue]
		ifFalse:
			[classSelection]</body>

<body package="Sparing Scrollbar Samples">classSelectionHolder
	^self selectionSubclasses selectionHolder</body>

<body package="Sparing Scrollbar Samples">classes
	^Object subclasses asValue</body>

<body package="Sparing Scrollbar Samples">selectionSubclasses
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^selectionSubclasses isNil
		ifTrue:
			[selectionSubclasses := SelectionInList new]
		ifFalse:
			[selectionSubclasses]</body>
</methods>

<methods>
<class-id>ClassCommentEditor</class-id> <category>notification</category>

<body package="Sparing Scrollbar Samples">classSelected
	self selectionSubclasses list: self classSelection value subclasses asList</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">printTables
	| ps interior composite scale layout wrapperToFit boundsToFit boundsToDisplay |
	ps := Printer startPrintJobNamed: 'tables.ps'.
	interior := ps bounds insetBy: ps bounds width * 0.06.
	layout := (LayoutFrame new)
				leftFraction: 0.1;
				rightFraction: 0.9;
				topFraction: 0.1;
				bottomFraction: 0.9.
	composite := CompositePart new.
	wrapperToFit := self tableWrapperOf: (self builder componentAt: #Table2).
	wrapperToFit	 newGraphicsDevice: ps graphicsDevice.
	boundsToFit := wrapperToFit preferredBounds.
	boundsToDisplay := layout rectangleRelativeTo: interior preferred: boundsToFit.
	composite add: (0@0 extent: boundsToDisplay extent) asStroker  in: layout.

	scale := boundsToDisplay extent / boundsToFit extent.
	scale := scale x min: scale y.
	composite add: ((ScalingWrapper on: wrapperToFit) scale: scale) in: layout.
	[(MockMedium 
		on: composite
		in: interior
		for: ps)
		newGraphicsDevice: ps graphicsDevice;
		display] 
			ensure: [ps close].</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample</class-id> <category>initialize-release</category>

<body package="Sparing Scrollbar Samples">initialize					
	| list bigList |
	super initialize.
	"Create a collection of sightings data."
	bigList := #('Vulcans' 188 173 192 'Romulans' 26 26 452).
	4 timesRepeat:[bigList := bigList , bigList].
	list := TwoDList
		on: bigList
		columns: 4
		rows: bigList size / 4.
	sightingsTable := SelectionInTable with: list.
	"Create a table interface and load it with the sightings."
	tableInterface := TableInterface new
		selectionInTable: sightingsTable.

	tableInterface columnWidths: #(100 40).

	tableInterface
	columnLabelsArray: #('Visiting Race' '1992' '1993' '1994');
	rowLabelsArray: #('100' 'Two Hundred').
	"rowLabelsWidth: 20."

	tableInterface
	elementFormats: #(#left #right #right #right);
	columnLabelsFormats: #(#left #right #right #right);
	rowLabelsFormat: #right.</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">sightingsTable
	^sightingsTable</body>

<body package="Sparing Scrollbar Samples">tableInterface
	^tableInterface</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample</class-id> <category>interface opening</category>

<body package="Sparing Scrollbar Samples">preBuildWith: aBuilder
	"aBuilder policy: MacLookPolicy new."</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample</class-id> <category>private</category>

<body package="Sparing Scrollbar Samples">tableWrapperOf: aSpecWrapper 
	| widget decorator |
	widget := aSpecWrapper widget copy.
	decorator := aSpecWrapper decorator copy.
	(decorator initialize)
		noDecorations;
		setComponent: (ScrollWrapper on: widget);
		setUpColumnLabelsFor: widget;
		setUpRowLabelsFor: widget;
		resetComponents.
	^decorator</body>
</methods>

<methods>
<class-id>Examples.TreeList1Example</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">chooseNewClass

         | result |
        result := SmalltalkWorkbench findAClass: 'Hierarchy on what class?' for: nil.
        result isNil ifFalse:[self treeList tree: result].</body>
</methods>

<methods>
<class-id>Examples.TreeList1Example</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">selection
        ^self treeList selectionHolder</body>

<body package="Sparing Scrollbar Samples">treeList
        ^treeList isNil
                ifTrue: [treeList := IndentedTreeSelectionInList
                                                listObjectHierarchy: Collection
                                                childAccessor: #subclasses
                                                childNameAccessor: #name]
                ifFalse: [treeList]</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>testing</category>

<body package="Sparing Scrollbar Samples">hasFileSelection
	^self gifFiles selectionIndex &gt; 0</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>private</category>

<body package="Sparing Scrollbar Samples">addFile: filename 
	^self gifFiles list 
		add: filename -&gt; (CachedImage on: (ImageReader fromFile: filename) image)</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">readFile
	| filename |
	filename := Dialog requestFileName: 'GIF file to read' default: '*.gif'.
	filename notEmpty 
		ifTrue: [self addFile: filename]</body>

<body package="Sparing Scrollbar Samples">readFromDirectory
	| directory |
	directory := Dialog requestDirectoryName: 'GIF source directory'.
	directory notEmpty 
		ifTrue: 
			[(directory asFilename filesMatching: '*.gif') 
				do: [:filename | self addFile: filename]]</body>

<body package="Sparing Scrollbar Samples">removeFile
	self gifFiles selectionDo: 
			[:item | 
			self gifFiles list remove: item.
			self gifFiles selectionIndex: 0.
			self selectionUpdate]</body>

<body package="Sparing Scrollbar Samples">removeSelection
	self gifFiles selectionDo: 
			[:item | 
			self gifFiles list remove: item.
			self gifFiles selectionIndex: 0.
			self selectionUpdate]</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>initialize-release</category>

<body package="Sparing Scrollbar Samples">initialize
	super initialize.
	imageWrapper := BoundedWrapper on: self emptyVisual.</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>notification</category>

<body package="Sparing Scrollbar Samples">selectionUpdate
	| image |
	image :=self gifFiles selection value ifNil: [self emptyVisual].
	imageWrapper
		component: image;
		bounds: image bounds;
		changedPreferredBounds: nil.
	(self builder componentAt: #ViewHolder1) invalidate</body>
</methods>

<methods>
<class-id>GIFImageViewer</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">emptyVisual
	^VisualBlock block: [:gc :bounds | gc clear]</body>

<body package="Sparing Scrollbar Samples">gifFiles
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^gifFiles isNil
		ifTrue:
			[gifFiles := SelectionInList new]
		ifFalse:
			[gifFiles]</body>

<body package="Sparing Scrollbar Samples">imageWrapper
	^imageWrapper</body>
</methods>

<methods>
<class-id>TestSubcanvas1</class-id> <category>accessing</category>

<body package="Sparing Scrollbar Samples">client
	^Examples.TreeList2Example new</body>
</methods>

<methods>
<class-id>Examples.SparingTable1Example</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">sightingsTable
	^sightingsTable</body>

<body package="Sparing Scrollbar Samples">tableInterface
	^tableInterface</body>
</methods>

<methods>
<class-id>Examples.SparingTable1Example</class-id> <category>initialize-release</category>

<body package="Sparing Scrollbar Samples">initialize					
	| list |
	super initialize.
	"Create a collection of sightings data."
	list := TwoDList
		on: #('Vulcans' 188 173 192 'Romulans' 26 26 452) copy
		columns: 4
		rows: 2.
	sightingsTable := SelectionInTable with: list.
	"Create a table interface and load it with the sightings."
	tableInterface := TableInterface new
		selectionInTable: sightingsTable.

	tableInterface columnWidths: #(100 40).</body>
</methods>

<methods>
<class-id>Examples.SparingTable1Example</class-id> <category>interface opening</category>

<body package="Sparing Scrollbar Samples">openInterface: aSymbol 
	"Open the ApplicationModel's user interface, using the specification 
	named."

	self halt.
	^self openInterface: aSymbol withPolicy: UIBuilder defaultPolicy</body>
</methods>

<methods>
<class-id>Examples.SparingTable1Example</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">refreshTable

	self halt.
	self builder window refresh</body>
</methods>

<methods>
<class-id>UI.ScrollConstructor</class-id> <category>accessing</category>

<body package="Sparing Scrollbars UIEdit">specChannel
	^specChannel</body>
</methods>

<methods>
<class-id>UI.ScrollConstructor</class-id> <category>notification</category>

<body package="Sparing Scrollbars UIEdit">updateHorizontalScrollOption
	| enableVisibility |
	enableVisibility := (self builder 
				aspectAt: #'specChannel hasHorizontalScrollBar') value.
	enableVisibility 
		ifFalse: 
			[(self builder aspectAt: #'specChannel isSparingHorizontalScrollBar') 
				value: false].
	(self builder componentAt: #SparingHorizontalCheckBox) 
		isEnabled: enableVisibility</body>

<body package="Sparing Scrollbars UIEdit">updateVerticalScrollOption
	| enableVisibility |
	enableVisibility := (self builder 
				aspectAt: #'specChannel hasVerticalScrollBar') value.
	enableVisibility 
		ifFalse: 
			[(self builder aspectAt: #'specChannel isSparingVerticalScrollBar') 
				value: false].
	(self builder componentAt: #SparingVerticalCheckBox) 
		isEnabled: enableVisibility</body>
</methods>

<methods>
<class-id>UI.ScrollConstructor</class-id> <category>initialize-release</category>

<body package="Sparing Scrollbars UIEdit">on: aValueHolder
	specChannel := aValueHolder.</body>
</methods>

<methods>
<class-id>UI.ScrollConstructor</class-id> <category>interface opening</category>

<body package="Sparing Scrollbars UIEdit">postBuildWith: aBuilder 
	super postBuildWith: aBuilder.
	self updateHorizontalScrollOption.
	self updateVerticalScrollOption</body>
</methods>

<methods>
<class-id>Examples.SparingTable3Example</class-id> <category>initialize-release</category>

<body package="Sparing Scrollbar Samples">initialize					
	| list bigList interface |
	super initialize.

	"Create a collection of sightings data."
	bigList := #('Vulcans' 188 173 192 'Romulans' 26 26 452).
	3 timesRepeat:[bigList := bigList , bigList].
	list := TwoDList
		on: bigList
		columns: 4
		rows: bigList size / 4.
	sightingsTable := SelectionInTable with: list.

	"Create a table interface and load it with the sightings."
	interface := TableInterface new
		selectionInTable: sightingsTable.
	interface 
		columnWidths: #(100 40);
		columnLabelsArray: #('Visiting Race' '1992' '1993' '1994');
		elementFormats: #(#left #right #right #right);
		columnLabelsFormats: #(#left #right #right #right).

	tableInterface := interface.</body>
</methods>

<methods>
<class-id>Examples.SparingTable3Example</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">tableInterface
	^tableInterface</body>
</methods>

<methods>
<class-id>Examples.SparingTable3Example</class-id> <category>interface opening</category>

<body package="Sparing Scrollbar Samples">openInterface: aSymbol 
	"Open the ApplicationModel's user interface, using the specification 
	named."

	self halt.
	^self openInterface: aSymbol withPolicy: UIBuilder defaultPolicy</body>
</methods>

<methods>
<class-id>Examples.SparingTable3Example</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">refreshTable

	self halt.
	self builder window refresh</body>
</methods>

<methods>
<class-id>Examples.TreeList2Example</class-id> <category>actions</category>

<body package="Sparing Scrollbar Samples">chooseNewClass
         | result |
        result := SmalltalkWorkbench findAClass: 'Hierarchy on what class?' for:nil.
        result isNil
                ifFalse:[self rootClass value: result].</body>

<body package="Sparing Scrollbar Samples">updateComment
        | class |
        self classComment value: (
                (class := self treeList selection) isNil
                        ifTrue: [String new]
                        ifFalse: [class comment])</body>
</methods>

<methods>
<class-id>Examples.TreeList2Example</class-id> <category>aspects</category>

<body package="Sparing Scrollbar Samples">classComment

        ^classComment isNil
                ifTrue:
                        [classComment := String new asValue]
                ifFalse:
                        [classComment]</body>

<body package="Sparing Scrollbar Samples">rootClass

        ^rootClass isNil
                ifTrue:[rootClass := (AspectAdaptor forAspect:#tree) subject: self treeList]
                ifFalse:[rootClass]</body>

<body package="Sparing Scrollbar Samples">selection
        ^self treeList selectionHolder</body>

<body package="Sparing Scrollbar Samples">treeList
        treeList isNil
                ifTrue: [treeList := IndentedTreeSelectionInList
                                                listObjectHierarchy: Collection
                                                childAccessor: #subclasses
                                                childNameAccessor: #name.
                                self selection onChangeSend:#updateComment to: self.
                                "Uncomment the following for an indented list"
                                "treeList isUsingVisualBlocks: false"].
                ^treeList</body>
</methods>

<methods>
<class-id>UI.BorderDecorator</class-id> <category>accessing</category>

<body package="Sparing Scrollbars">noBorder
	"The receiver is not to draw a border around the component."

	self widgetFlags: (self widgetFlags maskClear: 8).
	hasBorder := false.
	self checkComponents</body>

<body package="Sparing Scrollbars">noHorizontalScrollBar
	"The receiver is not to use a horizontal scroll bar.  This is the default."

	self widgetFlags: (self widgetFlags maskClear: 2).
	self noHorizontalScrollbar</body>

<body package="Sparing Scrollbars">noMenuBar
	"The receiver is not to use a MenuBar."

	self widgetFlags: (self widgetFlags maskClear: 4).</body>

<body package="Sparing Scrollbars">noSparingHorizontalScrollBar
	"The receiver will not hide a horizontal scroll bar whenever it is unnecessary.  This is the default."

	self widgetFlags: (self widgetFlags maskClear: 128).</body>

<body package="Sparing Scrollbars">noSparingVerticalScrollBar
	"The receiver will not hide a vertical scroll bar whenever it is unnecessary.  This is the default."

	self widgetFlags: (self widgetFlags maskClear: 64)</body>

<body package="Sparing Scrollbars">noVerticalScrollBar
	"The receiver is not to use a vertical scroll bar."

	self widgetFlags: (self widgetFlags maskClear: 1).
	self noVerticalScrollbar</body>

<body package="Sparing Scrollbars">useHorizontalScrollBar: aBoolean 
	"Update the visibility of the horizontal scroll bar only when changed by aBoolean."

	(aBoolean and: [self hasHorizontalScrollBar not]) 
		ifTrue: [self useHorizontalScrollBar].
	(aBoolean not and: [self hasHorizontalScrollBar]) 
		ifTrue: [self noHorizontalScrollBar]</body>

<body package="Sparing Scrollbars">useHorizontalScrollBarSparingly
	"The receiver is to hide the horizontal scroll bar whenever it is unnecessary."

	self widgetFlags: (self widgetFlags maskSet: 128).
	self checkComponents</body>

<body package="Sparing Scrollbars">useVerticalScrollBar: aBoolean 
	"Update the visibility of the vertical scroll bar only when changed by aBoolean."

	(aBoolean and: [self hasVerticalScrollBar not]) 
		ifTrue: [self useVerticalScrollBar].
	(aBoolean not and: [self hasVerticalScrollBar]) 
		ifTrue: [self noVerticalScrollBar]</body>

<body package="Sparing Scrollbars">useVerticalScrollBarSparingly
	"The receiver is to hide the vertical scroll bar whenever it is unnecessary."

	self widgetFlags: (self widgetFlags maskSet: 64).
	self checkComponents</body>

<body package="Sparing Scrollbars">widgetFlags
	^widgetFlags ifNil: [widgetFlags := 0]</body>

<body package="Sparing Scrollbars">widgetFlags: highWidgetFlags
	widgetFlags := highWidgetFlags</body>
</methods>

<methods>
<class-id>UI.BorderDecorator</class-id> <category>testing</category>

<body package="Sparing Scrollbars">isSparingHorizontalScrollBar
	"Answer whether the receiver is using a horizontal scroll bar sparingly."

	^(self widgetFlags bitAnd: 128) ~= 0</body>

<body package="Sparing Scrollbars">isSparingVerticalScrollBar
	"Answer whether the receiver is using a vertical scroll bar sparingly."

	^(self widgetFlags bitAnd: 64) ~= 0</body>
</methods>

<methods>
<class-id>UI.BorderDecorator</class-id> <category>bounds accessing</category>

<body package="Sparing Scrollbars">bounds: newBounds
	"Set the receiver's bounds to newBounds."
	
	components isEmpty ifTrue: [self resetComponents].
	super bounds: newBounds.
	self
		setScrollBarsFor: component
		update:
			[self checkComponents.
			self isOpen ifFalse: [self bounds: newBounds]]</body>
</methods>

<methods>
<class-id>UI.BorderDecorator</class-id> <category>private</category>

<body package="Sparing Scrollbars">setScrollBarsFor: aScrollWrapper
	
	self
		setScrollBarsFor: aScrollWrapper
		update: [self checkComponents]</body>

<body package="Sparing Scrollbars">setScrollBarsFor: aScrollWrapper update: aBlock
	
	| update |
	(aScrollWrapper isKindOf: ScrollWrapper) ifFalse: [^self].
	update := false.
	self isSparingVerticalScrollBar
		ifTrue:
			[update := update
				|
					(self
						show: aScrollWrapper canScrollVertically
						scrollBar: 2r001)].
	self isSparingHorizontalScrollBar
		ifTrue:
			[update := update
				|
					(self
						show: aScrollWrapper canScrollHorizontally
						scrollBar: 2r010)].
	update ifTrue: aBlock</body>

<body package="Sparing Scrollbars">show: aBoolean scrollBar: anInteger
	
	anInteger = 1 ifTrue: 
		[self hasVerticalScrollbar = aBoolean ifFalse:
			[hasVerticalScrollbar := aBoolean.
			^true]].
	anInteger = 2 ifTrue: 
		[self hasHorizontalScrollbar = aBoolean ifFalse:
			[hasHorizontalScrollbar := aBoolean.
			^true]].
	"(widgetFlags bitAnd: anInteger) ~= 0 = aBoolean
		ifFalse:
			[widgetFlags := aBoolean
				ifTrue: [widgetFlags bitOr: anInteger]
				ifFalse: [widgetFlags maskClear: anInteger].
			^true].
	"
	^false</body>
</methods>

<methods>
<class-id>UI.BorderDecorator</class-id> <category>broadcast</category>

<body package="Sparing Scrollbars">upcastEvent: aKey with: aParameter from: anInitiator path: aPathCollection 
	"For Border Decorated components, we want to downcast to my components before passing it on up"

	aKey == #setScrollBarVisibility 
		ifTrue: [^self setScrollBarsFor: aParameter].
	self 
		downcastEvent: aKey
		with: aParameter
		from: anInitiator.
	super 
		upcastEvent: aKey
		with: aParameter
		from: anInitiator
		path: aPathCollection</body>
</methods>

<methods>
<class-id>TestSubcanvas2</class-id> <category>accessing</category>

<body package="Sparing Scrollbar Samples">client
	^Examples.TreeList2Example new</body>
</methods>

<methods>
<class-id>UI.WindowSpec</class-id> <category>decoration accessing</category>

<body package="Sparing Scrollbars">isSparingHorizontalScrollBar

	^self flags anyMask: 128</body>

<body package="Sparing Scrollbars">isSparingHorizontalScrollBar: aBoolean

	self flags: (aBoolean ifTrue: [self flags maskSet: 128] ifFalse: [self flags maskClear: 128])</body>

<body package="Sparing Scrollbars">isSparingVerticalScrollBar

	^self flags anyMask: 64</body>

<body package="Sparing Scrollbars">isSparingVerticalScrollBar: aBoolean

	self flags: (aBoolean ifTrue: [self flags maskSet: 64] ifFalse: [self flags maskClear: 64])</body>
</methods>

<methods>
<class-id>UI.WindowSpec</class-id> <category>private</category>

<body package="Sparing Scrollbars">scrollingFlags

	^self flags bitAnd: 2r11001011</body>
</methods>

<methods>
<class-id>UI.NamedSpec</class-id> <category>decoration accessing</category>

<body package="Sparing Scrollbars">isSparingHorizontalScrollBar

	^self flags anyMask: 128</body>

<body package="Sparing Scrollbars">isSparingHorizontalScrollBar: aBoolean

	self flags: (aBoolean ifTrue: [self flags maskSet: 128] ifFalse: [self flags maskClear: 128])</body>

<body package="Sparing Scrollbars">isSparingVerticalScrollBar

	^self flags anyMask: 64</body>

<body package="Sparing Scrollbars">isSparingVerticalScrollBar: aBoolean

	self flags: (aBoolean ifTrue: [self flags maskSet: 64] ifFalse: [self flags maskClear: 64])</body>
</methods>

<methods>
<class-id>UI.NamedSpec</class-id> <category>accessing</category>

<body package="Sparing Scrollbars">scrollingFlags

	^self flags bitAnd: 2r11001111</body>
</methods>

<methods>
<class-id>UI.ScrollWrapper</class-id> <category>testing</category>

<body package="Sparing Scrollbars">canScrollHorizontally

	^self scrollableExtent x &gt; self bounds extent x</body>

<body package="Sparing Scrollbars">canScrollVertically

	^self scrollableExtent y &gt; self bounds extent y</body>
</methods>

<methods>
<class-id>UI.ScrollWrapper</class-id> <category>private</category>

<body package="Sparing Scrollbars">changedPreferredBounds: oldPreferredBounds forComponent: aVisualComponent
	"The preferred bounds of aVisualComponent has changed from oldPreferredBounds.
	Pass the message up the hierarchy after translation."

	super changedPreferredBounds: oldPreferredBounds forComponent: aVisualComponent.
	self upcastEvent: #setScrollBarVisibility with: self.
	self updateControls</body>
</methods>

<methods>
<class-id>Tools.UIPainterTool</class-id> <category>aspects</category>

<body package="Sparing Scrollbars UIEdit">scrollConstructor
	^ScrollConstructor new on: specChannel</body>
</methods>

<methods>
<class-id>TestWindow class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Unlabeled Canvas' 
			#bounds: #(#{Graphics.Rectangle} 640 512 1030 917 ) 
			#flags: 195 ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.RegionSpec} 
					#layout: #(#{Graphics.Rectangle} 23 36 367 366 ) 
					#name: #Region1 
					#lineWidth: 1 ) ) ) )</body>
</methods>

<methods>
<class-id>ClassCommentEditor class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Class Comment Editor' 
			#bounds: #(#{Graphics.Rectangle} 640 512 997 776 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TextEditorSpec} 
					#layout: #(#{Graphics.LayoutFrame} 10 0 5 0.5 -10 1 -10 1 ) 
					#name: #TextEditor1 
					#flags: 207 
					#model: #'classSelectionHolder comment' 
					#tabRequiresControl: true 
					#isWrapped: false ) 
				#(#{UI.SequenceViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 10 0 49 0 -10 1 -5 0.5 ) 
					#name: #List1 
					#flags: 77 
					#model: #selectionSubclasses 
					#useModifierKeys: true 
					#selectionType: #highlight ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 53 18 ) 
					#name: #Label1 
					#label: 'Class' ) 
				#(#{UI.ComboBoxSpec} 
					#layout: #(#{Graphics.LayoutFrame} -77 0.5 17 0 65 0.5 40 0 ) 
					#name: #ComboBox1 
					#model: #classSelection 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#valueChangeSelector: #classSelected ) 
					#type: #object 
					#comboList: #classes ) ) ) )</body>
</methods>

<methods>
<class-id>Examples.TableLabelsExample class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Table row labels demo' 
			#min: #(#{Core.Point} 20 20 ) 
			#max: #(#{Core.Point} 1600 1200 ) 
			#bounds: #(#{Graphics.Rectangle} 301 512 1280 711 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TableViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 38 0.666666 6 0 -22 1 -41 1 ) 
					#name: #Table2 
					#flags: 207 
					#model: #tableInterface 
					#style: #large 
					#showHGrid: true 
					#showVGrid: true ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Graphics.LayoutOrigin} -45 0.5 -35 1 ) 
					#name: #Label1 
					#label: 'Pixel small' ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Graphics.LayoutOrigin} -194 0.333333 -35 1 ) 
					#name: #Label2 
					#label: 'Default' ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Graphics.LayoutOrigin} 125 0.666666 -36 1 ) 
					#name: #Label3 
					#label: 'Standard large' ) 
				#(#{UI.TableViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 22 0 4 0 -38 0.333333 -43 1 ) 
					#name: #Table3 
					#flags: 207 
					#model: #tableInterface 
					#showHGrid: true 
					#showVGrid: true ) 
				#(#{UI.TableViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 20 0.333333 4 0 -41 0.666666 -43 1 ) 
					#name: #Table1 
					#flags: 207 
					#model: #tableInterface 
					#style: #pixelSmall 
					#showHGrid: true 
					#showVGrid: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutSizedOrigin} 283 0 -31 1.0 81 23 ) 
					#name: #ActionButton1 
					#model: #printTables 
					#label: 'Print tables' 
					#defaultable: true ) ) ) )</body>
</methods>

<methods>
<class-id>Examples.TreeList1Example class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Class Hierarchy' 
			#bounds: #(#{Graphics.Rectangle} 640 512 999 842 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.HierarchicalViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 32 0 10 0 -32 1 -76 1 ) 
					#name: #treeListWidget 
					#flags: 207 
					#model: #treeList 
					#multipleSelections: false 
					#useModifierKeys: true 
					#selectionType: #highlight ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 32 272 122 300 ) 
					#model: #chooseNewClass 
					#label: 'New Root' 
					#defaultable: true ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.LayoutFrame} 137 0 271 0 -32 1 -28 1 ) 
					#model: #selection 
					#isReadOnly: true 
					#type: #object ) ) ) )</body>
</methods>

<methods>
<class-id>GIFImageViewer class</class-id> <category>resources</category>

<body package="Sparing Scrollbar Samples">gifFileMenu
	"Tools.MenuEditor new openOnClass: self andSelector: #gifFileMenu"

	&lt;resource: #menu&gt;
	^#(#{UI.Menu} #(
			#(#{UI.MenuItem} 
				#rawLabel: 'read Directory...' 
				#value: #readFromDirectory ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'read File...' 
				#value: #readFile ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Remove from list' 
				#enabled: false 
				#value: #removeSelection 
				#enablementSelector: #hasFileSelection ) ) #(3 ) nil ) decodeAsLiteralArray</body>
</methods>

<methods>
<class-id>GIFImageViewer class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'GIF Image Viewer' 
			#bounds: #(#{Graphics.Rectangle} 822 140 1650 818 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.ArbitraryComponentSpec} 
					#layout: #(#{Graphics.LayoutFrame} 130 0 10 0 -10 1 -10 1 ) 
					#name: #ViewHolder1 
					#flags: 203 
					#component: #imageWrapper ) 
				#(#{UI.SequenceViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 10 0 10 0 120 0 -10 1 ) 
					#name: #List1 
					#flags: 12 
					#model: #gifFiles 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#valueChangeSelector: #selectionUpdate ) 
					#menu: #gifFileMenu 
					#useModifierKeys: true 
					#selectionType: #highlight ) 
				#(#{UI.ResizingSplitterSpec} 
					#layout: #(#{Graphics.LayoutFrame} 122 0 10 0 128 0 -10 1 ) 
					#name: #ResizingSplitter1 
					#flags: 8 
					#horizontal: false 
					#minAboveSize: 30 
					#minBelowSize: 30 
					#aboveWidgets: 'List1' 
					#belowWidgets: 'ViewHolder1' ) ) ) )</body>
</methods>

<methods>
<class-id>TestSubcanvas1 class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Unlabeled Canvas' 
			#bounds: #(#{Graphics.Rectangle} 640 512 1003 734 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 10 0 10 0 -10 1 -10 1 ) 
					#name: #Subcanvas1 
					#flags: 203 
					#majorKey: #{Examples.TreeList2Example} 
					#minorKey: #windowSpec 
					#clientKey: #client ) ) ) )</body>
</methods>

<methods>
<class-id>Examples.SparingTable1Example class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Table1Example' 
			#bounds: #(#{Graphics.Rectangle} 720 450 1051 650 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TableViewSpec} 
					#layout: #(#{Graphics.Rectangle} 22 44 288 196 ) 
					#name: #Table1 
					#flags: 207 
					#model: #tableInterface 
					#showHGrid: true 
					#showVGrid: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 24 13 85 34 ) 
					#name: #ActionButton1 
					#model: #refreshTable 
					#label: 'Refresh' 
					#defaultable: true ) ) ) )</body>
</methods>

<methods>
<class-id>UI.ScrollConstructor class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 235 229 ) 
			#max: #(#{Core.Point} 256 333 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 896 845 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.GroupBoxSpec} 
					#layout: #(#{Graphics.LayoutFrame} 2 0 0 0 -2 1 64 0 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #ScrollBars 
						#defaultString: 'Scroll Bars' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 9 22 ) 
					#model: #'specChannel hasHorizontalScrollBar' 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#valueChangeSelector: #updateHorizontalScrollOption ) 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Horizontal 
						#defaultString: 'Horizontal' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 124 22 ) 
					#model: #'specChannel hasVerticalScrollBar' 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#valueChangeSelector: #updateVerticalScrollOption ) 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Vertical 
						#defaultString: 'Vertical' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 9 38 ) 
					#name: #SparingHorizontalCheckBox 
					#flags: 32 
					#model: #'specChannel isSparingHorizontalScrollBar' 
					#tabable: true 
					#helpText: 
					#(#{Kernel.UserMessage} 
						#key: #helpSparingHorizontal 
						#defaultString: 'Select for dynamic horizontal scrollbar' 
						#catalogID: #UIPainter ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #UseSparingly 
						#defaultString: 'Use Sparingly' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 124 38 ) 
					#name: #SparingVerticalCheckBox 
					#flags: 32 
					#model: #'specChannel isSparingVerticalScrollBar' 
					#tabable: true 
					#helpText: 
					#(#{Kernel.UserMessage} 
						#key: #helpSparingVertical 
						#defaultString: 'Select for dynamic vertical scrollbar' 
						#catalogID: #UIPainter ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #UseSparingly 
						#defaultString: 'Use Sparingly' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>Examples.SparingTable3Example class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Sparing Scrollbar Table Demo' 
			#min: #(#{Core.Point} 20 20 ) 
			#max: #(#{Core.Point} 800 600 ) 
			#bounds: #(#{Graphics.Rectangle} 720 450 1020 650 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TableViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 22 0 37 0 -22 1 -22 1 ) 
					#name: #Table3 
					#flags: 207 
					#model: #tableInterface 
					#showHGrid: true 
					#showVGrid: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 26 10 79 30 ) 
					#name: #ActionButton1 
					#model: #refreshTable 
					#label: 'Refresh' 
					#defaultable: true ) ) ) )</body>
</methods>

<methods>
<class-id>Examples.TreeList2Example class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Class Hierarchy' 
			#bounds: #(#{Graphics.Rectangle} 640 512 1197 839 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.HierarchicalViewSpec} 
					#layout: #(#{Graphics.Rectangle} 15 27 322 155 ) 
					#name: #treeListWidget 
					#flags: 207 
					#model: #treeList 
					#useModifierKeys: true 
					#selectionType: #highlight ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 457 28 547 56 ) 
					#model: #chooseNewClass 
					#label: 'New Root' 
					#defaultable: true ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 336 124 547 155 ) 
					#model: #selection 
					#isReadOnly: true 
					#type: #object ) 
				#(#{UI.TextEditorSpec} 
					#layout: #(#{Graphics.LayoutFrame} 15 0 161 0 -10 1 -10 1 ) 
					#flags: 77 
					#model: #classComment 
					#tabRequiresControl: true ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 333 95 ) 
					#label: 'Selection:' ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 335 33 ) 
					#label: 'Root:' ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 336 63 547 94 ) 
					#model: #rootClass 
					#isReadOnly: true 
					#type: #object ) ) ) )</body>
</methods>

<methods>
<class-id>TestSubcanvas2 class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbar Samples">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Unlabeled Canvas' 
			#bounds: #(#{Graphics.Rectangle} 640 512 1003 734 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 10 0 10 0 -10 1 -10 1 ) 
					#name: #Subcanvas1 
					#flags: 203 
					#majorKey: #{TestWindow} 
					#minorKey: #windowSpec 
					#clientKey: #client ) ) ) )</body>
</methods>

<methods>
<class-id>UI.TreeViewSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 235 229 ) 
			#max: #(#{Core.Point} 235 292 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 875 804 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.LabelSpec} 
					#properties: #(#{UI.PropertyListDictionary} #labelFromApplication true ) 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: #componentName ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 27 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #FontC 
						#defaultString: 'Font:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 55 0 26 0 -10 1 49 0 ) 
					#model: #style 
					#menu: #fontMenu ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 51 0 -3 1 125 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 118 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 135 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 152 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 170 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 188 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 205 ) 
					#model: #autoSelect 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #AutoSelectOnKeyNavigation 
						#defaultString: 'Auto Select on Key Navigation' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 223 ) 
					#model: #multipleSelections 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #MultiSelect 
						#defaultString: 'Multi Select' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 15 242 ) 
					#model: #fullLineSelect 
					#helpText: 
					#(#{Kernel.UserMessage} 
						#key: #GenKey28 
						#defaultString: 'Checked = Select From Container Left to Full Right. Unchecked = Select Only Text' 
						#catalogID: #UIPainter ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #WholeLineSelection 
						#defaultString: 'Whole Line Selection' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 170 261 220 284 ) 
					#model: #minimumHeight 
					#alignment: #right 
					#numChars: 3 
					#type: #number 
					#formatString: '###' ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 262 ) 
					#name: #Label1 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #MinimumElementHeight 
						#defaultString: 'Minimum Element Height:' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.ArbitraryComponentSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 294 201 ) 
			#max: #(#{Core.Point} 294 201 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 934 713 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 28 0 -3 1 102 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: #componentName ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 101 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 122 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 143 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.DataSetSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 204 83 ) 
			#max: #(#{Core.Point} 278 257 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 927 800 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.LabelSpec} 
					#layout: #(#{Graphics.LayoutOrigin} -40 0.5 3 0 ) 
					#label: #componentName ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 23 0 -3 1 97 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 96 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 115 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 134 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 153 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 172 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 191 ) 
					#model: #multipleSelections 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #MultipleSelections 
						#defaultString: 'Multiple Selections' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 210 ) 
					#model: #showVerticalLines 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #ShowVerticalLines 
						#defaultString: 'Show Vertical Lines' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 229 ) 
					#model: #showHorizontalLines 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #ShowHorizontalLines 
						#defaultString: 'Show Horizontal Lines' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 248 ) 
					#model: #showLineNumbers 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #ShowLineNumbers 
						#defaultString: 'Show Line Numbers' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.SequenceViewSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 235 229 ) 
			#max: #(#{Core.Point} 256 333 ) 
			#bounds: #(#{Graphics.Rectangle} 980 505 1236 838 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 55 0 28 0 -10 1 52 0 ) 
					#name: #fontMenu 
					#model: #style 
					#menu: #fontMenu ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 51 0 -3 1 125 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: #componentName ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 28 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #FontC 
						#defaultString: 'Font:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 270 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #SelectionType 
						#defaultString: 'Selection Type:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 120 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 138 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 156 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 174 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 192 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 210 ) 
					#model: #multipleSelections 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #MultiSelect 
						#defaultString: 'Multi Select' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 228 ) 
					#model: #useModifierKeys 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #GenKey20 
						#defaultString: 'Use Modifier Keys For Multi Select' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 17 246 ) 
					#model: #autoSelect 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #AutoSelectOnKeyNavigation 
						#defaultString: 'Auto Select on Key Navigation' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 115 0 268 0 -10 1 292 0 ) 
					#model: #selectionType 
					#menu: #selectionTypeMenu ) ) ) )</body>
</methods>

<methods>
<class-id>UI.TextEditorSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 236 293 ) 
			#max: #(#{Core.Point} 240 293 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 880 805 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 23 0 -3 1 97 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: #componentName ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 125 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #AlignC 
						#defaultString: 'Align:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 98 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #FontC 
						#defaultString: 'Font:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 86 0 96 0 -10 1 120 0 ) 
					#model: #style 
					#menu: #fontMenu ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 86 0 124 0 -10 1 148 0 ) 
					#model: #alignment 
					#menu: #alignmentMenu ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 150 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 169 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 188 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 92 188 ) 
					#model: #tabRequiresControl 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #TabRequiresControlKey 
						#defaultString: 'Tab Requires Control Key' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 207 ) 
					#model: #isReadOnly 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #ReadOnly 
						#defaultString: 'Read Only' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 226 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 245 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 264 ) 
					#model: #isWrapped 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #WordWrap 
						#defaultString: 'Word Wrap' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.TableViewSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 
			#(#{Kernel.UserMessage} 
				#key: #UnlabeledCanvas 
				#defaultString: 'Unlabeled Canvas' 
				#catalogID: #UIPainter ) 
			#min: #(#{Core.Point} 261 294 ) 
			#max: #(#{Core.Point} 261 294 ) 
			#bounds: #(#{Graphics.Rectangle} 640 513 901 807 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Table 
						#defaultString: 'Table' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 10 0 55 0 0 1 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #FontC 
						#defaultString: 'Font:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 85 0 33 0 -11 1 55 0 ) 
					#model: #style 
					#menu: #fontMenu ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 51 0 -3 1 125 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 137 ) 
					#model: #showHGrid 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Horizontal 
						#defaultString: 'Horizontal' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 130 137 ) 
					#model: #showVGrid 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Vertical 
						#defaultString: 'Vertical' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.GroupBoxSpec} 
					#layout: #(#{Graphics.LayoutFrame} 5 0 118 0 -5 1 168 0 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #GridLines 
						#defaultString: 'Grid Lines' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 170 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 192 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 214 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 236 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 258 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.RadioButtonSpec} 
					#layout: #(#{Core.Point} 166 194 ) 
					#model: #selectionStyle 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Cell 
						#defaultString: 'Cell' 
						#catalogID: #UIPainter ) 
					#select: #element ) 
				#(#{UI.RadioButtonSpec} 
					#layout: #(#{Core.Point} 166 219 ) 
					#model: #selectionStyle 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Row 
						#defaultString: 'Row' 
						#catalogID: #UIPainter ) 
					#select: #row ) 
				#(#{UI.RadioButtonSpec} 
					#layout: #(#{Core.Point} 166 244 ) 
					#model: #selectionStyle 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Column 
						#defaultString: 'Column' 
						#catalogID: #UIPainter ) 
					#select: #column ) 
				#(#{UI.GroupBoxSpec} 
					#layout: #(#{Graphics.LayoutFrame} 148 0 170 0 -5 1 277 0 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Selection 
						#defaultString: 'Selection' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.HierarchicalViewSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 235 229 ) 
			#max: #(#{Core.Point} 256 333 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 896 845 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 10 21 ) 
					#name: #Label2 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #FontC 
						#defaultString: 'Font:' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 -1 0 0.5 0 ) 
					#name: #Label1 
					#label: #componentName ) 
				#(#{UI.MenuButtonSpec} 
					#layout: #(#{Graphics.LayoutFrame} 55 0 22 0 -10 1 46 0 ) 
					#name: #fontMenu 
					#model: #style 
					#menu: #fontMenu ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 48 0 -3 1 122 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 115 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 133 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 151 ) 
					#model: #tabable 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #CanTab 
						#defaultString: 'Can Tab' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 169 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 187 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 205 ) 
					#model: #autoSelect 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #AutoSelectOnKeyNavigation 
						#defaultString: 'Auto Select on Key Navigation' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CompositeSpecCollection} 
					#collection: #(
						#(#{UI.LabelSpec} 
							#layout: #(#{Core.Point} 0 0 ) 
							#label: 
							#(#{Kernel.UserMessage} 
								#key: #MinimumItemHeight 
								#defaultString: 'Minimum Item Height:' 
								#catalogID: #UIPainter ) ) 
						#(#{UI.InputFieldSpec} 
							#layout: #(#{Graphics.LayoutFrame} 135 0 0 0 0 1.0 24 0 ) 
							#model: #minimumHeight 
							#alignment: #right 
							#numChars: 3 
							#type: #number 
							#formatString: '###' ) ) 
					#compositeSpec: 
					#(#{UI.CompositeSpec} 
						#layout: #(#{Graphics.Rectangle} 10 229 240 257 ) 
						#name: #Composite1 ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.SubCanvasSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 
			#(#{Kernel.UserMessage} 
				#key: #UnlabeledCanvas 
				#defaultString: 'Unlabeled Canvas' 
				#catalogID: #UIPainter ) 
			#min: #(#{Core.Point} 237 219 ) 
			#bounds: #(#{Graphics.Rectangle} 650 515 952 832 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 28 0 -3 1 102 0 ) 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: #componentName ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 103 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 124 ) 
					#model: #isOpaque 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Opaque 
						#defaultString: 'Opaque' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 145 ) 
					#model: #initiallyDisabled 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyDisabled 
						#defaultString: 'Initially Disabled' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 13 166 ) 
					#model: #initiallyInvisible 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #InitiallyInvisible 
						#defaultString: 'Initially Invisible' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<methods>
<class-id>UI.WindowSpec class</class-id> <category>interface specs</category>

<body package="Sparing Scrollbars UIEdit">detailsEditSpec
	"Tools.UIPainter new openOnClass: self andSelector: #detailsEditSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: ' ' 
			#min: #(#{Core.Point} 300 222 ) 
			#max: #(#{Core.Point} 300 222 ) 
			#bounds: #(#{Graphics.Rectangle} 640 512 940 734 ) ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 3 0 27 0 -3 1 101 0 ) 
					#name: #Subcanvas2 
					#flags: 0 
					#majorKey: #{UI.ScrollConstructor} 
					#minorKey: #windowSpec 
					#clientKey: #scrollConstructor ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{UI.AlignmentOrigin} 0 0.5 4 0 0.5 0 ) 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Window 
						#defaultString: 'Window' 
						#catalogID: #UIPainter ) ) 
				#(#{UI.CheckBoxSpec} 
					#layout: #(#{Core.Point} 12 102 ) 
					#model: #hasBorder 
					#tabable: true 
					#label: 
					#(#{Kernel.UserMessage} 
						#key: #Bordered 
						#defaultString: 'Bordered' 
						#catalogID: #UIPainter ) ) ) ) )</body>
</methods>

<do-it>"Imported Classes:"</do-it>

<do-it>self error: 'Attempting to file-in parcel imports.  Choose terminate or close'</do-it>

<class>
<name>ApplicationModel</name>
<environment>UI</environment>
<super>UI.Model</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>builder uiSession eventHandlers </inst-vars>
<class-inst-vars>savedWindowInformation </class-inst-vars>
<imports></imports>
<category>UIBuilder-Framework</category>
<attributes>
<package>UIBuilder-Framework</package>
</attributes>
</class>

<class>
<name>NamedSpec</name>
<environment>UI</environment>
<super>UI.ComponentSpec</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>name flags isOpaque colors </inst-vars>
<class-inst-vars>paletteIcon </class-inst-vars>
<imports></imports>
<category>UIBuilder-Specifications</category>
<attributes>
<package>UIBuilder-Specifications</package>
</attributes>
</class>

<class>
<name>WindowSpec</name>
<environment>UI</environment>
<super>UI.UISpecification</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>model label min max bounds flags menu toolBar performer colors pushMode pushOn pushAspect dynamism backgroundPattern defineFontLoadingMethod namedFontFileOutType savedFontFileName </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>UIBuilder-Specifications</category>
<attributes>
<package>UIBuilder-Specifications</package>
</attributes>
</class>

<class>
<name>UIPainterTool</name>
<environment>Tools</environment>
<super>Tools.UIPainterWatcher</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>selection selectionKind controller currentSpecCopy currentSpecBindings specChannel subBuilder lock slice lastSlice slicesMenu sliceInfo client statusBarText list sliceChanging sliceTabChanging canvasTree menuBar currentView </inst-vars>
<class-inst-vars></class-inst-vars>
<imports>
			private Smalltalk.TextConstants.*
			</imports>
<category>UIPainter-Tools</category>
<attributes>
<package>UIPainter</package>
</attributes>
</class>

<class>
<name>CompositePart</name>
<environment>Graphics</environment>
<super>Graphics.VisualPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>components preferredBounds </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Graphics-Visual Objects</category>
<attributes>
<package>Graphics-Visual Objects</package>
</attributes>
</class>

<class>
<name>ScrollWrapper</name>
<environment>UI</environment>
<super>Graphics.TranslatingWrapper</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>dependents preferredBoundsBlock </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Interface-Support</category>
<attributes>
<package>Interface-Support</package>
</attributes>
</class>

</st-source>
