Ricardo Moran uploaded a new version of Etoys to project Etoys:
http://source.squeak.org/etoys/Etoys-Richo.106.mcz ==================== Summary ==================== Name: Etoys-Richo.106 Author: Richo Time: 15 February 2012, 5:08:02 pm UUID: 87396860-3791-2e48-93ab-1f080fac9474 Ancestors: Etoys-Richo.105, Etoys-kfr.105 * Added a new dialog for adding/modifying user slots. =============== Diff against Etoys-kfr.105 =============== Item was added: + NewVariableDialogMorph subclass: #ModifyVariableDialogMorph + instanceVariableNames: 'slot' + classVariableNames: '' + poolDictionaries: '' + category: 'Etoys-Scripting'! Item was added: + ----- Method: ModifyVariableDialogMorph class>>on:slot: (in category 'as yet unclassified') ----- + on: aMorph slot: aByteSymbol + ^ self basicNew initializeWith: aMorph slot: aByteSymbol! Item was added: + ----- Method: ModifyVariableDialogMorph>>doAccept (in category 'actions') ----- + doAccept + | newName | + self delete. + self varName isEmpty ifTrue: [^ self]. + "If the original slot was modified while this dialog was still open, we add a new variable" + (self targetPlayer slotInfo includesKey: slot) + ifFalse: [self addNewVariable. + ^ self]. + "Change slot type" + self varType = (self targetPlayer typeForSlot: slot) + ifFalse: [self targetPlayer + changeSlotTypeOf: slot + to: self varType]. + "Change slot name" + (newName := self varAcceptableName) = slot + ifFalse: [self targetPlayer + renameSlot: slot + newSlotName: newName]. + "Change decimal places" + (#(#Number #Point) includes: self varType) + ifTrue: [ + self targetPlayer + setPrecisionFor: newName + precision: self decimalPlaces]! Item was added: + ----- Method: ModifyVariableDialogMorph>>initializeWith:slot: (in category 'initialization') ----- + initializeWith: aMorph slot: aSymbolOrNil + myTarget := aMorph. + slot := aSymbolOrNil. + self initialize! Item was added: + ----- Method: ModifyVariableDialogMorph>>title (in category 'accessing') ----- + title + ^ 'Modify variable'! Item was added: + ----- Method: ModifyVariableDialogMorph>>varAcceptableName (in category 'accessing') ----- + varAcceptableName + ^ ScriptingSystem + acceptableSlotNameFrom: self varName + forSlotCurrentlyNamed: slot + asSlotNameIn: self targetPlayer + world: self targetPlayer costume world! Item was added: + ----- Method: ModifyVariableDialogMorph>>varName (in category 'accessing') ----- + varName + ^ varNameText + ifNil: [slot] + ifNotNil: [:text | text contents string]! Item was added: + ----- Method: ModifyVariableDialogMorph>>varType (in category 'accessing') ----- + varType + ^ varTypeButton + ifNil: [self targetPlayer typeForSlot: slot] + ifNotNil: [:button| + Vocabulary typeChoices + detect: [:each | + each translated = button label] + ifNone: [button label asSymbol]]! Item was added: + GenericPropertiesMorph subclass: #NewVariableDialogMorph + instanceVariableNames: 'varNameText varTypeButton decimalPlacesButton' + classVariableNames: '' + poolDictionaries: '' + category: 'Etoys-Scripting'! Item was added: + ----- Method: NewVariableDialogMorph class>>new (in category 'as yet unclassified') ----- + new + ^ self on: Morph new openInWorld! Item was added: + ----- Method: NewVariableDialogMorph class>>on: (in category 'as yet unclassified') ----- + on: morph + ^ self basicNew initializeWith: morph! Item was added: + ----- Method: NewVariableDialogMorph>>addArrowsOn: (in category 'build') ----- + addArrowsOn: button + | arrowsHolder | + arrowsHolder := (TileMorph addArrowsOn: button) anyOne owner. + arrowsHolder center: button left + (arrowsHolder width / 2) + 2 @ button center y. + ! Item was added: + ----- Method: NewVariableDialogMorph>>addDecimalPlaces (in category 'build') ----- + addDecimalPlaces + self addARow: { + self inAColumn: { + (self addARow: { + self lockedString: 'Decimal places: ' translated. + self spacer. + decimalPlacesButton := self buildDecimalPlacesButton + }) cellPositioning: #center. + } + }. + self addSeparator! Item was added: + ----- Method: NewVariableDialogMorph>>addNewVariable (in category 'actions') ----- + addNewVariable + | slotName | + self targetPlayer + addInstanceVariableNamed: (slotName := self varAcceptableName) + type: self varType + value: (self targetPlayer initialValueForSlotOfType: self varType). + (#(#Number #Point) includes: self varType) + ifTrue: [ + self targetPlayer + setPrecisionFor: slotName + precision: self decimalPlaces]! Item was added: + ----- Method: NewVariableDialogMorph>>addSeparator (in category 'build') ----- + addSeparator + (self addAColumn: {}) + wrapCentering: #topLeft; + color: Color white; + borderWidth: 2; + borderColor: self color darker.! Item was added: + ----- Method: NewVariableDialogMorph>>askUserForDecimalPlaces (in category 'actions') ----- + askUserForDecimalPlaces + | list | + list := #(0 1 2 3 4 5 6 7 8 9 10). + ^ UIManager + chooseFrom: (list collect: [:each | each asString]) + values: list + title: ('How many decimal places? (currently {1})' translated + format: {self decimalPlaces})! Item was added: + ----- Method: NewVariableDialogMorph>>askUserForNewType (in category 'actions') ----- + askUserForNewType + | typeChoices menuTitle | + typeChoices := Vocabulary typeChoices asOrderedCollection. + [self target renderedMorph defaultPatch] + on:Exception + do:[ typeChoices remove: #Patch ifAbsent: [typeChoices]]. + menuTitle := 'Choose the TYPE + for {1} + ' translated, ' + (currently {2})' translated format: {self varAcceptableName. self varType}. + ^ UIManager + chooseFrom: (typeChoices collect: [:t | t translated]) + values: typeChoices + title: menuTitle! Item was added: + ----- Method: NewVariableDialogMorph>>buildDecimalPlacesButton (in category 'build') ----- + buildDecimalPlacesButton + | button | + button := SimpleButtonMorph new + labelString: self decimalPlaces asString font: Preferences standardEToysButtonFont; + color: (Color r: 0.806 g: 1.0 b: 0.645); + target: self; + actionSelector: #chooseDecimalPlaces; + extent: 200 @ (TextStyle defaultFont height + 10); + cornerStyle: #square; + borderColor: #raised; + yourself. + self addArrowsOn: button. + ^ button + ! Item was added: + ----- Method: NewVariableDialogMorph>>buildVarTypeButton (in category 'build') ----- + buildVarTypeButton + | button | + button := SimpleButtonMorph new + labelString: self varType translated font: Preferences standardEToysButtonFont; + color: (Color r: 0.806 g: 1.0 b: 0.645); + target: self; + actionSelector: #chooseType; + extent: 200 @ (TextStyle defaultFont height + 10); + cornerStyle: #square; + borderColor: #raised; + yourself. + self addArrowsOn: button. + ^ button + ! Item was added: + ----- Method: NewVariableDialogMorph>>chooseDecimalPlaces (in category 'actions') ----- + chooseDecimalPlaces + self askUserForDecimalPlaces + ifNotNil: [:reply | + decimalPlacesButton label: reply asString. + self rebuild]! Item was added: + ----- Method: NewVariableDialogMorph>>chooseType (in category 'actions') ----- + chooseType + self askUserForNewType + ifNotNil: [:newType | + varTypeButton label: newType. + self rebuild]! Item was added: + ----- Method: NewVariableDialogMorph>>decimalPlaces (in category 'accessing') ----- + decimalPlaces + ^ decimalPlacesButton + ifNil: [Utilities + decimalPlacesForFloatPrecision: (self targetPlayer + defaultFloatPrecisionFor: (Utilities getterSelectorFor: self varAcceptableName))] + ifNotNil: [:button| button label asNumber]! Item was added: + ----- Method: NewVariableDialogMorph>>defaultBorderColor (in category 'accessing') ----- + defaultBorderColor + ^ self defaultColor darker! Item was added: + ----- Method: NewVariableDialogMorph>>defaultColor (in category 'accessing') ----- + defaultColor + ^ (Color r: 0.677 g: 0.935 b: 0.484) + mixed: 0.9 with: Color blue! Item was added: + ----- Method: NewVariableDialogMorph>>doAccept (in category 'actions') ----- + doAccept + self delete. + self varName isEmpty ifTrue: [^ self]. + self addNewVariable! Item was added: + ----- Method: NewVariableDialogMorph>>initialize (in category 'initialize') ----- + initialize + super initialize. + self rebuild! Item was added: + ----- Method: NewVariableDialogMorph>>initializeWith: (in category 'initialize') ----- + initializeWith: aMorph + myTarget := aMorph. + self initialize! Item was added: + ----- Method: NewVariableDialogMorph>>morphicLayerNumber (in category 'accessing') ----- + morphicLayerNumber + + ^10.6! Item was added: + ----- Method: NewVariableDialogMorph>>newTextMorph (in category 'build') ----- + newTextMorph + ^ TextMorph new autoFit: false; + extent: 200 @ (TextStyle defaultFont height + 6); + borderWidth: 1; + backgroundColor: Color white; + borderColor: Color gray; + centered! Item was added: + ----- Method: NewVariableDialogMorph>>rebuild (in category 'build') ----- + rebuild + | buttonColor | + self removeAllMorphs. + self addAColumn: { + self lockedString: self title translated. + }. + self addSeparator. + + self addARow: { + self inAColumn: { + (self addARow: { + self lockedString: 'Name: ' translated. + self spacer. + varNameText := self newTextMorph + contentsWrapped: self varName; + selectAll; + crAction: (MessageSend + receiver: self + selector: #doAccept); + yourself + }) cellPositioning: #center. + (self addARow: { + self lockedString: 'Type: ' translated. + self spacer. + varTypeButton := self buildVarTypeButton + }) cellPositioning: #center. + } + }. + ActiveWorld activeHand newKeyboardFocus: varNameText. + self addSeparator. + + (#(#Number #Point) includes: self varType) + ifTrue: [self addDecimalPlaces]. + + buttonColor := self color lighter. + self addARow: { + self inAColumn: { + (self addARow: { + self + buttonNamed: 'Accept' translated action: #doAccept color: buttonColor + help: 'keep changes made and close panel' translated. + self + buttonNamed: 'Cancel' translated action: #doCancel color: buttonColor + help: 'cancel changes made and close panel' translated. + }) listCentering: #center + } + } + ! Item was added: + ----- Method: NewVariableDialogMorph>>spacer (in category 'build') ----- + spacer + ^ AlignmentMorph newVariableTransparentSpacer ! Item was added: + ----- Method: NewVariableDialogMorph>>target (in category 'accessing') ----- + target + ^ myTarget! Item was added: + ----- Method: NewVariableDialogMorph>>targetPlayer (in category 'accessing') ----- + targetPlayer + ^ self target assuredPlayer! Item was added: + ----- Method: NewVariableDialogMorph>>title (in category 'accessing') ----- + title + ^ 'Add new variable'! Item was added: + ----- Method: NewVariableDialogMorph>>varAcceptableName (in category 'accessing') ----- + varAcceptableName + ^ ScriptingSystem + acceptableSlotNameFrom: self varName + forSlotCurrentlyNamed: nil + asSlotNameIn: self targetPlayer + world: self targetPlayer costume world! Item was added: + ----- Method: NewVariableDialogMorph>>varName (in category 'accessing') ----- + varName + ^ varNameText + ifNil: [| usedNames | + usedNames := self targetPlayer class instVarNames. + Utilities + keyLike: ('var' translated, (usedNames size + 1) asString) + satisfying: [:aKey | (usedNames includes: aKey) not]] + ifNotNil: [:text | text contents string]! Item was added: + ----- Method: NewVariableDialogMorph>>varType (in category 'accessing') ----- + varType + ^ varTypeButton + ifNil: [self targetPlayer initialTypeForSlotNamed: self varAcceptableName] + ifNotNil: [:button| + Vocabulary typeChoices + detect: [:each | + each translated = button label] + ifNone: [button label asSymbol]]! Item was changed: ----- Method: Player>>addInstanceVariable (in category 'slots-user') ----- addInstanceVariable "Offer the user the opportunity to add an instance variable, and if he goes through with it, actually add it." + ActiveWorld + addMorphInLayer: (NewVariableDialogMorph on: self costume) + centeredNear: (ActiveHand ifNil:[Sensor]) cursorPoint! - - | itsName initialValue typeChosen usedNames initialAnswer setterSelector originalString | - usedNames := self class instVarNames. - - initialAnswer := Utilities keyLike: ('var' translated, (usedNames size + 1) asString) satisfying: [:aKey | (usedNames includes: aKey) not]. - - originalString := FillInTheBlank request: 'name for new variable: ' translated initialAnswer: initialAnswer. - Cursor wait showWhile: [ - originalString isEmptyOrNil ifTrue: [^ self]. - itsName := ScriptingSystem acceptableSlotNameFrom: originalString forSlotCurrentlyNamed: nil asSlotNameIn: self world: self costume world. - - itsName size == 0 ifTrue: [^ self]. - self assureUniClass. - typeChosen := (self askUserForNewTypeFor: itsName) ifNil: [#Number]. - self slotInfo at: itsName put: (SlotInformation new initialize type: typeChosen). - initialValue := self initialValueForSlotOfType: typeChosen. - self addInstanceVarNamed: itsName withValue: initialValue. - self compileInstVarAccessorsFor: itsName. - setterSelector := Utilities setterSelectorFor: itsName. - ((self class allSubInstances copyWithout: self) reject: [:e | e isSequentialStub]) do: - [:anInstance | anInstance perform: setterSelector with: initialValue]. - self regenerateScripts. - self updateAllViewersAndForceToShow: ScriptingSystem nameForInstanceVariablesCategory. - ]! Item was changed: ----- Method: Player>>addInstanceVariableNamed:type:value: (in category 'slots-user') ----- addInstanceVariableNamed: nameSymbol type: typeChosen value: aValue "Add an instance variable of the given name and type, and initialize it to have the given value" | initialValue setterSelector | self assureUniClass. self slotInfo at: nameSymbol put: (SlotInformation new initialize type: typeChosen). + initialValue := self initialValueForSlotOfType: typeChosen. - initialValue _ self initialValueForSlotOfType: typeChosen. self addInstanceVarNamed: nameSymbol withValue: aValue. + self compileInstVarAccessorsFor: nameSymbol. - self class compileAccessorsFor: nameSymbol. setterSelector _ Utilities setterSelectorFor: nameSymbol. + ((self class allSubInstances copyWithout: self) reject: [:e | e isSequentialStub]) do: - (self class allSubInstances copyWithout: self) do: [:anInstance | anInstance perform: setterSelector with: initialValue]. self regenerateScripts. self updateAllViewersAndForceToShow: ScriptingSystem nameForInstanceVariablesCategory ! Item was removed: - ----- Method: Player>>askUserForNewTypeFor: (in category 'slots-user') ----- - askUserForNewTypeFor: slotName - | typeChoices menuCaption | - typeChoices := Vocabulary typeChoices asOrderedCollection. - [self costume renderedMorph defaultPatch] - on:Exception - do:[ typeChoices remove: #Patch ifAbsent: [typeChoices]]. - menuCaption := 'Choose the TYPE - for {1} - ' translated, slotName, ' - (currently {2})' translated format: {slotName. (self slotInfoAt: slotName) type translated}. - ^ (SelectionMenu - labelList: (typeChoices collect: [:t | t translated]) - lines: #() - selections: typeChoices) - startUpWithCaption: menuCaption.! Item was added: + ----- Method: Player>>changeSlotInfo: (in category 'slots-user') ----- + changeSlotInfo: aByteSymbol + ActiveWorld + addMorphInLayer: (ModifyVariableDialogMorph on: self costume slot: aByteSymbol) + centeredNear: (ActiveHand ifNil:[Sensor]) cursorPoint! Item was added: + ----- Method: Player>>changeSlotTypeOf:to: (in category 'slots-user') ----- + changeSlotTypeOf: slotName to: newType + (self typeForSlot: slotName) capitalized = newType ifTrue: [^ self]. + + (self slotInfoAt: slotName) type: newType. + self class allInstancesDo: "allSubInstancesDo:" + [:anInst | anInst instVarNamed: slotName asString put: + (anInst valueOfType: newType from: (anInst instVarNamed: slotName))]. + self updateAllViewers. "does siblings too" + self changeTypesInWatchersOf: slotName. "does siblings too" + + ! Item was removed: - ----- Method: Player>>chooseSlotTypeFor: (in category 'slots-user') ----- - chooseSlotTypeFor: aGetter - "Let the user designate a type for the slot associated with the given getter" - - | typeChosen slotName | - slotName := Utilities inherentSelectorForGetter: aGetter. - typeChosen := self askUserForNewTypeFor: slotName. - typeChosen isEmptyOrNil ifTrue: [^ self]. - (self typeForSlot: slotName) capitalized = typeChosen ifTrue: [^ self]. - - (self slotInfoAt: slotName) type: typeChosen. - self class allInstancesDo: "allSubInstancesDo:" - [:anInst | anInst instVarNamed: slotName asString put: - (anInst valueOfType: typeChosen from: (anInst instVarNamed: slotName))]. - self updateAllViewers. "does siblings too" - self changeTypesInWatchersOf: slotName. "does siblings too" - - ! Item was removed: - ----- Method: Player>>renameSlot: (in category 'slots-user') ----- - renameSlot: oldSlotName - | reply newSlotName | - reply := FillInTheBlank request: 'New name for "' translated , oldSlotName , '":' - initialAnswer: oldSlotName. - reply isEmpty ifTrue: [^self]. - newSlotName := ScriptingSystem - acceptableSlotNameFrom: reply - forSlotCurrentlyNamed: oldSlotName - asSlotNameIn: self - world: self costume currentWorld. - oldSlotName = newSlotName ifTrue: [^ self]. - self renameSlot: oldSlotName newSlotName: newSlotName! Item was changed: ----- Method: Player>>setPrecisionFor: (in category 'slots-user') ----- setPrecisionFor: slotName "Set the precision for the given slot name" + | aList aMenu reply aGetter places | - | aList aMenu reply val aGetter places | aGetter := Utilities getterSelectorFor: slotName. places := Utilities decimalPlacesForFloatPrecision: (self defaultFloatPrecisionFor: aGetter). aList := #('0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '10'). aMenu := SelectionMenu labels: aList selections: (aList collect: [:m | m asNumber]). reply := aMenu startUpWithCaption: ('How many decimal places? (currently {1})' translated format: {places}). reply ifNotNil: + [self setPrecisionFor: slotName precision: reply]! - [(self slotInfo includesKey: slotName) - ifTrue: - ["it's a user slot" - - (self slotInfoAt: slotName) - floatPrecision: (Utilities floatPrecisionForDecimalPlaces: reply). - self class allInstancesDo: - [:anInst | - reply == 0 - ifFalse: - [((val := anInst instVarNamed: slotName asString) isInteger) - ifTrue: [anInst instVarNamed: slotName asString put: val asFloat]]. - anInst updateAllViewers]] - ifFalse: - ["it's specifying a preference for precision on a system-defined numeric slot" - - self noteDecimalPlaces: reply forGetter: aGetter. - self updateAllViewers]]! Item was added: + ----- Method: Player>>setPrecisionFor:precision: (in category 'slots-user') ----- + setPrecisionFor: slotName precision: aNumber + | val | + (self slotInfo includesKey: slotName) + ifTrue: + ["it's a user slot" + + (self slotInfoAt: slotName) + floatPrecision: (Utilities floatPrecisionForDecimalPlaces: aNumber). + self class allInstancesDo: + [:anInst | + aNumber == 0 + ifFalse: + [((val := anInst instVarNamed: slotName asString) isInteger) + ifTrue: [anInst instVarNamed: slotName asString put: val asFloat]]. + anInst updateAllViewers]] + ifFalse: + ["it's specifying a preference for precision on a system-defined numeric slot" + + self noteDecimalPlaces: aNumber forGetter: (Utilities getterSelectorFor: slotName). + self updateAllViewers]! Item was changed: ----- Method: Player>>slotInfoButtonHitFor:inViewer: (in category 'scripts-kernel') ----- slotInfoButtonHitFor: aGetterSymbol inViewer: aViewer "The user made a gesture asking for slot menu for the given getter symbol in a viewer; put up the menu." | aMenu slotSym aType typeVocab interface selector | (#(+ - * /) includes: aGetterSymbol) ifTrue: [^ self inform: ('{1} is used for vector operations' translated format: {aGetterSymbol})]. slotSym _ Utilities inherentSelectorForGetter: aGetterSymbol. aType _ self typeForSlotWithGetter: aGetterSymbol asSymbol. aMenu _ MenuMorph new defaultTarget: self. interface := aViewer currentVocabulary methodInterfaceAt: aGetterSymbol ifAbsent: [nil]. selector := interface isNil ifTrue: [slotSym asString] ifFalse: [interface selector]. aType = #Patch ifTrue: [ aMenu add: 'grab morph' translated target: (self perform: aGetterSymbol) selector: #grabPatchMorph argument: #(). aMenu addLine. ]. (typeVocab _ Vocabulary vocabularyForType: aType) addWatcherItemsToMenu: aMenu forGetter: aGetterSymbol. (self slotInfo includesKey: slotSym) ifTrue: + [typeVocab addUserSlotItemsTo: aMenu slotSymbol: slotSym. - [aMenu add: 'change value type' translated selector: #chooseSlotTypeFor: argument: aGetterSymbol. - typeVocab addUserSlotItemsTo: aMenu slotSymbol: slotSym. aMenu add: ('remove "{1}"' translated format: {slotSym}) selector: #removeSlotNamed: argument: slotSym. + aMenu add: ('modify "{1}"' translated format: {slotSym}) selector: #changeSlotInfo: argument: slotSym + ] + ifFalse: [ + aMenu addLine. + typeVocab addExtraItemsToMenu: aMenu forSlotSymbol: slotSym. "e.g. Player type adds hand-me-tiles"]. - aMenu add: ('rename "{1}"' translated format: {slotSym}) selector: #renameSlot: argument: slotSym. aMenu addLine]. - typeVocab addExtraItemsToMenu: aMenu forSlotSymbol: slotSym. "e.g. Player type adds hand-me-tiles" - self addIdiosyncraticMenuItemsTo: aMenu forSlotSymol: slotSym. aMenu items isEmpty ifTrue: [aMenu add: 'ok' translated action: #yourself]. aMenu popUpForHand: aViewer primaryHand in: aViewer world! _______________________________________________ etoys-dev mailing list [hidden email] http://lists.squeakland.org/mailman/listinfo/etoys-dev |
Free forum by Nabble | Edit this page |