tim Rowledge uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-tpr.1348.mcz
==================== Summary ====================
Name: Morphic-tpr.1348
Author: tpr
Time: 7 August 2017, 4:40:57.485319 pm
UUID: b8af09c4-97da-4835-a036-b1c557a8ab92
Ancestors: Morphic-mt.1347
Explain that an underscore assignment requires a Preference setting
=============== Diff against Morphic-mt.1347 ===============
Item was changed:
----- Method: TextEditor>>explainChar: (in category 'explain') -----
explainChar: string
"Does string start with a special character?"
| char |
char := string at: 1.
char = $. ifTrue: [^'"Period marks the end of a Smalltalk statement. A period in the middle of a number means a decimal point. (The number is an instance of class Float)."'].
char = $' ifTrue: [^'"The characters between two single quotes are made into an instance of class String"'].
char = $" ifTrue: [^'"Double quotes enclose a comment. Smalltalk ignores everything between double quotes."'].
char = $# ifTrue: [^'"The characters following a hash mark are made into an instance of class Symbol. If parenthesis follow a hash mark, an instance of class Array is made. It contains literal constants."'].
(char = $( or: [char = $)]) ifTrue: [^'"Expressions enclosed in parenthesis are evaluated first"'].
(char = $[ or: [char = $]]) ifTrue: [^'"The code inside square brackets is an unevaluated block of code. It becomes an instance of BlockClosure and is usually passed as an argument."'].
(char = ${ or: [char = $}]) ifTrue: [^ '"A sequence of expressions separated by periods, when enclosed in curly braces, are evaluated to yield the elements of a new Array"'].
(char = $< or: [char = $>]) ifTrue: [^'"<primitive: xx> means that this method is usually preformed directly by the virtual machine. If this method is primitive, its Smalltalk code is executed only when the primitive fails."'].
char = $^ ifTrue: [^'"Uparrow means return from this method. The value returned is the expression following the ^"'].
char = $| ifTrue: [^'"Vertical bars enclose the names of the temporary variables used in this method. In a block, the vertical bar separates the argument names from the rest of the code."'].
+ char = $_ ifTrue: [^'"Left arrow means assignment (deprecated, applies if the Preference for allow underscore assignment is set). The value of the expression after the left arrow is stored into the variable before it."'].
- char = $_ ifTrue: [^'"Left arrow means assignment. The value of the expression after the left arrow is stored into the variable before it."'].
char = $; ifTrue: [^'"Semicolon means cascading. The message after the semicolon is sent to the same object which received the message before the semicolon."'].
char = $: ifTrue: [^'"A colon at the end of a keyword means that an argument is expected to follow. Methods which take more than one argument have selectors with more than one keyword. (One keyword, ending with a colon, appears before each argument).', '\\' withCRs, 'A colon before a variable name just inside a block means that the block takes an agrument. (When the block is evaluated, the argument will be assigned to the variable whose name appears after the colon)."'].
char = $$ ifTrue: [^'"The single character following a dollar sign is made into an instance of class Character"'].
char = $- ifTrue: [^'"A minus sign in front of a number means a negative number."'].
char = $e ifTrue: [^'"An e in the middle of a number means that the exponent follows."'].
char = $r ifTrue: [^'"An r in the middle of a bunch of digits is an instance of Integer expressed in a certain radix. The digits before the r denote the base and the digits after it express a number in that base."'].
char = Character space ifTrue: [^'"the space Character"'].
char = Character tab ifTrue: [^'"the tab Character"'].
char = Character cr ifTrue: [^'"the carriage return Character"'].
char = Character lf ifTrue: [^'"the line feed Character"'].
^nil!
tim Rowledge uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-tpr.1110.mcz
==================== Summary ====================
Name: Kernel-tpr.1110
Author: tpr
Time: 7 August 2017, 4:38:16.198536 pm
UUID: f7a1538d-4c10-4b42-9ec7-325d0ac94c8d
Ancestors: Kernel-nice.1109
Correct an ancient underscore assignment
=============== Diff against Kernel-nice.1109 ===============
Item was changed:
----- Method: Semaphore>>wait (in category 'communication') -----
wait
"Primitive. The active Process must receive a signal through the receiver
before proceeding. If no signal has been sent, the active Process will be
suspended until one is sent. Essential. See Object documentation
whatIsAPrimitive."
<primitive: 86>
self primitiveFailed
"excessSignals>0
+ ifTrue: [excessSignals := excessSignals-1]
- ifTrue: [excessSignals _ excessSignals-1]
ifFalse: [self addLastLink: Processor activeProcess suspend]"
!
tim Rowledge uploaded a new version of Network to project The Trunk:
http://source.squeak.org/trunk/Network-tpr.202.mcz
==================== Summary ====================
Name: Network-tpr.202
Author: tpr
Time: 2 August 2017, 5:56:32.822543 pm
UUID: e26da09c-d555-47c0-8c95-d0fcc1085a03
Ancestors: Network-eem.201
Correct a misleading comment
=============== Diff against Network-eem.201 ===============
Item was changed:
----- Method: NetNameResolver class>>initializeNetwork (in category 'network initialization') -----
initializeNetwork
+ "Initialize the network drivers and record the semaphore to be used by the resolver. Do nothing if the network is already initialized. Signal NoNetworkError if network initialization fails."
- "Initialize the network drivers and record the semaphore to be used by the resolver. Do nothing if the network is already initialized. Evaluate the given block if network initialization fails."
"NetNameResolver initializeNetwork"
self resolverStatus = ResolverUninitialized
ifFalse: [^HaveNetwork := true]. "network is already initialized"
HaveNetwork := false. "in case abort"
Smalltalk newExternalSemaphoreDo: [ :semaphore :index |
ResolverSemaphore := semaphore.
"result is nil if network initialization failed, self if it succeeds"
(self primInitializeNetwork: index)
ifNil: [
Smalltalk unregisterExternalObject: ResolverSemaphore.
ResolverSemaphore := nil.
NoNetworkError signal: 'failed network initialization']
ifNotNil: [ HaveNetwork := true ] ].
self initializeOldNetworkFlag!
tim Rowledge uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-tpr.209.mcz
==================== Summary ====================
Name: MorphicExtras-tpr.209
Author: tpr
Time: 2 August 2017, 5:53:29.922577 pm
UUID: 7ad502c6-49bf-4866-886b-e9e5369b003b
Ancestors: MorphicExtras-tpr.208
tiny changes to the init of Hygrometer and Thermomemter dials
=============== Diff against MorphicExtras-tpr.208 ===============
Item was changed:
----- Method: HygrometerDialMorph>>initialize (in category 'initialize-release') -----
initialize
"Build a hygrometer. The background is an ImageMorph showing a dial derived from the same general principles as the BarometerMorph. "
| pointerMorph |
super initialize.
self startAngle: -140 stopAngle: 140;
+ startValue: 0 stopValue: 100.
- startValue: 25 stopValue: 100.
self extent: 200@200; color: Color transparent; borderWidth: 0.
dialCenter := self center.
self buildDial.
"build our fancy needle as an ImageMorph, set the position to horizontal centre and about 2/3 down so that it rotates about that point when inside the TransformationMorph"
pointerMorph := self fancyNeedleOfLength: (self height * 0.65) rounded.
pointerMorph position: pointerMorph extent * ( -0.5@ -0.65).
"we keep track of the TransformationMorph since that is what we have to rotate as the incoming pressure values change"
needleMorph := TransformationMorph new position: dialCenter; addMorph: pointerMorph.
self addMorph: needleMorph.
"add a central colored dot. Because we just do."
self addMorph: (CircleMorph new extent: 20@20; color: Color black; center: dialCenter)
!
Item was changed:
----- Method: ThermometerDialMorph>>buildDial (in category 'dial drawing') -----
buildDial
"start by making a damn big Form, twice the size we want to end up with"
|outerRadius destForm canvas tickLabel tickLength beginAngle endAngle tickAngle tickLabelSize maxTicks |
outerRadius := self height - 1.
destForm := Form extent: self extent * 2 depth: 32.
(canvas := destForm getCanvas) fillOval: (0@0 extent: self extent * 2) color: Color white.
"outer ring"
self drawArcAt: destForm center radius: outerRadius thickness: 1 color: Color black beginAngle: 0 endAngle: 360 onForm: destForm.
"inner ring"
self drawArcAt: destForm center radius: outerRadius * 0.97 thickness: 1 color: Color black beginAngle: 0 endAngle: 360 onForm: destForm.
"outer scale for Fahrenheit"
beginAngle := startAngle -360. "needs cleaning up about this"
endAngle := stopAngle.
self drawArcAt: destForm center radius: outerRadius * 0.8 thickness: 1 color: Color black beginAngle:beginAngle endAngle: stopAngle onForm: destForm.
self drawArcAt: destForm center radius: outerRadius * 0.73 thickness: 1 color: Color black beginAngle:beginAngle endAngle: stopAngle onForm: destForm.
+
- "The Fahrenheit values of our range are
- startValue -5/ 5 * 9 + 32 ->23
- stopValue 30 / 5 * 9 + 32 -> 86
- which is very conveniently integral but sadly it corresponds to 4.44444 deg per ... degree."
maxTicks := stopValue - startValue / 5 * 9 .
tickAngle := endAngle - beginAngle / maxTicks.
(startValue / 5 * 9 +32) to: (stopValue / 5 * 9 +32) do: [:tick|
tickLength := outerRadius * 0.07.
tickLabel := nil.
tick \\ 10 = 0 ifTrue: [
tickLabel := tick asString.
tickLabelSize := 24
] ifFalse: [
tick \\ 2 = 0 ifTrue:[
tickLabel := (tick \\ 10) asString.
tickLabelSize := 18
] ifFalse: [
tickLength := tickLength * 2
]
].
self drawTickRadius: outerRadius * 0.73 length: tickLength thickness: 2 color: Color black angle: beginAngle + (tick - (startValue / 5 * 9 +32) * tickAngle) onCanvas: canvas.
self tickLabel: tickLabel fontSize: tickLabelSize color: Color black centeredAt: dialCenter radius: (outerRadius * 0.73) + tickLength angle: beginAngle + (tick - (startValue / 5 * 9 +32) * tickAngle) onCanvas: canvas.
].
self tickInnerLabel: (String with: (Unicode value: 16rB0) with: $C) fontSize: 36 color: Color black centeredAt: dialCenter radius: (outerRadius * 0.73) angle: 180 onCanvas: canvas.
"inner scale for Celsius"
beginAngle := startAngle -360. "needs cleaning up about this"
endAngle := stopAngle.
self drawArcAt: destForm center radius: outerRadius * 0.71 thickness: 1 color: Color black beginAngle:beginAngle endAngle: stopAngle onForm: destForm.
self drawArcAt: destForm center radius: outerRadius * 0.63 thickness: 1 color: Color black beginAngle:beginAngle endAngle: stopAngle onForm: destForm.
maxTicks := stopValue - startValue.
tickAngle := endAngle - beginAngle / maxTicks.
tickLength := outerRadius * 0.07.
startValue to: stopValue do: [ :tick ||tickThickness|
tickLabel := nil.
tick \\ 5 = 0 ifTrue: [
tickLabelSize := 20.
tickThickness := 3.
tickLabel := tick asString.
] ifFalse: [
tickThickness := 2.
].
self drawTickRadius: outerRadius * 0.63 length: tickLength thickness: tickThickness color: Color black angle: beginAngle + (tick - startValue * tickAngle) onCanvas: canvas.
self tickInnerLabel: tickLabel fontSize: tickLabelSize color: Color black centeredAt: dialCenter radius: (outerRadius * 0.63) angle: beginAngle + (tick - startValue * tickAngle) onCanvas: canvas.
].
self tickLabel: (String with: (Unicode value: 16rB0) with: $F) fontSize: 36 color: Color black centeredAt: dialCenter radius: (outerRadius * 0.73) angle: 180 onCanvas: canvas.
self addMorph: (destForm magnify: destForm boundingBox by: 0.5 smoothing: 2) asMorph!
Item was changed:
----- Method: ThermometerDialMorph>>initialize (in category 'initialize-release') -----
initialize
"Build a thermometer. The background is an ImageMorph showing a dial derived from the same general principles as the BarometerMorph.
The temperature scale is fixed for now at -5C to 30C but ought to be parameterised someday. We'll have the Celcius scale as the inner and a conversion to Fahrenheit as the outer"
| pointerMorph |
super initialize.
self startAngle: -140 stopAngle: 140;
+ startValue: -10 stopValue: 35.
- startValue: -5 stopValue: 30.
self extent: 200@200; color: Color transparent; borderWidth: 0.
dialCenter := self center.
self buildDial.
"build our fancy needle as an ImageMorph, set the position to horizontal centre and about 2/3 down so that it rotates about that point when inside the TransformationMorph"
pointerMorph := self fancyNeedleOfLength: (self height * 0.65) rounded.
pointerMorph position: pointerMorph extent * ( -0.5@ -0.65).
"we keep track of the TransformationMorph since that is what we have to rotate as the incoming pressure values change"
needleMorph := TransformationMorph new position: dialCenter; addMorph: pointerMorph.
self addMorph: needleMorph.
"add a central colored dot. Because we just do."
self addMorph: (CircleMorph new extent: 20@20; color: Color black; center: dialCenter)
!
David T. Lewis uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-dtl.961.mcz
==================== Summary ====================
Name: System-dtl.961
Author: dtl
Time: 2 August 2017, 9:22:02.611529 am
UUID: 4485dae2-bb1b-48ca-bdc1-5f1f4dd89eb0
Ancestors: System-eem.960
When Project class>>tryOtherProjectForRecovery is searching for a safe project to use for emergency recovery, test for projects of a type that the current project inherits from, but do not require that they be of the same class. This handles the case of errors in a FooMorphicProject that inherits from MorphicProject, for which another Morphic project is not likely to be suitable for handling a fatal error raised in the FooMorphicProject.
Expected behavior when evaluating "Project handlePrimitiveError: 'Foobar' "
In an MVC project that is a chlid of a Morphic project, enter the Mophic project and open a debugger on the process that failed in MVC.
In a Mophic project that is a chlid of an MVC project, enter the MVC project and open a debugger on the process that failed in Morphic.
For the common case of a parent project of the same type as the project from which the error is raised, do not attempt to enter another project, and open an emergency evaluator instead.
=============== Diff against System-eem.960 ===============
Item was changed:
----- Method: Project class>>tryOtherProjectForRecovery: (in category 'error recovery') -----
tryOtherProjectForRecovery: errorMessage
"Try entering the parent project if it uses a different user interface. We determine this by comparing the project's class."
| safeProject nextProject |
nextProject := Project current.
safeProject := nil.
[safeProject notNil or: [nextProject isTopProject]] whileFalse: [
nextProject := nextProject parent.
+ (Project current isKindOf: nextProject class)
- nextProject class == Project current class
ifFalse: [safeProject := nextProject]].
safeProject ifNotNil: [:p |
p enterForEmergencyRecovery.
"Active process will usually suspend after this."].!