Model subclass: #Spreadsheet
instanceVariableNames: 'value sheetType '
classVariableNames: ''
poolDictionaries: ''
category: 'SpreadSheets'!
!Spreadsheet methodsFor: 'accessing'!
sheetType
"Return my sheetType"
^sheetType.!
sheetType: aType
"Set the sheetType to aType"
sheetType := aType.! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
Spreadsheet class
instanceVariableNames: ''!
!Spreadsheet class methodsFor: 'demos'!
demo
| ss1 ss2 ss3 ss4 ssArray|
ss1 := Spreadsheet type: #sum.
ss1 cell: 1 put: 15. "Puts 15 into cell 1"
ss1 cell: 2 put: 30.
ss1 cell: 3 put: 75.2.
Transcript cr; show: ss1 value printString. "Prints the sum (120.2) to the Transcript"
Transcript cr; show: (ss1 cell: 1) printString. "Prints 15 to the Transcript"
ss2 := Spreadsheet type: #average.
ss2 cells: #(24 76.4 19 37 89). "Fill five cells of the spreadsheets with these values"
Transcript cr; show: ss2 value printString. "Prints the average (49.08) to the Transcript"
"Create a spreadsheet that sums the values of two Spreadsheets"
ssArray := Array with: ss1 with: ss2.
ss3 := Spreadsheet type: #sum with: ssArray.
Transcript cr; show: ss3 value printString. "Prints the sum 120.2 + 49.08 to the Transcript"
ss1 cell: 4 put: 89.9. "Add a fourth cell to ss1."
Transcript cr; show: ss3 value printString. "Prints the updated values of ss1 and ss2"
"Create a fourth spreadsheet whose value is the average of ss1 cell 2 and ss2 cell 3"
ss4 := Spreadsheet type: #average with: ss1 cell: 2 with: ss2 cell: 3.
Transcript cr; show: ss4 value printString. "Prints the average of 30 and 19 (24.5)"! !
!Spreadsheet class methodsFor: 'instance-creation'!
type: aType
"Call CellSheet with aType. Return what it returns"
^CellSheet type: aType.!
type: aType with: anArray
"Call SpreadsheetSumSheet with aType and anArray. Return what it returns"
^SpreadsheetSumSheet type: aType with: anArray.!
type: aType with: sheet1 cell: cell1 with: sheet2 cell: cell2
"Call CellAverageSheet with aType sheet1, cell1, sheet2, cell2.
Return what it returns"
^CellAverageSheet type: aType with: sheet1 cell: cell1 with: sheet2 cell: cell2.! !
Spreadsheet subclass: #SpreadsheetSumSheet
instanceVariableNames: 'sheets '
classVariableNames: ''
poolDictionaries: ''
category: 'SpreadSheets'!
!SpreadsheetSumSheet methodsFor: 'accessing'!
update: anAspect
"Recalculate my value when I receive the message #value"
( anAspect == #value )
ifTrue: [ self calculate ].!
value
"Return my value"
^value.!
value: aValue
"Set my value to aValue. Announce change of value to my dependents"
value := aValue.
self changed: #value.! !
!SpreadsheetSumSheet methodsFor: 'initialize-release'!
with: anArray
"Add all the sheets in anArray to sheets, notify each sheet of my dependence
calculate my value"
sheets := OrderedCollection new.
anArray do:
[ :each | sheets add: each.
each addDependent: self ].
self calculate.! !
!SpreadsheetSumSheet methodsFor: 'enumerating'!
calculate
"calculate my value, sum the values of all spreadsheets"
| total |
total := 0.
sheets do: [ :each | total := total + each value ].
self value: total.! !
!SpreadsheetSumSheet methodsFor: 'view access'!
cellCollection
"Return the values of each of the spreadsheets"
^sheets collect: [ :each | each value ].! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
SpreadsheetSumSheet class
instanceVariableNames: ''!
!SpreadsheetSumSheet class methodsFor: 'instance-creation'!
type: aType with: anArray
"Create a new one of me, initialize it, set my type, open a window for myself, return myself"
| aSheet |
aSheet := super new with: anArray.
aSheet sheetType: aType.
SpreadsheetViewContainer new openOn: aSheet labeled: aType.
^aSheet.! !
Spreadsheet subclass: #CellAverageSheet
instanceVariableNames: 'cells '
classVariableNames: ''
poolDictionaries: ''
category: 'SpreadSheets'!
!CellAverageSheet methodsFor: 'initialize-release'!
with: sheet1 cell: cell1 with: sheet2 cell: cell2
"Add cell1 & cell2 to cells, notify each cell of my dependence, calculate my value"
cells := OrderedCollection new.
cells add: (sheet1 aCell: cell1).
( sheet1 aCell: cell1 ) addDependent: self.
cells add: (sheet2 aCell: cell2).
( sheet2 aCell: cell2 ) addDependent: self.
self calculate.! !
!CellAverageSheet methodsFor: 'testing'!
size
"Return the size of collection cells"
^cells size.! !
!CellAverageSheet methodsFor: 'enumerating'!
calculate
"calculate my value, total the values of all the cells, find their average"
| total |
total := 0.
cells do: [ :each | total := total + each value ].
self value: total / self size.! !
!CellAverageSheet methodsFor: 'accessing'!
update: anAspect
"Recalculate my value when I receive the message #value"
( anAspect == #value )
ifTrue: [ self calculate ].!
value
"Return my value as a float"
^value asFloat.!
value: aValue
"Set my value to aValue. Announce change of value to my dependents"
value := aValue.
self changed: #value.! !
!CellAverageSheet methodsFor: 'view access'!
cellCollection
"Return the values of each of the cells"
^cells collect: [ :each | each value ].! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
CellAverageSheet class
instanceVariableNames: ''!
!CellAverageSheet class methodsFor: 'instance-creation'!
type: aType with: sheet1 cell: cell1 with: sheet2 cell: cell2
"Create a new one of me, initialize it, set my type, open a window for myself, return myself"
| aSheet |
aSheet := super new with: sheet1 cell: cell1 with: sheet2 cell: cell2.
aSheet sheetType: aType.
SpreadsheetViewContainer new openOn: aSheet labeled: aType.
^aSheet.! !
ModelValueViewContainer subclass: #SpreadsheetViewContainer
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Model Views'!
!SpreadsheetViewContainer methodsFor: 'view creation'!
buildViewOn: aSpreadsheet
"Build a window for aSpreadsheet with the following ViewOn"
self addCellListViewOn: aSpreadsheet.
self addValueViewOn: aSpreadsheet.
self addTypeViewOn: aSpreadsheet.!
makeListOn: aSpreadsheet showing: getListMsg updateFor: aspect
"Make a list with the following properties for aSpreadsheet"
| listView |
listView := SelectionInListView
on: aSpreadsheet
printItems: true
oneItem: false
aspect: aspect
change: nil
list: getListMsg
menu: nil
initialSelection: nil
useIndex: true.
^listView.! !
!SpreadsheetViewContainer methodsFor: 'view layout'!
addCellListViewOn: aSpreadsheet
"Add a ViewOn that displays the value of the Spreadsheet"
| itemView listArea |
itemView := self
makeListOn: aSpreadsheet
showing: #cellCollection
updateFor: #value.
listArea := self constraintFrame: 0 @ (1/10) corner: 1 @ (9/10).
self addListView: itemView in: listArea.
^itemView.!
addListView: listView in: area
"Create a wrapper with scroll bars"
| wrapper |
wrapper := BorderDecorator on: listView.
self add: wrapper in: area.!
addTypeViewOn: aSpreadsheet
"Add a ViewOn that displays the sheetType of the Spreadsheet"
| itemView itemArea |
itemView := self makeDisplayBoxOn: aSpreadsheet for: #sheetType.
itemArea := self constraintFrame: 0 @ 0 corner: 1 @ (1/10).
self addView: itemView in: itemArea.!
addValueViewOn: aSpreadsheet
"Add a ViewOn that displays the values of each Spreadsheet cell in a list"
| itemView itemArea |
itemView := self makeDisplayBoxOn: aSpreadsheet for: #value.
itemArea := self constraintFrame: 0 @ (9/10) corner: 1 @ 1.
self addView: itemView in: itemArea.! !