The Trunk: Morphic-bf.753.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Morphic-bf.753.mcz

commits-2
Bert Freudenberg uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-bf.753.mcz

==================== Summary ====================

Name: Morphic-bf.753
Author: bf
Time: 8 December 2014, 1:52:24.579 am
UUID: 6e72a684-dce4-4de0-a012-cf80ce30a3eb
Ancestors: Morphic-eem.752

Restore timestamps lost in assignment conversion.

=============== Diff against Morphic-eem.752 ===============

Item was changed:
  ----- Method: AbstractSound class>>updateScorePlayers (in category '*Morphic-Sounds-sound library-file in/out') -----
  updateScorePlayers
  | soundsBeingEdited |
  "Force all ScorePlayers to update their instrument list from the sound library. This may done after loading, unloading, or replacing a sound to make all ScorePlayers feel the change."
 
  ScorePlayer allSubInstancesDo:
  [:p | p pause].
  SoundPlayer shutDown.
  soundsBeingEdited := EnvelopeEditorMorph allSubInstances collect: [:ed | ed soundBeingEdited].
  ScorePlayerMorph allSubInstancesDo:
  [:p | p updateInstrumentsFromLibraryExcept: soundsBeingEdited].
  !

Item was changed:
  ----- Method: MIDIFileReader class>>playURLNamed: (in category '*Morphic-Sounds') -----
  playURLNamed: urlString
 
  | titleString |
  titleString := urlString
  copyFrom: (urlString findLast: [:c | c=$/]) + 1
  to: urlString size.
  ScorePlayerMorph
  openOn: (self scoreFromURL: urlString)
  title: titleString.
  !

Item was changed:
  ----- Method: Morph>>justDroppedIntoPianoRoll:event: (in category '*Morphic-Sound-piano rolls') -----
  justDroppedIntoPianoRoll: pianoRoll event: evt
 
  | ambientEvent startTimeInScore |
  startTimeInScore := pianoRoll timeForX: self left.
 
  ambientEvent := AmbientEvent new
  morph: self;
  time: startTimeInScore.
 
  pianoRoll score addAmbientEvent: ambientEvent.
 
  "self endTime > pianoRoll scorePlayer durationInTicks ifTrue:
  [pianoRoll scorePlayer updateDuration]"
  !

Item was changed:
  ----- Method: Morph>>privateExtension: (in category 'accessing - extension') -----
  privateExtension: aMorphExtension
  "private - change the receiver's extension"
  extension := aMorphExtension!

Item was changed:
  ----- Method: Morph>>triggerActionFromPianoRoll (in category '*Morphic-Sound-piano rolls') -----
  triggerActionFromPianoRoll
 
  | evt |
  "a hack to allow for abitrary morphs to be dropped into piano roll"
  self world ifNil: [^self].
  evt := MouseEvent new setType: nil position: self center buttons: 0 hand: self world activeHand.
  self programmedMouseUp: evt for: self.
 
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>deselect (in category 'selecting') -----
  deselect
 
  selected ifFalse: [^ self].
  self changed.
  selected := false.
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>editPitch: (in category 'editing') -----
  editPitch: evt
 
  | mk note |
  mk := owner midiKeyForY: evt cursorPoint y.
  note := (owner score tracks at: trackIndex) at: indexInTrack.
  note midiKey = mk ifTrue: [^ self].
  note midiKey: mk.
  self playSound: (self soundOfDuration: 999.0).
  self position: self position x @ ((owner yForMidiKey: mk) - 1)
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>invokeNoteMenu: (in category 'menu') -----
  invokeNoteMenu: evt
  "Invoke the note's edit menu."
 
  | menu |
  menu := MenuMorph new defaultTarget: self.
  menu addList:
  #(('grid to next quarter' gridToNextQuarter)
  ('grid to prev quarter' gridToPrevQuarter)).
 
  menu popUpEvent: evt in: self world.
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>mouseDown: (in category 'event handling') -----
  mouseDown: evt
 
  hitLoc := evt cursorPoint.
  editMode := nil.
  owner submorphsDo:
  [:m | (m isKindOf: PianoRollNoteMorph) ifTrue: [m deselect]].
  selected := true.
  self changed.
  owner selection: (Array with: trackIndex with: indexInTrack with: indexInTrack).
  self playSound!

Item was changed:
  ----- Method: PianoRollNoteMorph>>noteOfDuration: (in category 'note playing') -----
  noteOfDuration: duration
 
  | note |
  note := self noteInScore.
  ^ (owner scorePlayer instrumentForTrack: trackIndex)
  soundForMidiKey: note midiKey
  dur: duration
  loudness: (note velocity asFloat / 127.0)
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>playSound: (in category 'note playing') -----
  playSound: aSoundOrNil
 
  SoundPlaying ifNotNil: [SoundPlaying stopGracefully].
  SoundPlaying := aSoundOrNil.
  SoundPlaying ifNotNil: [SoundPlaying play].!

Item was changed:
  ----- Method: PianoRollNoteMorph>>select (in category 'selecting') -----
  select
 
  selected ifTrue: [^ self].
  selected := true.
  self changed!

Item was changed:
  ----- Method: PianoRollNoteMorph>>selectNotes: (in category 'selecting') -----
  selectNotes: evt
 
  | lastMorph oldEnd saveOwner |
  saveOwner := owner.
  (owner autoScrollForX: evt cursorPoint x) ifTrue:
  ["If scroll talkes place I will be deleted and my x-pos will become invalid."
  owner := saveOwner.
  bounds := bounds withLeft: (owner xForTime: self noteInScore time)].
  oldEnd := owner selection last.
  (owner notesInRect: (evt cursorPoint x @ owner top corner: owner bottomRight))
  do: [:m | m trackIndex = trackIndex ifTrue: [m deselect]].
  self select.  lastMorph := self.
  (owner notesInRect: (self left @ owner top corner: evt cursorPoint x @ owner bottom))
  do: [:m | m trackIndex = trackIndex ifTrue: [m select.  lastMorph := m]].
  owner selection: (Array with: trackIndex with: indexInTrack with: lastMorph indexInTrack).
  lastMorph indexInTrack ~= oldEnd ifTrue:
  ["Play last note as selection grows or shrinks"
  owner ifNotNil: [lastMorph playSound]]
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>soundOfDuration: (in category 'note playing') -----
  soundOfDuration: duration
 
  | sound |
  sound := MixedSound new.
  sound add: (self noteOfDuration: duration)
  pan: (owner scorePlayer panForTrack: trackIndex)
  volume: owner scorePlayer overallVolume *
  (owner scorePlayer volumeForTrack: trackIndex).
  ^ sound reset
  !

Item was changed:
  ----- Method: PianoRollNoteMorph>>trackIndex:indexInTrack: (in category 'initialization') -----
  trackIndex: ti indexInTrack: i
 
  trackIndex := ti.
  indexInTrack := i.
  selected := false!

Item was changed:
  ----- Method: ScorePlayerMorph class>>onMIDIFileNamed: (in category 'system hookup') -----
  onMIDIFileNamed: fileName
  "Return a ScorePlayerMorph on the score from the MIDI file of the given name."
 
  | score player |
  score := MIDIFileReader scoreFromFileNamed: fileName .
  player := ScorePlayer onScore: score.
  ^ self new onScorePlayer: player title: fileName
  !

Item was changed:
  ----- Method: ScorePlayerMorph class>>openOn:title: (in category 'system hookup') -----
  openOn: aScore title: aString
 
  | player |
  player := ScorePlayer onScore: aScore.
  (self new onScorePlayer: player title: aString) openInWorld.
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>closeMIDIPort (in category 'initialization') -----
  closeMIDIPort
 
  scorePlayer closeMIDIPort.
  LastMIDIPort := nil.
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>invokeMenu (in category 'menu') -----
  invokeMenu
  "Invoke a menu of additonal functions for this ScorePlayer."
 
  | aMenu |
  aMenu := MenuMorph new defaultTarget: self.
  aMenu add: 'open a MIDI file' translated action: #openMIDIFile.
  aMenu addList: {
  #-.
  {'save as AIFF file' translated. #saveAsAIFF}.
  {'save as WAV file' translated. #saveAsWAV}.
  {'save as Sun AU file' translated. #saveAsSunAudio}.
  #-}.
  aMenu add: 'reload instruments' translated target: AbstractSound selector: #updateScorePlayers.
  aMenu addLine.
  scorePlayer midiPort
  ifNil: [
  aMenu add: 'play via MIDI' translated action: #openMIDIPort]
  ifNotNil: [
  aMenu add: 'play via built in synth' translated action: #closeMIDIPort.
  aMenu add: 'new MIDI controller' translated action: #makeMIDIController:].
  aMenu addLine.
  aMenu add: 'make a pause marker' translated action: #makeAPauseEvent:.
 
  aMenu popUpInWorld: self world.
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>makeAPauseEvent: (in category 'menu') -----
  makeAPauseEvent: evt
 
  | newWidget |
 
  newWidget := AlignmentMorph newRow.
  newWidget
  color: Color orange;
  borderWidth: 0;
  layoutInset: 0;
  hResizing: #shrinkWrap;
  vResizing: #shrinkWrap;
  extent: 5@5;
  addMorph: (StringMorph contents: '[pause]' translated) lock;
  addMouseUpActionWith: (
  MessageSend receiver: self selector: #showResumeButtonInTheWorld
  ).
 
  evt hand attachMorph: newWidget.!

Item was changed:
  ----- Method: ScorePlayerMorph>>makeControls (in category 'layout') -----
  makeControls
 
  | bb r reverbSwitch repeatSwitch |
  r := AlignmentMorph newRow.
  r color: color; borderWidth: 0; layoutInset: 0.
  r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
  bb := SimpleButtonMorph new target: self; borderColor: #raised;
  borderWidth: 2; color: color.
  r addMorphBack: (bb label: '<>'; actWhen: #buttonDown;
  actionSelector: #invokeMenu).
  bb := SimpleButtonMorph new target: self; borderColor: #raised;
  borderWidth: 2; color: color.
  r addMorphBack: (bb label: 'Piano Roll' translated; actionSelector: #makePianoRoll).
  bb := SimpleButtonMorph new target: self; borderColor: #raised;
  borderWidth: 2; color: color.
  r addMorphBack: (bb label: 'Rewind' translated; actionSelector: #rewind).
  bb := SimpleButtonMorph new target: scorePlayer; borderColor: #raised;
  borderWidth: 2; color: color.
  r addMorphBack: (bb label: 'Play' translated; actionSelector: #resumePlaying).
  bb := SimpleButtonMorph new target: scorePlayer; borderColor: #raised;
  borderWidth: 2; color: color.
  r addMorphBack: (bb label: 'Pause' translated; actionSelector: #pause).
  reverbSwitch := SimpleSwitchMorph new
  offColor: color;
  onColor: (Color r: 1.0 g: 0.6 b: 0.6);
  borderWidth: 2;
  label: 'Reverb Disable' translated;
  actionSelector: #disableReverb:;
  target: scorePlayer;
  setSwitchState: SoundPlayer isReverbOn not.
  r addMorphBack: reverbSwitch.
  scorePlayer ifNotNil:
  [repeatSwitch := SimpleSwitchMorph new
  offColor: color;
  onColor: (Color r: 1.0 g: 0.6 b: 0.6);
  borderWidth: 2;
  label: 'Repeat' translated;
  actionSelector: #repeat:;
  target: scorePlayer;
  setSwitchState: scorePlayer repeat.
  r addMorphBack: repeatSwitch].
  ^ r
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>makePianoRoll (in category 'layout') -----
  makePianoRoll
  "Create a piano roll viewer for this score player."
 
  | pianoRoll hand |
  pianoRoll := PianoRollScoreMorph new on: scorePlayer.
  hand := self world activeHand.
  hand ifNil: [self world addMorph: pianoRoll]
  ifNotNil: [hand attachMorph: pianoRoll.
  hand lastEvent shiftPressed ifTrue:
  ["Special case for NOBM demo"
  pianoRoll contractTime; contractTime; enableDragNDrop]].
  pianoRoll startStepping.
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>onScorePlayer:title: (in category 'initialization') -----
  onScorePlayer: aScorePlayer title: scoreName
  | divider col r |
  scorePlayer := aScorePlayer.
  scorePlayer ifNotNil:
  [scorePlayer  reset.
  instrumentSelector := Array new: scorePlayer score tracks size].
 
  self removeAllMorphs.
  self addMorphBack: self makeControls.
  scorePlayer ifNil: [^ self].
 
  r := self makeRow
  hResizing: #shrinkWrap;
  vResizing: #shrinkWrap.
  r addMorphBack: self rateControl;
  addMorphBack: (Morph newBounds: (0@0 extent: 20@0) color: Color transparent);
  addMorphBack: self volumeControl.
  self addMorphBack: r.
  self addMorphBack: self scrollControl.
 
  col := AlignmentMorph newColumn color: color; layoutInset: 0.
  self addMorphBack: col.
  1 to: scorePlayer trackCount do: [:trackIndex |
  divider := AlignmentMorph new
  extent: 10@1;
  borderWidth: 1;
  layoutInset: 0;
  borderColor: #raised;
  color: color;
  hResizing: #spaceFill;
  vResizing: #rigid.
  col addMorphBack: divider.
  col addMorphBack: (self trackControlsFor: trackIndex)].
 
  LastMIDIPort ifNotNil: [
  "use the most recently set MIDI port"
  scorePlayer openMIDIPort: LastMIDIPort].
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>openMIDIFile (in category 'initialization') -----
  openMIDIFile
  "Open a MIDI score and re-init controls..."
  | score fileName f player |
  fileName := Utilities chooseFileWithSuffixFromList: #('.mid' '.midi')
  withCaption: 'Choose a MIDI file to open' translated.
  (fileName isNil or: [ fileName == #none ])
  ifTrue: [^ self inform: 'No .mid/.midi files found in the Squeak directory' translated].
  f := FileStream readOnlyFileNamed: fileName.
  score := (MIDIFileReader new readMIDIFrom: f binary) asScore.
  f close.
  player := ScorePlayer onScore: score.
  self onScorePlayer: player title: fileName!

Item was changed:
  ----- Method: ScorePlayerMorph>>openMIDIPort (in category 'initialization') -----
  openMIDIPort
 
  | portNum |
  portNum := SimpleMIDIPort outputPortNumFromUser.
  portNum ifNil: [^ self].
  scorePlayer openMIDIPort: portNum.
  LastMIDIPort := portNum.
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>panAndVolControlsFor: (in category 'layout') -----
  panAndVolControlsFor: trackIndex
 
  | volSlider panSlider c r middleLine pianoRollColor |
  pianoRollColor := (Color wheel: scorePlayer score tracks size) at: trackIndex.
  volSlider := SimpleSliderMorph new
  color: color;
  sliderColor: pianoRollColor;
  extent: 101@2;
  target: scorePlayer;
  arguments: (Array with: trackIndex);
  actionSelector: #volumeForTrack:put:;
  minVal: 0.0;
  maxVal: 1.0;
  adjustToValue: (scorePlayer volumeForTrack: trackIndex).
  panSlider := SimpleSliderMorph new
  color: color;
  sliderColor: pianoRollColor;
  extent: 101@2;
  target: scorePlayer;
  arguments: (Array with: trackIndex);
  actionSelector: #panForTrack:put:;
  minVal: 0.0;
  maxVal: 1.0;
  adjustToValue: (scorePlayer panForTrack: trackIndex).
  c := AlignmentMorph newColumn
  color: color;
  layoutInset: 0;
  wrapCentering: #center; cellPositioning: #topCenter;
  hResizing: #spaceFill;
  vResizing: #shrinkWrap.
  middleLine := Morph new  "center indicator for pan slider"
  color: (Color r: 0.4 g: 0.4 b: 0.4);
  extent: 1@(panSlider height - 4);
  position: panSlider center x@(panSlider top + 2).
  panSlider addMorphBack: middleLine.
  r := self makeRow.
  r addMorphBack: (StringMorph contents: '0').
  r addMorphBack: volSlider.
  r addMorphBack: (StringMorph contents: '10').
  c addMorphBack: r.
  r := self makeRow.
  r addMorphBack: (StringMorph contents: 'L' translated).
  r addMorphBack: panSlider.
  r addMorphBack: (StringMorph contents: 'R' translated).
  c addMorphBack: r.
  ^ c
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>rateControl (in category 'layout') -----
  rateControl
 
  | rateSlider middleLine r |
  rateSlider := SimpleSliderMorph new
  color: color;
  sliderColor: Color gray;
  extent: 180@2;
  target: self;
  actionSelector: #setLogRate:;
  minVal: -1.0;
  maxVal: 1.0;
  adjustToValue: 0.0.
  middleLine := Morph new  "center indicator for pan slider"
  color: (Color r: 0.4 g: 0.4 b: 0.4);
  extent: 1@(rateSlider height - 4);
  position: rateSlider center x@(rateSlider top + 2).
  rateSlider addMorphBack: middleLine.
  r := self makeRow
  hResizing: #shrinkWrap;
  vResizing: #rigid;
  height: 24.
  r addMorphBack: (StringMorph contents: 'slow ' translated).
  r addMorphBack: rateSlider.
  r addMorphBack: (StringMorph contents: ' fast' translated).
  ^ r
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>scrollControl (in category 'layout') -----
  scrollControl
 
  | r |
  scrollSlider := SimpleSliderMorph new
  color: color;
  sliderColor: Color gray;
  extent: 360@2;
  target: scorePlayer;
  actionSelector: #positionInScore:;
  adjustToValue: scorePlayer positionInScore.
  r := self makeRow
  hResizing: #shrinkWrap;
  vResizing: #rigid;
  height: 24.
  r addMorphBack: (StringMorph contents: 'start ' translated).
  r addMorphBack: scrollSlider.
  r addMorphBack: (StringMorph contents: ' end' translated).
  ^ r
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>standaloneResumeButton (in category 'layout') -----
  standaloneResumeButton
 
  | r |
 
  r := AlignmentMorph newRow.
  r color: Color red; borderWidth: 0; layoutInset: 6; useRoundedCorners.
  r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
  r addMorphBack: (
  SimpleButtonMorph new
  target: [
  scorePlayer resumePlaying.
  r delete
  ];
  borderColor: #raised;
  borderWidth: 2;
  color: Color green;
  label: 'Continue' translated;
  actionSelector: #value
  ).
  r setBalloonText: 'Continue playing a paused presentation' translated.
  ^r
 
 
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>trackControlsFor: (in category 'layout') -----
  trackControlsFor: trackIndex
 
  | r |
  r := self makeRow
  hResizing: #shrinkWrap;
  vResizing: #shrinkWrap.
  r addMorphBack: (self trackNumAndMuteButtonFor: trackIndex).
  r addMorphBack: (Morph new extent: 10@5; color: color).  "spacer"
  r addMorphBack: (self panAndVolControlsFor: trackIndex).
  ^ r
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>trackNumAndMuteButtonFor: (in category 'layout') -----
  trackNumAndMuteButtonFor: trackIndex
 
  | muteButton instSelector pianoRollColor r |
  muteButton := SimpleSwitchMorph new
  onColor: (Color r: 1.0 g: 0.6 b: 0.6);
  offColor: color;
  color: color;
  label: 'Mute' translated;
  target: scorePlayer;
  actionSelector: #mutedForTrack:put:;
  arguments: (Array with: trackIndex).
  instSelector := PopUpChoiceMorph new
  extent: 95@14;
  contentsClipped: 'oboe1';
  target: self;
  actionSelector: #atTrack:from:selectInstrument:;
  getItemsSelector: #instrumentChoicesForTrack:;
  getItemsArgs: (Array with: trackIndex).
  instSelector arguments:
  (Array with: trackIndex with: instSelector).
  instrumentSelector at: trackIndex put: instSelector.
 
  "select track color using same color list as PianoRollScoreMorph"
  pianoRollColor := (Color wheel: scorePlayer score tracks size) at: trackIndex.
 
  r := self makeRow
  hResizing: #rigid;
  vResizing: #spaceFill;
  extent: 70@10.
  r addMorphBack:
  ((StringMorph
  contents: trackIndex printString
  font: (TextStyle default fontOfSize: 24)) color: pianoRollColor).
  trackIndex < 10
  ifTrue: [r addMorphBack: (Morph new color: color; extent: 19@8)]  "spacer"
  ifFalse: [r addMorphBack: (Morph new color: color; extent: 8@8)].  "spacer"
  r addMorphBack:
  (StringMorph new
  extent: 140@14;
  contentsClipped: (scorePlayer infoForTrack: trackIndex)).
  r addMorphBack: (Morph new color: color; extent: 8@8).  "spacer"
  r addMorphBack: instSelector.
  r addMorphBack: (AlignmentMorph newRow color: color).  "spacer"
  r addMorphBack: muteButton.
  ^ r
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>updateInstrumentsFromLibraryExcept: (in category 'menu') -----
  updateInstrumentsFromLibraryExcept: soundsBeingEdited
  "The instrument library has been modified. Update my instruments with the new versions from the library. Use a single instrument prototype for all parts with the same name; this allows the envelope editor to edit all the parts by changing a single sound prototype."
 
  "soundsBeingEdited is a collection of sounds being edited (by an EnvelopeEditor).  If any of my instruments share one of these, then they will be left alone so as not to disturb that dynamic linkage."
 
  | unloadPostfix myInstruments name displaysAsUnloaded isUnloaded |
  unloadPostfix := '(out)'.
  myInstruments := Dictionary new.
  1 to: instrumentSelector size do: [:i |
  name := (instrumentSelector at: i) contents.
  displaysAsUnloaded := name endsWith: unloadPostfix.
  displaysAsUnloaded ifTrue: [
  name := name copyFrom: 1 to: name size - unloadPostfix size].
  (myInstruments includesKey: name) ifFalse: [
  myInstruments at: name put:
  (name = 'clink'
  ifTrue: [
  (SampledSound
  samples: SampledSound coffeeCupClink
  samplingRate: 11025) copy]
  ifFalse: [
  (AbstractSound
  soundNamed: name
  ifAbsent: [
  (instrumentSelector at: i) contentsClipped: 'default'.
  FMSound default]) copy])].
  (soundsBeingEdited includes: (scorePlayer instrumentForTrack: i)) ifFalse:
  ["Do not update any instrument that is currently being edited"
  scorePlayer instrumentForTrack: i put: (myInstruments at: name)].
 
  "update loaded/unloaded status in instrumentSelector if necessary"
  isUnloaded := (myInstruments at: name) isKindOf: UnloadedSound.
  (displaysAsUnloaded and: [isUnloaded not])
  ifTrue: [(instrumentSelector at: i) contentsClipped: name].
  (displaysAsUnloaded not and: [isUnloaded])
  ifTrue: [(instrumentSelector at: i) contentsClipped: name, unloadPostfix]].
  !

Item was changed:
  ----- Method: ScorePlayerMorph>>volumeControl (in category 'layout') -----
  volumeControl
 
  | volumeSlider r |
  volumeSlider := SimpleSliderMorph new
  color: color;
  sliderColor: Color gray;
  extent: 80@2;
  target: scorePlayer;
  actionSelector: #overallVolume:;
  adjustToValue: scorePlayer overallVolume.
  r := self makeRow
  hResizing: #shrinkWrap;
  vResizing: #rigid;
  height: 24.
  r addMorphBack: (StringMorph contents: 'soft  ' translated).
  r addMorphBack: volumeSlider.
  r addMorphBack: (StringMorph contents: ' loud' translated).
  ^ r
  !

Item was changed:
  ----- Method: Sonogram>>extent: (in category 'geometry') -----
  extent: newExtent
  super image: (Form extent: newExtent depth: Display depth).
  lastX := -1.
  columnForm := Form extent: (32//image depth)@(image height) depth: image depth.
  pixValMap := ((1 to: 256) collect:
  [:i | columnForm pixelValueFor: (Color gray: (256-i)/255.0)])
  as: Bitmap.
  !

Item was changed:
  ----- Method: Sonogram>>extent:minVal:maxVal:scrollDelta: (in category 'all') -----
  extent: extent minVal: min maxVal: max scrollDelta: d
  minVal := min.
  maxVal := max.
  scrollDelta := d.
  self extent: extent.
 
  " try following with scrolldelta = 1, 20, 200
  | s data |
  s := Sonogram new extent: 200@50
  minVal: 0.0 maxVal: 1.0 scrollDelta: 20.
  World addMorph: s.
  data := (1 to: 133) collect: [:i | 0.0].
  1 to: 300 do:
  [:i | data at: (i\\133)+1 put: 1.0.
  s plotColumn: data.
  data at: (i\\133)+1 put: 0.0.
  World doOneCycleNow].
  s delete
  "!

Item was changed:
  ----- Method: Sonogram>>scroll (in category 'all') -----
  scroll
  image copy: (scrollDelta@0 extent: (image width-scrollDelta)@image height)
  from: image to: 0@0 rule: Form over.
  lastX := lastX - scrollDelta.
  self changed!

Item was changed:
  ----- Method: String>>asStringMorph (in category '*Morphic') -----
  asStringMorph
  "Answer the receiver as a StringMorph"
 
  ^ StringMorph contents: self
 
  "'bugs black blood' asStringMorph openInHand"!

Item was changed:
  ----- Method: String>>hasContentsInExplorer (in category '*Morphic-Explorer') -----
  hasContentsInExplorer
 
  ^false!

Item was changed:
  ----- Method: SyntaxError class>>buildMorphicViewOn: (in category '*Morphic-Support') -----
  buildMorphicViewOn: aSyntaxError
  "Answer an Morphic view on the given SyntaxError."
  | window |
  window := (SystemWindow labelled: 'Syntax Error') model: aSyntaxError.
 
  window addMorph: (PluggableListMorph on: aSyntaxError list: #list
  selected: #listIndex changeSelected: nil menu: #listMenu:)
  frame: (0@0 corner: 1@0.15).
 
  window addMorph: (PluggableTextMorph on: aSyntaxError text: #contents
  accept: #contents:notifying: readSelection: #contentsSelection
  menu: #codePaneMenu:shifted:)
  frame: (0@0.15 corner: 1@1).
 
  ^ window openInWorldExtent: 380@220!

Item was changed:
  ----- Method: TextContainer>>paragraphClass (in category 'access') -----
  paragraphClass
  ^ NewParagraph!

Item was changed:
  ----- Method: TextMorph>>paragraphClass (in category 'private') -----
  paragraphClass
  container ifNil: [^ NewParagraph].
  ^ container paragraphClass!

Item was changed:
  ----- Method: TheWorldMenu>>saveAndQuit (in category 'commands') -----
  saveAndQuit
 
  Smalltalk snapshot: true andQuit: true!

Item was changed:
  ----- Method: UpdatingStringMorph>>acceptValue: (in category 'editing') -----
  acceptValue: aValue
 
  self updateContentsFrom: (self acceptValueFromTarget: aValue).
  !

Item was changed:
  ----- Method: WorldState>>releaseRemoteServer (in category 'Nebraska support') -----
  releaseRemoteServer
  "My server has been transferred to some other world. Release pending references"
  remoteServer := nil.
  self canvas: nil.!

Item was changed:
  ----- Method: WorldState>>remoteServer: (in category 'Nebraska support') -----
  remoteServer: aNebraskaServer
  remoteServer ifNotNil:[remoteServer destroy].
  remoteServer := aNebraskaServer.
  self canvas: nil.!