'From Pharo2.0a of ''18 April 2012'' [Latest update: #20582] on 4 March 2013 at 3:12:41 pm'! ----STARTUP----an Array(4 March 2013 2:53:55 pm) as /Users/denker/Desktop/Condense/Pharo-20582.image! Smalltalk condenseSources! ----QUIT----an Array(4 March 2013 3:13:01 pm) Pharo-20582.image priorSource: 0! ----STARTUP----an Array(4 March 2013 3:13:13 pm) as /Users/denker/Desktop/Condense/Pharo-20582.image! ImageCleaner cleanUpForRelease! ----QUIT----an Array(4 March 2013 3:13:34 pm) Pharo-20582.image priorSource: 225! ----STARTUP----an Array(4 March 2013 3:52:55 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(4 March 2013 3:52:55 pm) Pharo.image priorSource: 443! ----STARTUP----an Array(4 March 2013 3:52:56 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(4 March 2013 3:52:56 pm) Pharo-20582.image priorSource: 621! ----STARTUP----an Array(4 March 2013 4:37:56 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 3/4/2013 16:36' prior: 32781641! commentForCurrentUpdate ^ 'Issue 7637: SourceFileArrayTest hardcodes some offsets http://code.google.com/p/pharo/issues/detail?id=7637 Issue 7636: fix file name of sources file in #downloadSources http://code.google.com/p/pharo/issues/detail?id=7636 Issue 7634: Slow Package Menu on Mouse Button Right Click + Fix http://code.google.com/p/pharo/issues/detail?id=7634'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 3/4/2013 16:36'! script557 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1326.mcz KernelTests-EstebanLorenzano.472.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-MarcusDenker.63.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1365.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.7.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.75.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.520.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1055.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 3/4/2013 16:36'! update20583 "self new update20583" self withUpdateLog: 'Issue 7637: SourceFileArrayTest hardcodes some offsets http://code.google.com/p/pharo/issues/detail?id=7637 Issue 7636: fix file name of sources file in #downloadSources http://code.google.com/p/pharo/issues/detail?id=7636 Issue 7634: Slow Package Menu on Mouse Button Right Click + Fix http://code.google.com/p/pharo/issues/detail?id=7634'. self loadTogether: self script557 merge: false. self flushCaches. ! ! "ScriptLoader20"! !CriticBrowser class methodsFor: 'instance creation' stamp: 'MikeMueller 3/4/2013 15:01' prior: 20249958! packagesGroup: aBuilder (aBuilder item: #'Critics Browser') action: [ | packages target env rules group | target := aBuilder model. group := target selectedGroups. packages := OrderedCollection new. group do: [ :each | each classes do: [ :cl | MCWorkingCopy managersForClass: cl do: [ :package | packages add: package ] ] ]. rules := RBCompositeLintRule allGoodRules. env := RBPackageEnvironment new packages: packages. self openOnRule: rules onEnvironment: env ]; help: 'Running critics rules on this group'! ! !CriticBrowser class methodsFor: 'instance creation' stamp: 'MikeMueller 3/4/2013 15:01' prior: 20250613! packagesMenu: aBuilder (aBuilder item: #'Critics Browser') action: [ | packages target env rules | target := aBuilder model. packages := OrderedCollection new. target selectedPackages do: [ :p | MCWorkingCopy managersForCategory: p packageName do: [ :package | packages add: package ] ]. rules := RBCompositeLintRule allGoodRules. env := RBPackageEnvironment new packages: packages. self openOnRule: rules onEnvironment: env ]; help: 'Running critics rules on this package'! ! !SourceFileArrayTest methodsFor: 'testing' stamp: 'MarcusDenker 3/4/2013 16:23' prior: 50644852! testProtocol "Test that we can access protocol correctly" "self debug: #testProtocol" | okCm notOkCm | okCm := Point>>#dist: . self assert: (SourceFiles sourcedDataAt: okCm sourcePointer) = 'Point methodsFor: ''point functions'' stamp: ''lr 7/4/2009 10:42'''. self assert: (SourceFiles protocolAt: okCm sourcePointer) = 'point functions'. notOkCm := Behavior >> #supermostPrecodeCommentFor:. self assert: (SourceFiles protocolAt: notOkCm sourcePointer) = 'accessing method dictionary'. ! ! !SourceFileArrayTest methodsFor: 'testing' stamp: 'MarcusDenker 3/4/2013 16:24' prior: 50649193! testTimeStamp "Test that we can access timeStamp correctly" "self debug: #testTimeStamp" | okCm notOkCm | okCm := Point>>#dist: . self assert: (SourceFiles sourcedDataAt: okCm sourcePointer) = 'Point methodsFor: ''point functions'' stamp: ''lr 7/4/2009 10:42'''. self assert: (SourceFiles timeStampAt: okCm sourcePointer) = 'lr 7/4/2009 10:42'. notOkCm := Behavior >> #supermostPrecodeCommentFor:. self assert: (SourceFiles timeStampAt: notOkCm sourcePointer) = ''. ! ! !SmalltalkImage methodsFor: '*Zinc-System-Support' stamp: 'MarcusDenker 3/4/2013 16:26' prior: 33492625! downloadSources "Try downloading the sources file from 2 different locations to the shared directory. Be silent when this does not work: a missing sources will be triggered later on. For now, use the VM directory." | sharedDirectory | self shouldDownloadSourcesFile ifFalse: [ ^ self ]. sharedDirectory := self vmDirectory. self sourcesDownloadClient url: 'http://pharo.gforge.inria.fr/ci/image/PharoV20.sources'; downloadTo: sharedDirectory; close. (sharedDirectory / self sourcesFile basename) exists ifTrue: [ ^ self ]. self sourcesDownloadClient url: 'http://stfx.eu/PharoV20.sources'; downloadTo: sharedDirectory; close. ! ! "Manifest-CriticBrowser"! "Tests"! "Zinc-System-Support"! ----End fileIn----! ----QUIT----an Array(4 March 2013 4:38:01 pm) Pharo.image priorSource: 793! ----STARTUP----an Array(4 March 2013 4:38:02 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(4 March 2013 4:38:02 pm) Pharo-20583.image priorSource: 14553! ----STARTUP----an Array(4 March 2013 8:03:08 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 3/4/2013 19:59' prior: 33555497! commentForCurrentUpdate ^ 'Issue 7638: Make sendersOf: 2 times faster http://code.google.com/p/pharo/issues/detail?id=7638 Issue 7403: CMD-click no longer works to activate source-links http://code.google.com/p/pharo/issues/detail?id=7403'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 3/4/2013 19:59'! script558 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1328.mcz KernelTests-EstebanLorenzano.472.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-MarcusDenker.63.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1367.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.7.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.75.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.520.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1055.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 3/4/2013 19:59'! update20584 "self new update20584" self withUpdateLog: 'Issue 7638: Make sendersOf: 2 times faster http://code.google.com/p/pharo/issues/detail?id=7638 Issue 7403: CMD-click no longer works to activate source-links http://code.google.com/p/pharo/issues/detail?id=7403'. self loadTogether: self script558 merge: false. self flushCaches. ! ! "ScriptLoader20"! !ScrollPane methodsFor: 'event handling' stamp: 'CamilloBruni 3/4/2013 17:39' prior: 32838052! mouseDown: evt self flag: #todo. "This is a quick fix for ensure cmd+click works. see: http://code.google.com/p/pharo/issues/detail?id=7403 probably a better fix is just remove it, but I want to prevent any possible side effects and there is no time for study the issue as it would be required" (evt yellowButtonPressed and: [ evt commandKeyPressed not ]) "First check for option (menu) click" ifTrue: [ (self yellowButtonActivity: evt shiftPressed) ifTrue: [ ^ super mouseDown: evt. ]]. "If pane is not empty, pass the event to the last submorph, assuming it is the most appropriate recipient (!!)" scroller hasSubmorphs ifTrue: [ scroller submorphs last mouseDown: (evt transformedBy: (scroller transformFrom: self)) ]. self eventHandler ifNotNil: [ self eventHandler mouseDown: evt fromMorph: self ]! ! !CompiledMethodTrailer methodsFor: 'initialize-release' stamp: 'CamilloBruni 3/4/2013 17:29' prior: 19894076! method: aMethod | flagByte | data := size := nil. method := aMethod. flagByte := method at: (method size). "trailer kind encoded in 6 high bits of last byte" kind := self class trailerKinds at: 1+(flagByte>>2). "decode the trailer bytes, inline some common types to speed up decoding" kind = 'SourcePointer' ifTrue: [ self decodeSourcePointer ] ifFalse: [ kind = 'VarLengthSourcePointer' ifTrue: [ self decodeVarLengthSourcePointer ] ifFalse: [ kind = 'NoTrailer' ifTrue: [ self decodeNoTrailer ] ifFalse: [ "slow but general decoding using perform" self perform: ('decode' , kind) asSymbol ]]]. "after decoding the trailer, size must be set" [size notNil] assert. ! ! "Kernel"! "Morphic"! ----End fileIn----! ----QUIT----an Array(4 March 2013 8:03:18 pm) Pharo.image priorSource: 14725! ----STARTUP----an Array(4 March 2013 8:03:19 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(4 March 2013 8:03:19 pm) Pharo-20584.image priorSource: 26618! ----STARTUP----an Array(5 March 2013 10:21:14 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(5 March 2013 10:21:14 am) Pharo.image priorSource: 26792! ----STARTUP----an Array(5 March 2013 10:21:15 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(5 March 2013 10:21:15 am) Pharo-20584.image priorSource: 26977! ----STARTUP----an Array(6 March 2013 1:06:02 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 3/6/2013 13:03' prior: 33569431! commentForCurrentUpdate ^ 'Issue 7648: Setting Browser > Export Settings writes invalid startup files http://code.google.com/p/pharo/issues/detail?id=7648 Issue 7645: testValueWithinTimingRepeat sometimes fails http://code.google.com/p/pharo/issues/detail?id=7645 Issue 7642: Time and DateAndTime Parsing fix, cleanup and enhancement http://code.google.com/p/pharo/issues/detail?id=7642'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 3/6/2013 13:03'! script559 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1330.mcz KernelTests-MarcusDenker.474.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-MarcusDenker.63.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1367.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1055.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 3/6/2013 13:03'! update20585 "self new update20585" self withUpdateLog: 'Issue 7648: Setting Browser > Export Settings writes invalid startup files http://code.google.com/p/pharo/issues/detail?id=7648 Issue 7645: testValueWithinTimingRepeat sometimes fails http://code.google.com/p/pharo/issues/detail?id=7645 Issue 7642: Time and DateAndTime Parsing fix, cleanup and enhancement http://code.google.com/p/pharo/issues/detail?id=7642'. self loadTogether: self script559 merge: false. self flushCaches. ! ! "ScriptLoader20"! !Time class methodsFor: 'smalltalk-80' stamp: 'SvenVanCaekenberghe 3/4/2013 23:43' prior: 53151807! readFrom: aStream "Read a Time from the stream in the form: ::. , or may be omitted. e.g. 1:59:30 pm; 8AM; 15:30" | hour minute second ampm nanos power | hour := Integer readFrom: aStream. minute := second := nanos := 0. (aStream peekFor: $:) ifTrue: [ minute := Integer readFrom: aStream. (aStream peekFor: $:) ifTrue: [ second := Integer readFrom: aStream. (aStream peekFor: $.) ifTrue: [ power := 1. [ aStream atEnd not and: [ aStream peek isDigit ] ] whileTrue: [ nanos := nanos * 10 + aStream next digitValue. power := power * 10 ]. nanos := nanos / power * 1000000000 ] ] ]. aStream skipSeparators. (aStream atEnd not and: [ 'APap' includes: aStream peek ]) ifTrue: [ ampm := aStream next asLowercase. (ampm = $p and: [ hour < 12 ]) ifTrue: [ hour := hour + 12 ]. (ampm = $a and: [ hour = 12 ]) ifTrue: [ hour := 0 ]. (aStream peekFor: $m) ifFalse: [ aStream peekFor: $M ] ]. ^ self hour: hour minute: minute second: second nanoSecond: nanos! ! !DateAndTimeTest methodsFor: 'tests - under design' stamp: 'SvenVanCaekenberghe 3/5/2013 09:27' prior: 20431340! testAsDateAndTime "self debug: #testAsDateAndTime" #('-1199-01-05T20:33:14.321-05:00' ' 2002-05-16T17:20:45.1+01:01' ' 2002-05-16T17:20:45.02+01:01' ' 2002-05-16T17:20:45.003+01:01' ' 2002-05-16T17:20:45.0004+01:01' ' 2002-05-16T17:20:45.00005' ' 2002-05-16T17:20:45.000006+01:01' ' 2002-05-16T17:20:45.0000007+01:01' ' 2002-05-16T17:20:45.00000008-01:01' ' 2002-05-16T17:20:45.000000009+01:01' ' 2002-05-16T17:20:45.0000000001+01:01' ' 2002-05-16T17:20' ' 2002-05-16T17:20:45' ' 2002-05-16T17:20:45+01:57' ' 2002-05-16T17:20:45-02:34' ' 2002-05-16T17:20:45+00:00' ' 1997-04-26T01:02:03+01:02:3' ) do: [:each | each asDateAndTime printString = each]! ! !DateAndTimeTest methodsFor: 'tests - under design' stamp: 'SvenVanCaekenberghe 3/5/2013 09:25'! testReadFromUTCOffset "self debug: #testReadFromNoOffset" self assert: (DateAndTime readFrom: '2010-01-05T20:33:14.321Z' readStream) offset isZero ! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/4/2013 23:48' prior: 20362497! readFrom: aStream "Parse and return a new DateAndTime instance from stream, as a Date, a Time and a TimeZone offset." "self readFrom: ' 2013-03-04T23:47:52.876+01:00' readStream" | offset date time ch | date := Date readFrom: aStream. [ aStream peek isDigit ] whileFalse: [ aStream next ]. time := Time readFrom: aStream. offset := self readTimezoneOffsetFrom: aStream. ^ self year: date year month: date monthIndex day: date dayOfMonth hour: time hour minute: time minute second: time second nanoSecond: time nanoSecond offset: offset " '-1199-01-05T20:33:14.321-05:00' asDateAndTime ' 2002-05-16T17:20:45.1+01:01' asDateAndTime ' 2002-05-16T17:20:45.02+01:01' asDateAndTime ' 2002-05-16T17:20:45.003+01:01' asDateAndTime ' 2002-05-16T17:20:45.0004+01:01' asDateAndTime ' 2002-05-16T17:20:45.00005' asDateAndTime ' 2002-05-16T17:20:45.000006+01:01' asDateAndTime ' 2002-05-16T17:20:45.0000007+01:01' asDateAndTime ' 2002-05-16T17:20:45.00000008-01:01' asDateAndTime ' 2002-05-16T17:20:45.000000009+01:01' asDateAndTime ' 2002-05-16T17:20:45.0000000001+01:01' asDateAndTime ' 2002-05-16T17:20' asDateAndTime ' 2002-05-16T17:20:45' asDateAndTime ' 2002-05-16T17:20:45+01:57' asDateAndTime ' 2002-05-16T17:20:45-02:34' asDateAndTime ' 2002-05-16T17:20:45+00:00' asDateAndTime ' 1997-04-26T01:02:03+01:02:3' asDateAndTime "! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/4/2013 20:29'! readTimezoneOffsetFrom: stream "Read and return an optional timezone offset in the form of [+|-]hh[separator]mm[separator]ss or Z from stream as a duration. Separator can be a colon or a space. If there is no offset, return the local offset." | sign hour minute second | (stream peekFor: $Z) ifTrue: [ ^ Duration zero ]. ^ ('+-' includes: stream peek) ifTrue: [ sign := stream next = $- ifTrue: [ -1 ] ifFalse: [ 1 ]. hour := Integer readFrom: stream. (': ' includes: stream peek) ifFalse: [ minute := 0 ] ifTrue: [ stream next. minute := Integer readFrom: stream. (': ' includes: stream peek) ifFalse: [ second := 0 ] ifTrue: [ stream next. second := Integer readFrom: stream ] ]. Duration seconds: sign * ((hour * 3600) + (minute * 60) + second) ] ifFalse: [ self localOffset ]! ! !SettingDeclaration methodsFor: '*StartupPreferences' stamp: 'MikeMueller 3/5/2013 12:58' prior: 33156570! startupAction "I assume here that the receiver is always a class" | targetSymbol currentValue | targetSymbol := self target isSymbol ifTrue: [ self target ] ifFalse: [ self target name asSymbol ]. currentValue := self targetSelector ifNil: [ (Smalltalk at: targetSymbol) perform: self getSelector ] ifNotNil: [:s | ((Smalltalk at: targetSymbol) perform: s) perform: self getSelector]. ^ StartupAction name: self label code: (String streamContents: [:s | self targetSelector ifNotNil: [ s << '(' ]. s << '(Smalltalk at: '. targetSymbol asSymbol printOn: s. self targetSelector ifNotNil: [:ts | s << ') perform: '. ts printOn: s ]. s << ') perform: '. self setSelector asSymbol printOn: s. s << ' with: ('. currentValue settingStoreOn: s. s <<')' ]) runOnce: true! ! !TestValueWithinFix methodsFor: 'tests' stamp: 'MarcusDenker 3/5/2013 10:45' prior: 52477946! testValueWithinTimingRepeat "Test timing of valueWithin:onTimeout:" | time | time := [ 3 timesRepeat: [ [500 milliSeconds asDelay wait] valueWithin: 100 milliSeconds onTimeout: []] ] durationToRun. self assert: time < 450 milliSeconds. ! ! !FreeTypeSystemSettings class methodsFor: 'settings' stamp: 'MikeMueller 3/5/2013 12:58'! noFt2Library: aBoolean "ignore it for now" ! ! "Kernel"! "KernelTests"! "Settings-FreeType"! "StartupPreferences"! "Tests"! ----End fileIn----! ----QUIT----an Array(6 March 2013 1:06:12 pm) Pharo.image priorSource: 27153! ----STARTUP----an Array(6 March 2013 1:06:13 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(6 March 2013 1:06:13 pm) Pharo-20585.image priorSource: 43900! ----STARTUP----an Array(7 March 2013 2:06:49 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 3/6/2013 14:04' prior: 33581860! commentForCurrentUpdate ^ 'Issue 7458: Changing method in debugger (in a block activation) changes CompiledMethod but not source code http://code.google.com/p/pharo/issues/detail?id=7458'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 3/6/2013 14:04'! script560 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1330.mcz KernelTests-MarcusDenker.474.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-MarcusDenker.63.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1367.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1058.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 3/6/2013 14:04'! update20586 "self new update20586" self withUpdateLog: 'Issue 7458: Changing method in debugger (in a block activation) changes CompiledMethod but not source code http://code.google.com/p/pharo/issues/detail?id=7458'. self loadTogether: self script560 merge: false. self flushCaches. ! ! "ScriptLoader20"! !Debugger methodsFor: 'accessing' stamp: 'ClementBera 2/19/2013 16:34' prior: 20493289! recompileCurrentMethodTo: aText notifying: aController |classOfMethod category selector newMethod| classOfMethod := self selectedClass. category := self selectedMessageCategoryName. selector := self selectedClass parserClass new parseSelector: aText. (selector == self selectedMessageName or: [(self selectedMessageName beginsWith: 'DoIt') and: [selector numArgs = self selectedMessageName numArgs]]) ifFalse: [self inform: 'can''t change selector'. ^nil]. aController setText: aText. selector := classOfMethod compile: aText classified: category notifying: aController. selector ifNil: [^nil]. "compile cancelled" contents := aText. newMethod := classOfMethod compiledMethodAt: selector. newMethod isQuick ifTrue: [self down. self selectedContext jump: (self selectedContext previousPc - self selectedContext pc)]. ^ newMethod ! ! "Tools"! ----End fileIn----! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/6/2013 17:57' prior: 33598780! commentForCurrentUpdate ^ 'Issue 7655: new default preferences https://code.google.com/p/pharo/issues/detail?id=7655 Issue 7652: Nautilus and Message browser windows don''t get updated when in a window group https://code.google.com/p/pharo/issues/detail?id=7652 Issue 7654: keybindings redirects command to alt in linux/win https://code.google.com/p/pharo/issues/detail?id=7654 Issue 7650: ''2012-07-26 16:38:48 +0200'' asDateAndTime fails https://code.google.com/p/pharo/issues/detail?id=7650 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/6/2013 17:57'! script561 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1332.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1369.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1058.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/6/2013 17:58'! update20587 "self new update20587" self withUpdateLog: 'Issue 7655: new default preferences https://code.google.com/p/pharo/issues/detail?id=7655 Issue 7652: Nautilus and Message browser windows do not get updated when in a window group https:Argument expected -> //code.google.com/p/pharo/issues/detail?id=7652 Issue 7654: keybindings redirects command to alt in linux/win https://code.google.com/p/pharo/issues/detail?id=7654 Issue 7650: ''2012-07-26 16:38:48 +0200'' asDateAndTime fails https://code.google.com/p/pharo/issues/detail?id=7650 '. self loadTogether: self script561 merge: false. NECPreferences popupAutomaticDelay: 500. TextEditorDialogWindow autoAccept: true. Parser warningAllowed: true. self flushCaches. ! ! "ScriptLoader20"! !SystemWindow methodsFor: '*Morphic-Worlds' stamp: 'CamilleTeruel 3/6/2013 14:57' prior: 51685523! isDisplayed " Answer true if I am currently displayed in the World" ^ self world notNil! ! !KMComposedModifier methodsFor: 'arithmetic' stamp: 'GuillermoPolito 4/10/2011 02:32' prior: 24127217! + modified ^ modified asShortcut modifiedBy: self! ! !KMComposedModifier methodsFor: 'accessing' stamp: 'GuillermoPolito 5/31/2011 18:26' prior: 24127368! command modifiers add: KMModifier command! ! !KMComposedModifier methodsFor: 'initialization' stamp: 'CamilloBruni 3/19/2011 21:17' prior: 24127508! initialize super initialize. modifiers := Set new.! ! !KMComposedModifier methodsFor: 'matching' stamp: 'CamilloBruni 3/19/2011 21:18' prior: 24127658! matchesEvent: aKeyboardEvent ^ modifiers allSatisfy: [:modifier| modifier matchesEvent: aKeyboardEvent]! ! !KMComposedModifier methodsFor: 'printing' stamp: 'CamilloBruni 3/20/2011 23:57' prior: 24127862! modifiedBy: modifier modifiers add: modifier. self updateIdentifier.! ! !KMCtrlModifier methodsFor: 'initialization' stamp: 'GuillermoPolito 4/9/2011 23:52' prior: 24129374! initialize super initialize. identifier := #c. name := 'Ctrl'.! ! !KMCtrlModifier methodsFor: 'matching' stamp: 'CamilloBruni 3/19/2011 20:50' prior: 24129214! matchesEvent: aKeyboardEvent ^ aKeyboardEvent controlKeyPressed! ! !KMCommandModifier methodsFor: 'accessing' stamp: 'SeanDeNigris 11/22/2011 18:53' prior: 24125499! eventCode ^ 64.! ! !KMCommandModifier methodsFor: 'initialization' stamp: 'GuillermoPolito 5/31/2011 19:54' prior: 24125777! initialize super initialize. identifier := #m. name := 'Cmd'.! ! !KMCommandModifier methodsFor: 'matching' stamp: 'EstebanLorenzano 3/6/2013 16:41' prior: 24125613! matchesEvent: aKeyboardEvent self flag: #todo. "Command in windows and linux platforms is 'meta' key and do not have any sense (for the environment, right now). In the future we need to create a KMMetaModifier to handle properly this, and keep command as a mac-specific key" (OSPlatform isUnix or: [ OSPlatform isWin32 ]) ifTrue: [ ^ aKeyboardEvent controlKeyPressed ]. ^ aKeyboardEvent commandKeyPressed! ! !DateAndTimeTest methodsFor: 'tests - under design' stamp: 'SvenVanCaekenberghe 3/6/2013 16:41'! testReadFromSpaceBeforeOffset self assert: '2012-07-26 16:38:48 +0200' asDateAndTime offset equals: 2 hour. self assert: '2012-07-26 16:38:48 +02' asDateAndTime offset equals: 2 hour. ! ! !DateAndTimeTest methodsFor: 'tests - under design' stamp: 'SvenVanCaekenberghe 3/6/2013 16:48' prior: 33594172! testReadFromUTCOffset self assert: (DateAndTime readFrom: '2010-01-05T20:33:14.321Z' readStream) offset isZero. self assert: (DateAndTime readFrom: '2010-01-05T20:33:14.321+00' readStream) offset isZero. self assert: (DateAndTime readFrom: '2010-01-05T20:33:14.321+0000' readStream) offset isZero. self assert: (DateAndTime readFrom: '2010-01-05T20:33:14.321+00:00' readStream) offset isZero. ! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/6/2013 16:38' prior: 33594427! readFrom: aStream "Parse and return a new DateAndTime instance from stream, as a Date, a Time and a TimeZone offset." "self readFrom: ' 2013-03-04T23:47:52.876+01:00' readStream" | offset date time ch | date := Date readFrom: aStream. [ aStream peek isDigit ] whileFalse: [ aStream next ]. time := Time readFrom: aStream. aStream skipSeparators. offset := self readTimezoneOffsetFrom: aStream. ^ self year: date year month: date monthIndex day: date dayOfMonth hour: time hour minute: time minute second: time second nanoSecond: time nanoSecond offset: offset " '-1199-01-05T20:33:14.321-05:00' asDateAndTime ' 2002-05-16T17:20:45.1+01:01' asDateAndTime ' 2002-05-16T17:20:45.02+01:01' asDateAndTime ' 2002-05-16T17:20:45.003+01:01' asDateAndTime ' 2002-05-16T17:20:45.0004+01:01' asDateAndTime ' 2002-05-16T17:20:45.00005' asDateAndTime ' 2002-05-16T17:20:45.000006+01:01' asDateAndTime ' 2002-05-16T17:20:45.0000007+01:01' asDateAndTime ' 2002-05-16T17:20:45.00000008-01:01' asDateAndTime ' 2002-05-16T17:20:45.000000009+01:01' asDateAndTime ' 2002-05-16T17:20:45.0000000001+01:01' asDateAndTime ' 2002-05-16T17:20' asDateAndTime ' 2002-05-16T17:20:45' asDateAndTime ' 2002-05-16T17:20:45+01:57' asDateAndTime ' 2002-05-16T17:20:45-02:34' asDateAndTime ' 2002-05-16T17:20:45+00:00' asDateAndTime ' 1997-04-26T01:02:03+01:02:3' asDateAndTime "! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/6/2013 16:22'! readOptionalSeparatorFrom: stream "Read an optional separator (non decimal digit) from stream and return it. Return nil if nothing was read" ^ (stream atEnd or: [ '0123456789' includes: stream peek]) ifTrue: [ nil ] ifFalse: [ stream next ]! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/6/2013 16:33' prior: 33595916! readTimezoneOffsetFrom: stream "Read and return an optional timezone offset in the form of [+|-]hh[[separator]mm[[separator]ss]] or Z from stream as a duration. If there is no offset, return the local offset." | sign hour minute second | (stream peekFor: $Z) ifTrue: [ ^ Duration zero ]. hour := minute := second := 0. ^ ('+-' includes: stream peek) ifTrue: [ sign := stream next = $- ifTrue: [ -1 ] ifFalse: [ 1 ]. hour := self readTwoDigitIntegerFrom: stream. (self readOptionalSeparatorFrom: stream) ifNotNil: [ minute := self readTwoDigitIntegerFrom: stream. (self readOptionalSeparatorFrom: stream) ifNotNil: [ second := Integer readFrom: stream ] ]. Duration seconds: sign * ((hour * 3600) + (minute * 60) + second) ] ifFalse: [ self localOffset ]! ! !DateAndTime class methodsFor: 'input' stamp: 'SvenVanCaekenberghe 3/6/2013 16:34'! readTwoDigitIntegerFrom: stream "Parse and return a decimal number of 2 digits from stream. Fail if that is not possible" | integer | integer := 0. 2 timesRepeat: [ | char | char := stream next. ('0123456789' includes: char) ifFalse: [ self error: 'Decimal digit expected' ]. integer := (integer * 10) + char digitValue ]. ^ integer! ! !KMModifier methodsFor: 'arithmetic' stamp: 'CamilloBruni 3/19/2011 21:25' prior: 24160635! + modifier ^ modifier asShortcut modifiedBy: self! ! !KMModifier methodsFor: 'accessing' stamp: 'CamilloBruni 3/20/2011 23:54' prior: 24160775! identifier ^ identifier! ! !KMModifier methodsFor: 'comparing' stamp: 'CamilloBruni 3/19/2011 20:49' prior: 24160889! matches: aKeyboardEvent self shouldNotImplement! ! !KMModifier methodsFor: 'matching' stamp: 'CamilloBruni 3/19/2011 20:50' prior: 24161027! matchesEvent: aKeyboardEvent self subclassResponsibility! ! !KMModifier methodsFor: 'printing' stamp: 'CamilloBruni 3/19/2011 21:16' prior: 24161174! modifiedBy: modifier ^ KMComposedModifier new modifiedBy: modifier; modifiedBy: self; yourself! ! !KMModifier methodsFor: 'accessing' stamp: 'CamilloBruni 3/20/2011 23:54' prior: 24161365! name ^ name! ! !KMAltModifier methodsFor: 'initialization' stamp: 'CamilloBruni 3/20/2011 23:54' prior: 24103435! initialize super initialize. identifier := #a. name := 'Alt'.! ! !KMAltModifier methodsFor: 'matching' stamp: 'CamilloBruni 3/19/2011 20:50' prior: 24103592! matchesEvent: aKeyboardEvent ^ aKeyboardEvent altKeyPressed! ! !KMShiftModifier methodsFor: 'initialization' stamp: 'CamilloBruni 3/20/2011 23:55' prior: 24176078! initialize super initialize. identifier := #s. name := 'Shift'.! ! !KMShiftModifier methodsFor: 'matching' stamp: 'GuillermoPolito 10/20/2011 15:50' prior: 24175924! matchesEvent: aKeyboardEvent ^ aKeyboardEvent shiftPressed! ! "Kernel"! "KernelTests"! "Keymapping-Shortcuts"! "Morphic"! ----End fileIn----! ----QUIT----an Array(7 March 2013 2:07:08 pm) Pharo.image priorSource: 44074! ----STARTUP----an Array(7 March 2013 3:49:32 pm) as /Users/MAC/Desktop/Dev/Pharo/w20/w20.image! ----QUIT/NOSAVE----an Array(7 March 2013 3:49:41 pm) w20.image priorSource: 73478! ----STARTUP----an Array(7 March 2013 3:49:52 pm) as /Users/MAC/Desktop/Dev/Pharo/w20/w20.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/7/2013 15:46' prior: 33609587! commentForCurrentUpdate ^ 'Release 2.0'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/7/2013 15:46'! script562 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1332.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1369.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1058.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/7/2013 15:46'! update20588 "self new update20588" self withUpdateLog: 'Release 2.0'. self loadTogether: self script562 merge: false. ImageCleaner new cleanUpForRelease. (self confirm: 'Do you wish to advance to Pharo 3.0 Unstable? [Yes] Your system will be marked as Pharo3.0 (Unstable), and you will subsequently receive development updates for 3.0 (unstable stream). [No] Your system will remain at Pharo 2.0.') ifTrue: [SystemVersion newVersion: 'Pharo3.0a'. SystemVersion current date: '7 March 2013'. self inform: 'You may now save this image and retrieve updates again for Pharo2.0a and beyond.'] ifFalse: [SystemVersion newVersion: 'Pharo2.0'.]. . self flushCaches. ! ! MetacelloScriptLoader removeSelector: #writeCS:forUpdate:withName:! MetacelloScriptLoader removeSelector: #writeCS:forUpdate:! MetacelloScriptLoader removeSelector: #workingCopyFromPackageName:! MetacelloScriptLoader removeSelector: #withUpdateLog:! MetacelloScriptLoader removeSelector: #waitingFolderMCZFiles! MetacelloScriptLoader removeSelector: #verifyNewUpdate! MetacelloScriptLoader removeSelector: #updatesListFileName! MetacelloScriptLoader removeSelector: #updatesListFile! MetacelloScriptLoader removeSelector: #updateUpdatesList:! MetacelloScriptLoader removeSelector: #update20075! MetacelloScriptLoader removeSelector: #update20074! MetacelloScriptLoader removeSelector: #update20067! MetacelloScriptLoader removeSelector: #unloadPackageNamed:! MetacelloScriptLoader removeSelector: #unloadPackage:! MetacelloScriptLoader removeSelector: #theScriptLoaderPackageName! MetacelloScriptLoader removeSelector: #taskForcesRepositoryUrlString! MetacelloScriptLoader removeSelector: #shortImageName! MetacelloScriptLoader removeSelector: #setUpdateAndScriptVersionNumbers! MetacelloScriptLoader removeSelector: #setToRepositoriesPassword:to:! MetacelloScriptLoader removeSelector: #savePackage:in:with:! MetacelloScriptLoader removeSelector: #saveLatestScriptLoaderToWaitingFolder! MetacelloScriptLoader removeSelector: #saveLatestScriptLoaderToHome! MetacelloScriptLoader removeSelector: #saveInToReloadCachePackage:with:! MetacelloScriptLoader removeSelector: #saveImageForRunningTests! MetacelloScriptLoader removeSelector: #saveChangedPackagesIntoWaitingFolder! MetacelloScriptLoader removeSelector: #saveAsNewImageWithCurrentReleaseNameToPublish! MetacelloScriptLoader removeSelector: #saveAsNewImageWithCurrentReleaseName! MetacelloScriptLoader removeSelector: #saveAsImageAsTestImage! MetacelloScriptLoader removeSelector: #rootURLString! MetacelloScriptLoader removeSelector: #repositoryTreated! MetacelloScriptLoader removeSelector: #repositoryTaskForces! MetacelloScriptLoader removeSelector: #repositorySqueakTrunk! MetacelloScriptLoader removeSelector: #repositoryMC! MetacelloScriptLoader removeSelector: #repository:! MetacelloScriptLoader removeSelector: #repository39! MetacelloScriptLoader removeSelector: #repository310! MetacelloScriptLoader removeSelector: #repository! MetacelloScriptLoader removeSelector: #removeUpdateMethods! MetacelloScriptLoader removeSelector: #removeScriptMethods! MetacelloScriptLoader removeSelector: #removeAllRepositories! MetacelloScriptLoader removeSelector: #removeAllHTTPRepositories:! MetacelloScriptLoader removeSelector: #publishChanges! MetacelloScriptLoader removeSelector: #prepareNewUpdateSilently! MetacelloScriptLoader removeSelector: #prepareNewUpdate! MetacelloScriptLoader removeSelector: #postUpdate! MetacelloScriptLoader removeSelector: #packagesNotToSavePatternNames! MetacelloScriptLoader removeSelector: #openWindow:label:! MetacelloScriptLoader removeSelector: #newerVersionsIn:! MetacelloScriptLoader removeSelector: #newGenerateScriptTemplateWithCurrentPackages:! MetacelloScriptLoader removeSelector: #newGenerateNewUpdateMethodSilentlyPreLoad:postLoad:! MetacelloScriptLoader removeSelector: #newGenerateNewUpdateMethod! MetacelloScriptLoader removeSelector: #mergePackageFromWaitingFolder! MetacelloScriptLoader removeSelector: #logStream! MetacelloScriptLoader removeSelector: #logContents! MetacelloScriptLoader removeSelector: #log:! MetacelloScriptLoader removeSelector: #loadVersionFromFileNamed:! MetacelloScriptLoader removeSelector: #loadTogether:merge:! MetacelloScriptLoader removeSelector: #loadPackageFromWaitingFolder! MetacelloScriptLoader removeSelector: #loadOneAfterTheOther:merge:! MetacelloScriptLoader removeSelector: #loadLatestUpdateListSilently! MetacelloScriptLoader removeSelector: #loadLatestUpdateList! MetacelloScriptLoader removeSelector: #loadLatestScriptloader! MetacelloScriptLoader removeSelector: #launchUpdateSilently! MetacelloScriptLoader removeSelector: #launchUpdate! MetacelloScriptLoader removeSelector: #latestScriptLoaderPackageIdentificationString! MetacelloScriptLoader removeSelector: #installVersionInfo! MetacelloScriptLoader removeSelector: #installRepository:for:! MetacelloScriptLoader removeSelector: #inboxRepositoryUrlString! MetacelloScriptLoader removeSelector: #inboxRepositoryDefault! MetacelloScriptLoader removeSelector: #inboxRepository! MetacelloScriptLoader removeSelector: #homeRepositoryUrlString! MetacelloScriptLoader removeSelector: #gofer! MetacelloScriptLoader removeSelector: #getLatestUpdateNumber! MetacelloScriptLoader removeSelector: #getLatestScriptNumber! MetacelloScriptLoader removeSelector: #generateScriptTemplateWithCurrentPackages:! MetacelloScriptLoader removeSelector: #generateScriptTemplateWithAllCurrentPackages! MetacelloScriptLoader removeSelector: #generateScriptAndUpdateMethodForNewVersionSilentlyPreLoad:postLoad:! MetacelloScriptLoader removeSelector: #generateScriptAndUpdateMethodForNewVersion! MetacelloScriptLoader removeSelector: #generateNewUpdateMethod! MetacelloScriptLoader removeSelector: #generateCompleteFixList! MetacelloScriptLoader removeSelector: #generateCS:fromUpdate:on:! MetacelloScriptLoader removeSelector: #flushCaches! MetacelloScriptLoader removeSelector: #doneApplyingChangesSilentlyIssues:preLoad:postLoad:! MetacelloScriptLoader removeSelector: #doneApplyingChangesSilentlyComment:preLoad:postLoad:! MetacelloScriptLoader removeSelector: #doneApplyingChanges! MetacelloScriptLoader removeSelector: #deletePackage:! MetacelloScriptLoader removeSelector: #currentVersions! MetacelloScriptLoader removeSelector: #currentUpdateVersionNumber! MetacelloScriptLoader removeSelector: #currentScriptVersionNumber! MetacelloScriptLoader removeSelector: #currentPackages! MetacelloScriptLoader removeSelector: #copyPackagesFromWaitingFolderToHomeRepository! MetacelloScriptLoader removeSelector: #compileScriptMethodWithCurrentPackages:! MetacelloScriptLoader removeSelector: #compileNewUpdateMethodSilentlyPreLoad:postLoad:! MetacelloScriptLoader removeSelector: #compileNewUpdateMethod! MetacelloScriptLoader removeSelector: #commentForCurrentUpdate! MetacelloScriptLoader removeSelector: #checkImageIsUptodateSilently! MetacelloScriptLoader removeSelector: #checkImageIsUptodate! MetacelloScriptLoader removeSelector: #buildConfigurationMapFor:! MetacelloScriptLoader removeSelector: #announceOnMailingList! MetacelloScriptLoader removeSelector: #allManagers! MetacelloScriptLoader removeSelector: #allCurrentPackages! MetacelloScriptLoader removeSelector: #allCurrentDirtyPackages! MetacelloScriptLoader removeSelector: #addRepositoryTreatedToAllPackages! MetacelloScriptLoader removeSelector: #addRepositoryToPackageNamed:! MetacelloScriptLoader removeSelector: #addRepositoryTaskForcesToAllPackages! MetacelloScriptLoader removeSelector: #addRepositorySqueakTrunkToAllPackages! MetacelloScriptLoader removeSelector: #addRepositoryMCToAllPackages! MetacelloScriptLoader removeSelector: #addRepository39ToAllPackages! MetacelloScriptLoader removeSelector: #addRepository310ToAllPackages! MetacelloScriptLoader removeSelector: #addPackage:! MetacelloScriptLoader removeSelector: #addHomeRepositoryToPackageNamed:! MetacelloScriptLoader removeSelector: #addHomeRepositoryToAllPackages! MetacelloScriptLoader removeSelector: #addExtraRepositories! MetacelloScriptLoader removeSelector: #CSForLastUpdateAndPatchUpdatesList:! MetacelloScriptLoader removeSelector: #CSForLastUpdate:! MetacelloScriptLoader class removeSelector: #theme! MetacelloScriptLoader class removeSelector: #showIntegrationMenu! MetacelloScriptLoader class removeSelector: #rootURLString! MetacelloScriptLoader class removeSelector: #resetLogStream! MetacelloScriptLoader class removeSelector: #releaseMenu! MetacelloScriptLoader class removeSelector: #menuCommandOn:! MetacelloScriptLoader class removeSelector: #loadLatestPackage:fromSqueaksource:! MetacelloScriptLoader class removeSelector: #loadLatestPackage:fromRepository:! MetacelloScriptLoader class removeSelector: #loadLatestPackage:from:! MetacelloScriptLoader class removeSelector: #latestVersionOf:location:! MetacelloScriptLoader class removeSelector: #latestSource:location:! MetacelloScriptLoader class removeSelector: #initialize! MetacelloScriptLoader class removeSelector: #hideIntegrationMenu! MetacelloScriptLoader class removeSelector: #gofer! MetacelloScriptLoader class removeSelector: #defaultMCWaitingFolder! MetacelloScriptLoader class removeSelector: #currentlyIntegratingChanges! MetacelloScriptLoader class removeSelector: #currentMajorVersionNumber:! MetacelloScriptLoader class removeSelector: #currentMajorVersionNumber! MetacelloScriptLoader class removeSelector: #checkImageInSyncWithUpdate:! MetacelloScriptLoader class removeSelector: #checkImageInSyncWithUpdate! Smalltalk globals removeClassNamed: #MetacelloScriptLoader! MetacelloLoader removeSelector: #resetPackagesBeforeLastLoad! MetacelloLoader removeSelector: #packagesNotToSavePatternNames! MetacelloLoader removeSelector: #markPackagesBeforeNewCodeIsLoaded! MetacelloLoader removeSelector: #initialize! MetacelloLoader removeSelector: #diffPackages! MetacelloLoader removeSelector: #currentVersionsToBeSaved! MetacelloLoader removeSelector: #currentMajorVersionNumberWithoutDot! MetacelloLoader removeSelector: #currentMajorVersionNumber! MetacelloLoader removeSelector: #currentChangedPackages! MetacelloLoader removeSelector: #allCurrentVersions! MetacelloLoader class removeSelector: #waitingCacheFolder! MetacelloLoader class removeSelector: #packageToBeTestedFolderName! Smalltalk globals removeClassNamed: #MetacelloLoader! HazelKernelAnalyzer removeSelector: #list:! HazelKernelAnalyzer removeSelector: #list! HazelKernelAnalyzer removeSelector: #initialize! HazelKernelAnalyzer removeSelector: #dependentPackages! HazelKernelAnalyzer removeSelector: #dependentClasses! HazelKernelAnalyzer removeSelector: #analyzeMethods:! HazelKernelAnalyzer removeSelector: #analyzeMethod:! HazelKernelAnalyzer removeSelector: #analyzeClassVar:! HazelKernelAnalyzer removeSelector: #analyze! HazelKernelAnalyzer class removeSelector: #using:! HazelKernelAnalyzer class removeSelector: #forPackageNamed:! Smalltalk globals removeClassNamed: #HazelKernelAnalyzer! ConfigurationOfPharo20 removeSelector: #versionForMethodName:! ConfigurationOfPharo20 removeSelector: #version20075PreLoad! ConfigurationOfPharo20 removeSelector: #version20075Kernel:! ConfigurationOfPharo20 removeSelector: #version20075Environment:! ConfigurationOfPharo20 removeSelector: #version20075Core:! ConfigurationOfPharo20 removeSelector: #version20075:! ConfigurationOfPharo20 removeSelector: #testPatterns! ConfigurationOfPharo20 removeSelector: #templateVersionSplit! ConfigurationOfPharo20 removeSelector: #templateVersion! ConfigurationOfPharo20 removeSelector: #templateBaseline! ConfigurationOfPharo20 removeSelector: #requirementsFor:! ConfigurationOfPharo20 removeSelector: #project! ConfigurationOfPharo20 removeSelector: #packages:selectMatch:rejectMatch:! ConfigurationOfPharo20 removeSelector: #packages:selectMatch:! ConfigurationOfPharo20 removeSelector: #newVersion:description:preLoad:postLoad:fromBaseline:! ConfigurationOfPharo20 removeSelector: #newVersion:description:preLoad:postLoad:! ConfigurationOfPharo20 removeSelector: #newVersion:! ConfigurationOfPharo20 removeSelector: #newBaseline:! ConfigurationOfPharo20 removeSelector: #groupsTest! ConfigurationOfPharo20 removeSelector: #groupsKernel! ConfigurationOfPharo20 removeSelector: #groupsEnvironment! ConfigurationOfPharo20 removeSelector: #groupsCore! ConfigurationOfPharo20 removeSelector: #groupsAndPackages! ConfigurationOfPharo20 removeSelector: #generateVersion:fromBaseline:version:groups:! ConfigurationOfPharo20 removeSelector: #generateDoIt:version:with:! ConfigurationOfPharo20 removeSelector: #generateBaseline:version:imports:groups:defineGroups:! ConfigurationOfPharo20 removeSelector: #generateBaseline:version:imports:groups:! ConfigurationOfPharo20 removeSelector: #createPackage:withRequirements:! ConfigurationOfPharo20 removeSelector: #createPackage:with:! ConfigurationOfPharo20 removeSelector: #createPackage:! ConfigurationOfPharo20 removeSelector: #createIncluded:with:! ConfigurationOfPharo20 removeSelector: #createImports:with:! ConfigurationOfPharo20 removeSelector: #createGroup:with:! ConfigurationOfPharo20 removeSelector: #collectionToString:! ConfigurationOfPharo20 removeSelector: #calculateBaselineForVersion:! ConfigurationOfPharo20 removeSelector: #baseline20Kernel:! ConfigurationOfPharo20 removeSelector: #baseline20Core:! ConfigurationOfPharo20 removeSelector: #baseline20:! ConfigurationOfPharo20 removeSelector: #allPackages! ConfigurationOfPharo20 class removeSelector: #validate! ConfigurationOfPharo20 class removeSelector: #project! ConfigurationOfPharo20 class removeSelector: #loadDevelopment! ConfigurationOfPharo20 class removeSelector: #loadBleedingEdge! ConfigurationOfPharo20 class removeSelector: #load! ConfigurationOfPharo20 class removeSelector: #isMetacelloConfig! ConfigurationOfPharo20 class removeSelector: #ensureMetacelloBaseConfiguration! ConfigurationOfPharo20 class removeSelector: #ensureMetacello! ConfigurationOfPharo20 class removeSelector: #baseConfigurationClassIfAbsent:! ConfigurationOfPharo20 class removeSelector: #DevelopmentSupport! Smalltalk globals removeClassNamed: #ConfigurationOfPharo20! ScriptLoader removeSelector: #update20586! ScriptLoader removeSelector: #update20585! ScriptLoader removeSelector: #update20584! ScriptLoader removeSelector: #update20583! ScriptLoader removeSelector: #update20582! ScriptLoader removeSelector: #update20581! ScriptLoader removeSelector: #script561! ScriptLoader removeSelector: #script560! ScriptLoader removeSelector: #script559! ScriptLoader removeSelector: #script558! ScriptLoader removeSelector: #script557! ScriptLoader removeSelector: #script556! "ScriptLoader20"! ----End fileIn----! ----QUIT----an Array(7 March 2013 3:50:47 pm) w20.image priorSource: 73478! ----STARTUP----an Array(7 March 2013 3:51:38 pm) as /Users/MAC/Desktop/Dev/Pharo/w20/w20.image! | processes | processes := Process allInstances select: [ :p | | ctx | ctx := p suspendedContext. ctx notNil and: [ ctx method == (Delay>>#wait) and: [ ctx sender sender sender method selector == #secondsWhenClockTicks ] ]]. processes do: #terminate! ----QUIT----an Array(7 March 2013 3:53:03 pm) w20.image priorSource: 98147! ----STARTUP----an Array(7 March 2013 3:53:55 pm) as /Users/MAC/Desktop/Dev/Pharo/w20/w20.image! ----QUIT/NOSAVE----an Array(7 March 2013 3:54:04 pm) w20.image priorSource: 98586! ----STARTUP----an Array(8 March 2013 3:21:21 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/8/2013 15:08' prior: 33628363! commentForCurrentUpdate ^ 'Issue 7660: comments in isAbstractClass are wrong https://code.google.com/p/pharo/issues/detail?id=7660 Issue 7659: use more efficient setSourcePointer: in CompiledMethod https://code.google.com/p/pharo/issues/detail?id=7659 (almost the last one :) '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/8/2013 15:08'! script563 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1369.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1058.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/8/2013 15:08'! update20589 "self new update20589" self withUpdateLog: 'Issue 7660: comments in isAbstractClass are wrong https://code.google.com/p/pharo/issues/detail?id=7660 Issue 7659: use more efficient setSourcePointer: in CompiledMethod https://code.google.com/p/pharo/issues/detail?id=7659 (almost the last one :) '. self loadTogether: self script563 merge: false. self flushCaches. ! ! "ScriptLoader20"! !Class methodsFor: 'testing' stamp: 'EstebanLorenzano 3/8/2013 14:33' prior: 19087215! isAbstractClass self deprecated: 'Use hasAbstractMethods' on: '16 December 2012' in: #Pharo2.0. ^ (self allMethods anySatisfy: [:cm | cm sendsSelector: #subclassResponsibility ]) or: [ self class allMethods anySatisfy: [:cm | cm sendsSelector: #subclassResponsibility ] ]! ! !ClassDescription methodsFor: 'testing' stamp: 'EstebanLorenzano 3/8/2013 14:33' prior: 19257430! isAbstractClass self deprecated: 'Use hasAbstractMethods' on: '16 December 2012' in: #Pharo2.0. self subclassResponsibility! ! !Metaclass methodsFor: 'testing' stamp: 'EstebanLorenzano 3/8/2013 14:33' prior: 26327229! isAbstractClass self deprecated: 'Use hasAbstractMethods' on: '16 December 2012' in: #Pharo2.0. ^ self theNonMetaClass isAbstractClass! ! !CompiledMethod methodsFor: 'source code management' stamp: 'EstebanLorenzano 3/8/2013 15:04' prior: 19837973! setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing scrPointer, and then become it." | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer. "If possible do a replace in place as an optimization" (self trailer class == trailer class and: [ self size = copy size ]) ifTrue: [ | start | start := self endPC + 1. self replaceFrom: start to: self size with: copy startingAt: start ] ifFalse: [ self becomeForward: copy ]. ^ self ! ! "Kernel"! ----End fileIn----! ----QUIT----an Array(8 March 2013 3:21:26 pm) Pharo.image priorSource: 98586! ----STARTUP----an Array(8 March 2013 3:21:27 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(8 March 2013 3:21:27 pm) Pharo-20589.image priorSource: 110604! ----STARTUP----an Array(13 March 2013 11:05:31 am) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/13/2013 10:57' prior: 33653466! commentForCurrentUpdate ^ 'Issue 7345: DNU with Glamour: PaginatedMorphTreeMorph>>setSelectedMorph: https://code.google.com/p/pharo/issues/detail?id=7345 https://pharo.fogbugz.com/f/cases/7282 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/13/2013 10:57'! script564 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-StephaneDucasse.29.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1058.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/13/2013 10:57'! update20590 "self new update20590" self withUpdateLog: 'Issue 7345: DNU with Glamour: PaginatedMorphTreeMorph>>setSelectedMorph: https://code.google.com/p/pharo/issues/detail?id=7345 https://pharo.fogbugz.com/f/cases/7282 '. self loadTogether: self script564 merge: false. self flushCaches. ! ! "ScriptLoader20"! !PaginatedMorphTreeMorph methodsFor: 'updating' stamp: 'ThierryGoubier 3/8/2013 14:50' prior: 29045493! update: aSymbol aSymbol == #pageSize ifTrue: [ ^ self pageSize: model pageSize ]. aSymbol == #chunkSize ifTrue: [ ^ self chunkSize: model chunkSize ]. self pager isNil ifTrue: [ ^ super update: aSymbol ]. ((aSymbol isKindOf: Array) and: [ aSymbol size > 1 and: [ aSymbol first == self nodeListSelector and: [ aSymbol second == #openItemPath ] ] ]) ifTrue: [ | rest | rest := aSymbol allButFirst: 2. [ rest notEmpty ] whileTrue: [ | i res | res := (1 to: self nodeList size) select: [ :li | (self nodeList at: li) item = rest first ]. res isEmpty ifTrue: [ ^ self ]. self pager nextPage: res first. (self allNodeMorphs at: 1 ifAbsent: [ ^ self ]) openItemPath: {(rest first)}. rest := rest copyWithoutFirst ]. ^ self ]. "allow directed path opening where multiple trees exist" ^ super update: aSymbol! ! "Morphic"! ----End fileIn----! ----QUIT----an Array(13 March 2013 11:05:37 am) Pharo.image priorSource: 110778! ----STARTUP----an Array(13 March 2013 11:05:39 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(13 March 2013 11:05:39 am) Pharo-20590.image priorSource: 121837! ----STARTUP----an Array(14 March 2013 2:33:30 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 3/14/2013 14:31' prior: 33665492! commentForCurrentUpdate ^ '10014 World menu > System > Switch User serves no purpose https://pharo.fogbugz.com/f/cases/10014/World-menu-System-Switch-User-serves-no-purpose 10004 SmalltalkImage current reportCPUandRAM > DNU https://pharo.fogbugz.com/f/cases/10004/SmalltalkImage-current-reportCPUandRAM-DNU '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 3/14/2013 14:31'! script565 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.63.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-MarcusDenker.88.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 3/14/2013 14:31'! update20591 "self new update20591" self withUpdateLog: '10014 World menu > System > Switch User serves no purpose https://pharo.fogbugz.com/f/cases/10014/World-menu-System-Switch-User-serves-no-purpose 10004 SmalltalkImage current reportCPUandRAM > DNU https://pharo.fogbugz.com/f/cases/10004/SmalltalkImage-current-reportCPUandRAM-DNU '. self loadTogether: self script565 merge: false. self flushCaches. ! ! "ScriptLoader20"! !UsersManager class methodsFor: 'menu' stamp: 'MarcusDenker 3/14/2013 14:27' prior: 54606444! switchUsers: aBuilder "I build a menu" "" (aBuilder item: #'Switch User') parent: #System; order: 1.5; icon: (UITheme current iconNamed: #userIcon); action: [ self default openSwitchUsers ]! ! !MessageTally methodsFor: 'initialize-release' stamp: 'MarcusDenker 3/14/2013 14:28' prior: 25712939! spyAllEvery: millisecs on: aBlock "Create a spy and spy on the given block at the specified rate." "Spy all the system processes" | myDelay time0 | aBlock isBlock ifFalse: [ self error: 'spy needs a block here' ]. self class: aBlock receiver class method: aBlock method. "set up the probe" myDelay := Delay forMilliseconds: millisecs. time0 := Time millisecondClockValue. gcStats := Smalltalk vm getParameters. Timer ifNotNil: [ self error: 'it seems a tally is already running' ]. Timer := [ [true] whileTrue: [ | startTime observedProcess | startTime := Time millisecondClockValue. myDelay wait. observedProcess := Processor preemptedProcess. self tally: observedProcess suspendedContext in: observedProcess "tally can be > 1 if ran a long primitive" by: (Time millisecondClockValue - startTime) // millisecs]. nil] newProcess. Timer priority: Processor timingPriority-1. "activate the probe and evaluate the block" Timer resume. ^ aBlock ensure: [ "cancel the probe and return the value" "Could have already been terminated. See #terminateTimerProcess" Timer ifNotNil: [ Timer terminate. Timer := nil ]. "Collect gc statistics" Smalltalk vm getParameters keysAndValuesDo: [ :idx :gcVal | gcVal isNumber ifTrue: [ gcStats at: idx put: (gcVal - (gcStats at: idx))]]. time := Time millisecondClockValue - time0]! ! !MessageTally methodsFor: 'initialize-release' stamp: 'MarcusDenker 3/14/2013 14:29' prior: 25715995! spyEvery: millisecs onProcess: aProcess forMilliseconds: msecDuration "Create a spy and spy on the given process at the specified rate." | myDelay time0 endTime observedProcess sem | (aProcess isKindOf: Process) ifFalse: [self error: 'spy needs a Process here']. self class: aProcess suspendedContext receiver class method: aProcess suspendedContext method. "set up the probe" observedProcess := aProcess. myDelay := Delay forMilliseconds: millisecs. time0 := Time millisecondClockValue. endTime := time0 + msecDuration. sem := Semaphore new. gcStats := Smalltalk vm getParameters. Timer ifNotNil: [ self error: 'it seems a tally is already running' ]. Timer := [ [ | startTime | startTime := Time millisecondClockValue. myDelay wait. self tally: Processor preemptedProcess suspendedContext in: (observedProcess == Processor preemptedProcess ifTrue: [ observedProcess ] ifFalse: [nil]) "tally can be > 1 if ran a long primitive" by: (Time millisecondClockValue - startTime) // millisecs. startTime < endTime ] whileTrue. sem signal. ] newProcess. Timer priority: Processor timingPriority-1. "activate the probe and evaluate the block" Timer resume. "activate the probe and wait for it to finish" sem wait. "Collect gc statistics" Smalltalk vm getParameters keysAndValuesDo: [ :idx :gcVal | gcVal isNumber ifTrue: [gcStats at: idx put: (gcVal - (gcStats at: idx)) ] ]. time := Time millisecondClockValue - time0! ! "KeyChain"! "Tools"! ----End fileIn----! ----QUIT----an Array(14 March 2013 2:33:35 pm) Pharo.image priorSource: 122016! ----STARTUP----an Array(14 March 2013 2:33:36 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(14 March 2013 2:33:36 pm) Pharo-20591.image priorSource: 135722! ----STARTUP----an Array(15 March 2013 4:09:30 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/15/2013 16:06' prior: 33676727! commentForCurrentUpdate ^ '10017 ProtocolCLient do not propagate the erros from the server https://pharo.fogbugz.com/f/cases/10017 7627 FileReference>>deleteAll follows symlinks https://pharo.fogbugz.com/f/cases/7627 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/15/2013 16:06'! script566 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.65.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/15/2013 16:06'! update20592 "self new update20592" self withUpdateLog: '10017 ProtocolCLient do not propagate the erros from the server https://pharo.fogbugz.com/f/cases/10017 7627 FileReference>>deleteAll follows symlinks https://pharo.fogbugz.com/f/cases/7627 '. self loadTogether: self script566 merge: false. self flushCaches. ! ! "ScriptLoader20"! !DeleteVisitor commentStamp: 'cwp 11/18/2009 12:30' prior: 20649135! I delete the directory tree that I visit. I use the PostorderGuide so that I can delete files before deleting their containing directories.! !DeleteVisitor commentStamp: 'cwp 11/18/2009 12:30' prior: 33700502! I delete the directory tree that I visit. I use the PostorderGuide so that I can delete files before deleting their containing directories.! !DeleteVisitor methodsFor: 'visiting' stamp: 'SeanDeNigris 3/12/2013 10:46' prior: 20649358! visit: aReference root := aReference. PostorderGuide show: aReference to: self.! ! !DeleteVisitor methodsFor: 'visiting' stamp: 'SeanDeNigris 3/12/2013 10:58' prior: 20649491! visitReference: anEntry | reference relativePath | reference := anEntry reference. relativePath := reference relativeTo: root. relativePath segments inject: root into: [ :ref :segment | | ancestor | ancestor := ref / segment. (ancestor isDirectory and: [ ancestor isSymlink ]) ifTrue: [ ^ self error: ancestor fullName, ' is a symlinked directory. Skipping ', (reference relativeTo: ancestor) asString ] ]. reference delete.! ! !ProtocolClient methodsFor: 'private protocol' stamp: 'BenjaminVanRyseghem 3/14/2013 14:29' prior: 30081951! checkResponse self checkResponseOnError: [:response | (TelnetProtocolError protocolInstance: self) signal: response] onWarning: [:response | (TelnetProtocolError protocolInstance: self) signal: response]! ! "FileSystem-Core"! "Network-Protocols"! ----End fileIn----! ----QUIT----an Array(15 March 2013 4:09:34 pm) Pharo.image priorSource: 135899! ----STARTUP----an Array(15 March 2013 4:09:35 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(15 March 2013 4:09:35 pm) Pharo-20592.image priorSource: 147526! ----STARTUP----an Array(15 March 2013 4:40:30 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/15/2013 16:37' prior: 33690613! commentForCurrentUpdate ^ '10027 Failing Test: FileReferenceTest>>#testDeleteAl https://pharo.fogbugz.com/f/cases/10027 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/15/2013 16:37'! script567 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-MarcusDenker.62.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/15/2013 16:37'! update20593 "self new update20593" self withUpdateLog: '10027 Failing Test: FileReferenceTest>>#testDeleteAl https://pharo.fogbugz.com/f/cases/10027 '. self loadTogether: self script567 merge: false. self flushCaches. ! ! "ScriptLoader20"! !DeleteVisitor commentStamp: 'cwp 11/18/2009 12:30' prior: 33700712! I delete the directory tree that I visit. I use the PostorderGuide so that I can delete files before deleting their containing directories.! !DeleteVisitor commentStamp: 'cwp 11/18/2009 12:30' prior: 33712108! I delete the directory tree that I visit. I use the PostorderGuide so that I can delete files before deleting their containing directories.! !DeleteVisitor methodsFor: 'visiting' stamp: 'EstebanLorenzano 3/15/2013 16:33' prior: 33700946! visit: aReference PostorderGuide show: aReference to: self! ! !DeleteVisitor methodsFor: 'visiting' stamp: 'EstebanLorenzano 3/15/2013 16:33' prior: 33701125! visitReference: anEntry anEntry reference delete! ! "FileSystem-Core"! ----End fileIn----! ----QUIT----an Array(15 March 2013 4:40:32 pm) Pharo.image priorSource: 147703! ----STARTUP----an Array(15 March 2013 4:40:33 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(15 March 2013 4:40:33 pm) Pharo-20593.image priorSource: 158377! ----STARTUP----an Array(28 March 2013 12:31:23 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 3/28/2013 12:29' prior: 33702417! commentForCurrentUpdate ^ '10123 Bug in warning in CriticBrowser https://pharo.fogbugz.com/f/cases/10123'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 3/28/2013 12:29'! script568 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1337.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.142.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.434.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.796.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 3/28/2013 12:29'! update20594 "self new update20594" self withUpdateLog: '10123 Bug in warning in CriticBrowser https://pharo.fogbugz.com/f/cases/10123'. self loadTogether: self script568 merge: false. self flushCaches. ! ! "ScriptLoader20"! !SingleRuleCriticBrowser methodsFor: 'private' stamp: 'StephaneDucasse 3/25/2013 12:38' prior: 33360072! criticsOf: aRule cache ifNil: [^ {}]. criticsModel items: ((cache criticsOf: aRule) sorted: [ :a :b| a name < b name]).! ! "Manifest-CriticBrowser"! ----End fileIn----! ----QUIT----an Array(28 March 2013 12:31:26 pm) Pharo.image priorSource: 158554! ----STARTUP----an Array(28 March 2013 12:31:27 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(28 March 2013 12:31:27 pm) Pharo-20594.image priorSource: 168714! ----STARTUP----an Array(28 March 2013 12:33:26 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(28 March 2013 12:33:26 pm) Pharo.image priorSource: 168893! ----STARTUP----an Array(28 March 2013 12:33:27 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(28 March 2013 12:33:27 pm) Pharo-20594.image priorSource: 169082! ----STARTUP----an Array(2 April 2013 11:45:27 am) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 4/2/2013 11:41' prior: 33713269! commentForCurrentUpdate ^ '10196 Change shortcuts default settings of 2.0 to the traditional ones UI: Misc | Milestone: Pharo2.0 https://pharo.fogbugz.com/f/cases/10196 10195 Replace ugly Keymappings API on:do: https://pharo.fogbugz.com/f/cases/10195 10194 Backport to 2.0: special objects array recreation crash https://pharo.fogbugz.com/f/cases/10194 10185 Backport 2.0: 10173 ClassBuilder cannot safely modify a class why using it https://pharo.fogbugz.com/f/cases/10185 10174 Backport 2.0 Issue 10162: multiple selection of methods in method pane ... https://pharo.fogbugz.com/f/cases/10174 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 4/2/2013 11:41'! script569 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1341.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-EstebanLorenzano.437.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 4/2/2013 11:42'! update20595 "self new update20595" Nautilus useOldStyleKeys: true. self withUpdateLog: '10196 Change shortcuts default settings of 2.0 to the traditional ones UI: Misc | Milestone: Pharo2.0 https://pharo.fogbugz.com/f/cases/10196 10195 Replace ugly Keymappings API on:do: https://pharo.fogbugz.com/f/cases/10195 10194 Backport to 2.0: special objects array recreation crash https://pharo.fogbugz.com/f/cases/10194 10185 Backport 2.0: 10173 ClassBuilder cannot safely modify a class why using it https://pharo.fogbugz.com/f/cases/10185 10174 Backport 2.0 Issue 10162: multiple selection of methods in method pane ... https://pharo.fogbugz.com/f/cases/10174 '. self loadTogether: self script569 merge: false. self flushCaches. ! ! "ScriptLoader20"! !ClassBuilder methodsFor: 'class mutation' stamp: 'GuillermoPolito 4/2/2013 11:20' prior: 19118722! update: oldClass to: newClass "Convert oldClass, all its instances and possibly its meta class into newClass, instances of newClass and possibly its meta class. The process is surprisingly simple in its implementation and surprisingly complex in its nuances and potentially bad side effects. We can rely on two assumptions (which are critical): #1: The method #updateInstancesFrom: will not create any lasting pointers to 'old' instances ('old' is quote on quote since #updateInstancesFrom: will do a become of the old vs. the new instances and therefore it will not create pointers to *new* instances before the #become: which are *old* afterwards) #2: The non-preemptive execution of the critical piece of code guarantees that nobody can get a hold by 'other means' (such as process interruption and reflection) on the old instances. Given the above two, we know that after #updateInstancesFrom: there are no pointer to any old instances. After the forwarding become there will be no pointers to the old class or meta class either. Meaning that if we throw in a nice fat GC at the end of the critical block, everything will be gone (but see the comment right there). There's no need to worry. " | meta | meta := oldClass isMeta. "Note: Everything from here on will run without the ability to get interrupted to prevent any other process to create new instances of the old class." [ "Note: The following removal may look somewhat obscure and needs an explanation. When we mutate the class hierarchy we create new classes for any existing subclass. So it may look as if we don't have to remove the old class from its superclass. However, at the top of the hierarchy (the first class we reshape) that superclass itself is not newly created so therefore it will hold both the oldClass and newClass in its (obsolete or not) subclasses. Since the #become: below will transparently replace the pointers to oldClass with newClass the superclass would have newClass in its subclasses TWICE. With rather unclear effects if we consider that we may convert the meta-class hierarchy itself (which is derived from the non-meta class hierarchy). Due to this problem ALL classes are removed from their superclass just prior to converting them. Here, breaking the superclass/subclass invariant really doesn't matter since we will effectively remove the oldClass (become+GC) just a few lines below." oldClass superclass removeSubclass: oldClass. oldClass superclass removeObsoleteSubclass: oldClass. "make sure that the VM cache is clean" oldClass methodDict keysDo: [:aSelector | aSelector flushCache]. "Convert the instances of oldClass into instances of newClass" newClass updateInstancesFrom: oldClass. meta ifTrue:[oldClass becomeForward: newClass] ifFalse:[(Array with: oldClass with: oldClass class) elementsForwardIdentityTo: (Array with: newClass with: newClass class)]. Smalltalk garbageCollect. "Warning: Read this before you even think about removing the GC. Yes, it slows us down. Quite heavily if you have a large image. However, there's no good and simple alternative here, since unfortunately, #become: does change class pointers. What happens is that after the above become all of the instances of the old class will have a class pointer identifying them as instances of newClass. If we get our hands on any of these instances we will break immediately since their expected instance layout (that of its class, e.g., newClass) will not match their actual instance layout (that of oldClass). And getting your hands on any of those instances is really simple - just reshaping one class two times in rapid succession will do it. Reflection techniques, interrupts, etc. will only add to this problem. In the case of Metaclass things get even worse since when we recompile the entire class hierarchy we will recompile both, Metaclass and its instances (and some of its instances will have the old and some the new layout). The only easy solution to this problem would be to 'fix up' the class pointers of the old instances to point to the old class (using primitiveChangeClassTo:). But this won't work either - as we do a one-way become we would have to search the entire object memory for the oldClass and couldn't even clearly identify it unless we give it some 'special token' which sounds quite error-prone. If you really need to get rid of the GC here are some alternatives: On the image level, one could create a copy of the oldClass before becoming it into the new class and, after becoming it, 'fix up' the old instances. That would certainly work but it sounds quite complex, as we need to make sure we're not breaking any of the superclass/subclass meta/non-meta class variants. Alternatively, fix up #becomeForward on the VM-level to 'dump the source objects' of #become. This would be quite doable (just 'convert' them into a well known special class such as bitmap) yet it has problems if (accidentally or not) one of the objects in #become: appears on 'both sides of the fence' (right now, this will work ... in a way ... even though the consequences are unclear). Another alternative is to provide a dedicated primitive for this (instead of using it implicitly in become) which would allow us to dump all the existing instances right here. This is equivalent to a more general primitiveChangeClassTo: and might be worthwhile but it would likely have to keep in mind the differences between bits and pointer thingies etc. Since all of the alternatives seem rather complex and magical compared to a straight-forward GC it seems best to stick with the GC solution for now. If someone has a real need to fix this problem, that person will likely be motivated enough to check out the alternatives. Personally I'd probably go for #1 (copy the old class and remap the instances to it) since it's a solution that could be easily reverted from within the image if there's any problem with it." ] valueUnpreemptively. ! ! !Morph methodsFor: '*Keymapping-Core' stamp: 'GuillermoPolito 4/2/2013 11:19' prior: 26585998! on: aShortcut do: anAction self kmDispatcher on: aShortcut asShortcut do: anAction! ! !Morph methodsFor: '*Keymapping-Core' stamp: 'GuillermoPolito 4/2/2013 11:06'! onKeyCombination: aShortcut do: anAction self kmDispatcher on: aShortcut asShortcut do: anAction! ! !MethodWidget methodsFor: 'private' stamp: 'NorbertHartl 3/28/2013 12:46' prior: 26518558! initialize super initialize. methodsSelection := IdentityDictionary new.! ! !SmalltalkImage methodsFor: 'special objects' stamp: 'GuillermoPolito 4/2/2013 10:58' prior: 50346789! newSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Pharo virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | newArray := Array new: 56. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self globals associationAt: #Processor). "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. newArray at: 10 put: Float. newArray at: 11 put: MethodContext. newArray at: 12 put: nil. "Was BlockContext" newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. newArray at: 18 put: (self specialObjectsArray ifNil: [ Semaphore new ] ifNotNil: [ self specialObjectsArray at: 18 ]). "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 nil 0 nil 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self primitiveGetSpecialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. "A 32-element array with up to 32 classes that have compact instances. Cog inlines table into machine code class lookup so do not regenerate it." newArray at: 29 put: self compactClassesArray. newArray at: 30 put: (self specialObjectsArray ifNil: [ Semaphore new ] ifNotNil: [ self specialObjectsArray at: 30 ]). "(delay Semaphore)" newArray at: 31 put: (self specialObjectsArray ifNil: [ Semaphore new ] ifNotNil: [ self specialObjectsArray at: 31 ]). "(user interrupt Semaphore)" "Prototype instances that can be copied for fast initialization" newArray at: 32 put: (Float new: 2). newArray at: 33 put: (LargePositiveInteger new: 4). newArray at: 34 put: 0@0. newArray at: 35 put: #cannotInterpret:. "Note: This must be fixed once we start using context prototypes (yeah, right)" "(MethodContext new: CompiledMethod fullFrameSize)." newArray at: 36 put: (self primitiveGetSpecialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. "(BlockContext new: CompiledMethod fullFrameSize)." newArray at: 38 put: (self primitiveGetSpecialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" newArray at: 39 put: (self primitiveGetSpecialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" "finalization Semaphore" newArray at: 42 put: (self specialObjectsArray ifNil: [ Semaphore new ] ifNotNil: [ (self specialObjectsArray at: 42) ifNil: [ Semaphore new ] ]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" "newArray at: 51 put: #attemptToAssign:withIndex:." newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). newArray at: 54 put: #invokeCallback:stack:registers:jmpbuf:. newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). "Weak reference finalization" newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). ^newArray! ! SmalltalkImage removeSelector: #newCompactClassesArray! "Kernel"! "Keymapping-Core"! "Nautilus"! "System-Support"! ----End fileIn----! ----QUIT----an Array(2 April 2013 11:45:37 am) Pharo.image priorSource: 169261! ----STARTUP----an Array(2 April 2013 11:45:38 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(2 April 2013 11:45:38 am) Pharo-20595.image priorSource: 192494! ----STARTUP----an Array(2 April 2013 1:06:26 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 4/2/2013 13:02' prior: 33723975! commentForCurrentUpdate ^ 'Prepared for production.'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 4/2/2013 13:02'! script570 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1341.mcz KernelTests-EstebanLorenzano.476.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-EstebanLorenzano.437.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 4/2/2013 13:03'! update20596 "self new update20596" self withUpdateLog: 'Prepared for production.'. self loadTogether: self script570 merge: false. ImageCleaner cleanUpForRelease. (Process allInstances select: [ :p | | ctx | ctx := p suspendedContext. ctx notNil and: [ ctx method == (Delay>>#wait) and: [ ctx sender sender sender method selector == #secondsWhenClockTicks ] ] ]) do: #terminate. ((Workspace openContents: '" Pharo 2.0 ======= Welcome to Pharo, a clean, innovative, free, and open-source Smalltalk-like environment. Pharo 2.0 comes with a whole set of packages you can use to explore the system and develop your own applications. But maybe you need other stuff or feel more comfortable using a tool you already know. To easily load projects, you can open the Configurations Browser by executing:" MetacelloConfigurationBrowser open. "You can also open the World menu (just click the desktop) and go to Tools, then Configuration Browser. You can find information about Pharo on http://www.pharo-project.org. In particular, you may be interested in: - Joining us and getting help http://www.pharo-project.org/community - Getting the Pharo By Example book (available as a free PDF): http://www.pharobyexample.org - Watching the screencasts http://www.pharocasts.com - Reporting problems http://www.pharo-project.org/community/issue-tracking - Reading the forth coming book http://rmod.lille.inria.fr/pbe2 - Reading the Pharo vision document http://bit.ly/HNkEru About this release --------------------------- All in all, there were over 1600 issues treated in the issue tracker and 1350 improvements integrated into 2.0. http://code.google.com/p/pharo/issues/list?can=1&q=Milestone%3D2.0+status%3AIntegrated Read it again, yes 1350 is huge, take two minutes and have a look at the list of improvements!! Now you got the feel of the effort. And this was a true community effort. It is possible because people worldwide helped!! We want to deeply thank them. We want to thank Inria for its constant support, in particular for the salary of Igor Stasenko and Esteban Lorenzano, and for the help in the infrastructure. We have accomplished this huge task for a better system because we were together. Do not forget that we are working on a consortium to support our system: - http://consortium.pharo.org (for companies and organizations) - http://association.pharo.org (for individuals) Our goal is to build a system so that we can make a living with our creativity and programming skills. Read the Pharo vision document and join!! Thanks a lot for your participation, energy and fun. The Pharo Team Summarized issues for 2.0 ================== UI --- - Spec - Widget enhancements - Layout improvements/cleanups - Keybindings - New icons (famfam) - Growl style notifications - Revamp progress bar Developer tools ------------------------ - Nautilus browser - Critics browser - Improved version diff browsing - Spotlight - Revamp Code Completion and smart chars - Interactive navigation using ctrl/cmd+click over classes/methods - Shout themes - Andreas profiler Networking ----------------- - Update Zinc - Zodiac (SSL) System ----------- - System Announcer - RPackage replacing PackageInfo - Command line tools / Headless mode - Native boost - Update Ring metamodel - Fuel serializer - Freetype fonts Kernel ---------- - DateAndTime refactoring - Updated FileSystem and replaced FileDirectory VM -- - Latests cog builds - SSLPlugin - FilePlugin enhancements - SocketPlugin fixes - Included libraries: freetype2, cairo Cleanups ------------- - FileDirectory removed (replaced by FileSystem) - SmartRefStream and ReferenceStream removed (replaced by Fuel) - PackageInfo deprecated (replaced by RPackage) Other ------- - Zeroconf scripts - Continuous Integration for every aspect of our release process. Not all the changes are reported here, but this is to give you an impression, you can find better explanation here: https://code.google.com/p/pharo/wiki/ActionsInPharo20 "' label: 'Welcome to Pharo 2.0')) containingWindow bounds: ((130.0@141.0) corner: (820.0@590.0)). self flushCaches. ! ! "ScriptLoader20"! ----End fileIn----! ----QUIT----an Array(2 April 2013 1:06:31 pm) Pharo.image priorSource: 192671! ----STARTUP----an Array(2 April 2013 1:06:32 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(2 April 2013 1:06:32 pm) Pharo-20596.image priorSource: 206468! ----STARTUP----an Array(11 April 2013 1:01:26 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 4/11/2013 12:59' prior: 33747383! commentForCurrentUpdate ^ '10249 Backport 2.0: Red Light when all test are green https://pharo.fogbugz.com/f/cases/10249 10230 backport 2.0: 10229 Fix sender of #copyWithTempsFromMethodNode: https://pharo.fogbugz.com/f/cases/10230 10200 Date instances dayOfWeek wrong https://pharo.fogbugz.com/f/cases/10200 10179 backport 2.0: 10038 Wrong deprecated message https://pharo.fogbugz.com/f/cases/10179 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 4/11/2013 12:59'! script571 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1344.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 4/11/2013 12:59'! update20597 "self new update20597" self withUpdateLog: '10249 Backport 2.0: Red Light when all test are green https://pharo.fogbugz.com/f/cases/10249 10230 backport 2.0: 10229 Fix sender of #copyWithTempsFromMethodNode: https://pharo.fogbugz.com/f/cases/10230 10200 Date instances dayOfWeek wrong https://pharo.fogbugz.com/f/cases/10200 10179 backport 2.0: 10038 Wrong deprecated message https://pharo.fogbugz.com/f/cases/10179 '. self loadTogether: self script571 merge: false. self flushCaches. ! ! "ScriptLoader20"! !CompiledMethod methodsFor: 'source code management' stamp: 'MarcusDenker 4/8/2013 10:39' prior: 19836725! putSource: sourceStr fromParseNode: methodNode inFile: fileIndex withPreamble: preambleBlock "Store the source code for the receiver on an external file. If no sources are available, i.e., SourceFile is nil, then store temp names for decompilation at the end of the method. If the fileIndex is 1, print on *.sources; if it is 2, print on *.changes, in each case, storing a 4-byte source code pointer at the method end." | file remoteString | (SourceFiles == nil or: [(file := SourceFiles at: fileIndex) == nil]) ifTrue: [^self becomeForward: (self copyWithSource: methodNode)]. Smalltalk assureStartupStampLogged. file setToEnd. preambleBlock value: file. "Write the preamble" remoteString := RemoteString newString: sourceStr onFileNumber: fileIndex toFile: file. file nextChunkPut: ' '. InMidstOfFileinNotification signal ifFalse: [file flush]. self setSourcePosition: remoteString position inFile: fileIndex! ! !DateAndTimeTest methodsFor: 'tests' stamp: 'AndyKellens 4/4/2013 09:33'! testDayOfWeekWithUTC | date | "Calculating the day of week should take into account the UTC offset" date := DateAndTime julianDayNumber: 2456385 offset:(Duration hours:2). "Internally, this date gets represented as the julian day 2456384 with seconds 79200 and offset 2 hours" "When asking for the day of week, the offset should be taken into account to return the correct day of week" self assert: (date dayOfWeek = 3). ! ! !DateAndTime methodsFor: 'accessing' stamp: 'AndyKellens 4/3/2013 18:09' prior: 20340074! dayOfWeek "Sunday=1, ... , Saturday=7" ^ (self julianDayNumber + 1 rem: 7) + 1! ! !Object methodsFor: 'error handling' stamp: 'MarcusDenker 3/26/2013 13:17' prior: 28605797! deprecated: anExplanationString "this is not itself deprecated, but a compatibility method for old-style deprecation" (Deprecation method: thisContext sender method explanation: anExplanationString on: 'unknown' in: 'unknown') signal! ! !AbstractNautilusUI methodsFor: 'private' stamp: 'CamilleTeruel 4/5/2013 16:34' prior: 17368093! runTestsOfClass: aClass notifying: aBoolean | methods blockToEvaluate | methods := aClass methodDict values select: [ :method | method isTestMethod ] thenCollect: [:e | e selector ]. blockToEvaluate := [ |result | aClass resetHistory. result := (aClass addToSuite: TestSuite new fromMethods: methods) run. result updateResultsInHistory. ClassesIconsCache removeKey: aClass ifAbsent: []. testSemaphore signal. ]. aBoolean ifTrue: [ blockToEvaluate forkAt: Processor userBackgroundPriority ] ifFalse: [ blockToEvaluate value ]. testSemaphore wait. aBoolean ifTrue: [ | color | aClass hasPassedTest ifTrue: [ color := Color green ]. aClass hasFailedTest ifTrue: [ color := Color yellow ]. aClass hasErrorTest ifTrue: [ color := Color red ]. self notifyTitle: 'Test Finished' contents: 'Class: ', aClass name color: color ]! ! "Kernel"! "KernelTests"! "Nautilus"! ----End fileIn----! ----QUIT----an Array(11 April 2013 1:01:35 pm) Pharo.image priorSource: 206643! ----STARTUP----an Array(11 April 2013 1:01:36 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(11 April 2013 1:01:36 pm) Pharo-20597.image priorSource: 220229! ----STARTUP----an Array(16 April 2013 4:45:41 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 4/16/2013 16:43' prior: 33761352! commentForCurrentUpdate ^ '10260 backport 2.0: 10258 DivideByZero in SystemProgressMorph https://pharo.fogbugz.com/f/cases/10260 10109 MNU : SmalltalkEditor>>browseItHere: https://pharo.fogbugz.com/f/cases/10109 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 4/16/2013 16:44'! script572 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.12.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.5.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.3.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-EstebanLorenzano.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-EstebanLorenzano.11.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-EstebanLorenzano.8.mcz Zinc-System-Support-MarcusDenker.4.mcz Zinc-Tests-SvenVanCaekenberghe.176.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 4/16/2013 16:44'! update20598 "self new update20598" self withUpdateLog: '10260 backport 2.0: 10258 DivideByZero in SystemProgressMorph https://pharo.fogbugz.com/f/cases/10260 10109 MNU : SmalltalkEditor>>browseItHere: https://pharo.fogbugz.com/f/cases/10109 '. self loadTogether: self script572 merge: false. TextEditor initialize. SmalltalkEditor initialize. self flushCaches. ! ! "ScriptLoader20"! !Job methodsFor: 'progress' stamp: 'ChristopheDemarey 4/12/2013 13:53' prior: 24070782! progress "Avoid negative progress and divideByZero." ^ min >= max ifTrue: [ 1 ] ifFalse: [ (currentValue - min) / (max - min) ]! ! "Kernel"! ----End fileIn----! ----QUIT----an Array(16 April 2013 4:45:46 pm) Pharo.image priorSource: 220406! ----STARTUP----an Array(16 April 2013 4:45:47 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(16 April 2013 4:45:47 pm) Pharo-20598.image priorSource: 230802! ----STARTUP----an Array(17 April 2013 1:06:51 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ZnCharacterWriteStream class methodsFor: 'accessing' stamp: 'SvenVanCaekenberghe 5/3/2012 15:50' prior: 55325655! defaultEncoder ^ ZnUTF8Encoder new! ! !ZnCharacterWriteStream class methodsFor: 'instance creation' stamp: 'SvenVanCaekenberghe 5/3/2012 15:51' prior: 55325804! on: writeStream ^ self new on: writeStream; yourself! ! !ZnCharacterWriteStream class methodsFor: 'instance creation' stamp: 'SvenVanCaekenberghe 5/3/2012 15:51' prior: 55325975! on: writeStream encoding: encoding ^ self new on: writeStream; encoding: encoding; yourself! ! !String methodsFor: '*Zinc-Character-Encoding-Core' stamp: 'CamilloBruni 3/26/2013 23:18'! urlDecoded ^ ZnPercentEncoder new decode: self! ! !String methodsFor: '*Zinc-Character-Encoding-Core' stamp: 'CamilloBruni 3/26/2013 23:18'! urlEncoded ^ ZnPercentEncoder new encode: self ! ! !ZnPercentEncoder methodsFor: 'converting' stamp: 'SvenVanCaekenberghe 3/1/2013 21:25' prior: 55612320! encode: readStream to: writeStream | bytes buffer byte | buffer := (bytes := ByteArray new: 4) writeStream. self safeSet; characterEncoder. [ readStream atEnd ] whileFalse: [ buffer reset. characterEncoder nextPut: readStream next toStream: buffer. 1 to: buffer position do: [ :index | (safeSet includes: (byte := bytes at: index)) ifTrue: [ writeStream nextPut: byte asCharacter ] ifFalse: [ writeStream nextPut: $%. byte printOn: writeStream base: 16 length: 2 padded: true ] ] ]! ! "Zinc-Character-Encoding-Core"! !ZnPercentEncoderTests methodsFor: 'testing' stamp: 'SvenVanCaekenberghe 3/1/2013 21:29'! testLeadingZero | encoder | encoder := ZnPercentEncoder new. self assert: (encoder encode: 'foo', Character tab asString, 'bar') equals: 'foo%09bar'. self assert: (encoder decode: 'foo%09bar') equals: 'foo', Character tab asString, 'bar'. self assert: (encoder encode: 'foo', Character lf asString, 'bar') equals: 'foo%0Abar'. self assert: (encoder decode: 'foo%0Abar') equals: 'foo', Character lf asString, 'bar'! ! !ZnPercentEncoderTests methodsFor: 'testing' stamp: 'CamilloBruni 3/26/2013 23:18'! testStringUrlDecoded self assert: ('foo%20bar' urlDecoded) equals: 'foo bar' ! ! !ZnPercentEncoderTests methodsFor: 'testing' stamp: 'CamilloBruni 3/26/2013 23:18'! testStringUrlEncoded self assert: ('foo bar' urlEncoded) equals: 'foo%20bar'! ! "Zinc-Character-Encoding-Tests"! !ZnUrl methodsFor: 'convenience' stamp: 'SvenVanCaekenberghe 3/16/2013 20:22' prior: 55749658! / object ^ object addedToZnUrl: self! ! !ZnUrl methodsFor: 'convenience' stamp: 'SvenVanCaekenberghe 3/16/2013 20:39'! addedToZnUrl: url ^ url withPathSegments: self pathSegments ! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 19:32' prior: 55745160! clearPath self hasPath ifTrue: [ segments removeAll ]! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 19:55' prior: 55745457! directory ^ self isDirectoryPath ifTrue: [ self path ] ifFalse: [ String streamContents: [ :stream | segments allButLast do: [ :each | stream nextPutAll: each ] separatedBy: [ stream nextPut: $/ ] ] ]! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 19:39' prior: 55745655! file ^ self isDirectoryPath ifTrue: [ String new ] ifFalse: [ segments last ]! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 19:43' prior: 55746145! path self hasPath ifFalse: [ ^ String new ]. ^ String streamContents: [ :stream | segments do: [ :each | each == #/ ifFalse: [ stream nextPutAll: each ] ] separatedBy: [ stream nextPut: $/ ] ]! ! !ZnUrl methodsFor: 'printing' stamp: 'SvenVanCaekenberghe 3/16/2013 19:30' prior: 55756131! printPathOn: stream self hasPath ifFalse: [ ^ stream nextPut: $/ ]. segments do: [ :each | stream nextPut: $/. each == #/ ifFalse: [ self encode: each on: stream ] ] ! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 18:43' prior: 55746376! removeFirstPathSegment self hasPath ifTrue: [ segments removeFirst ]! ! !ZnUrl methodsFor: 'accessing-path' stamp: 'SvenVanCaekenberghe 3/16/2013 18:42' prior: 55746539! removeLastPathSegment self hasPath ifTrue: [ segments removeLast ]! ! !String methodsFor: '*zinc-resource-meta-core' stamp: 'SvenVanCaekenberghe 3/16/2013 20:23'! addedToZnUrl: url | segments | segments := self findTokens: '/'. ^ url withPathSegments: segments! ! !Collection methodsFor: '*zinc-resource-meta-core' stamp: 'SvenVanCaekenberghe 3/16/2013 20:24'! addedToZnUrl: url ^ url withPathSegments: self! ! ZnUrl removeSelector: #joinSegments:! "Zinc-Resource-Meta-Core"! !ZnUrlTests methodsFor: 'testing' stamp: 'SvenVanCaekenberghe 3/16/2013 18:41'! testBogusBackups self assert: '/../../../' asZnUrl isSlash! ! !ZnUrlTests methodsFor: 'testing' stamp: 'SvenVanCaekenberghe 3/16/2013 20:41' prior: 55762829! testConvenienceMethods | baseUrl | baseUrl := 'http://api.host.com' asZnUrl. self assert: baseUrl equals: 'http://api.host.com' asZnUrl. self assert: baseUrl / 'doc' / 'file.html' equals: 'http://api.host.com/doc/file.html' asZnUrl. self assert: baseUrl / 'doc/file.html' equals: 'http://api.host.com/doc/file.html' asZnUrl. self assert: baseUrl / #( 'doc' 'file.html' ) equals: 'http://api.host.com/doc/file.html' asZnUrl. self assert: baseUrl / 'doc/file.html' asZnUrl equals: 'http://api.host.com/doc/file.html' asZnUrl. self assert: (baseUrl / 'search' ? (#q -> 'Smalltalk') & (#lang -> #en)) equals: 'http://api.host.com/search?q=Smalltalk&lang=en' asZnUrl. self assert: baseUrl equals: 'http://api.host.com' asZnUrl! ! "Zinc-Resource-Meta-Tests"! !ZnApplicationFormUrlEncodedEntity methodsFor: 'accessing' stamp: 'SvenVanCaekenberghe 2/24/2013 10:52' prior: 55246961! addAll: keyedCollection "Note that we use #addAllMulti:" self invalidateRepresentation. self fields addAllMulti: keyedCollection. ^ keyedCollection ! ! "Zinc-HTTP"! !ZnClientTests methodsFor: 'testing' stamp: 'SvenVanCaekenberghe 2/24/2013 11:02'! testPrepareRequest | client | self withServerDo: [ :server | (client := ZnClient new) url: server localUrl; addPath: 'echo'; prepareRequest: [ :request | request setAuthorization: 'my-signature' ]; get. self assert: client isSuccess. self assert: (client contents includesSubstring: 'my-signature'). client url: server localUrl; addPath: 'echo'; get. self assert: client isSuccess. self assert: (client contents includesSubstring: 'my-signature'). client close ]! ! !ZnEntityTests methodsFor: 'testing' stamp: 'SvenVanCaekenberghe 2/24/2013 10:53'! testApplicationUrlEncodingAddAll | entity string data | data := Dictionary new. data at: 'foo' put: 1 asString. data at: 'bar' put: 2 asString. entity := ZnApplicationFormUrlEncodedEntity new. "Asking for the content length will force an internal computation of the representation" self assert: entity contentLength = 0. entity addAll: data. string := String streamContents: [ :stream | entity writeOn: stream ]. self assert: entity contentLength > 0. entity := ZnEntity readFrom: string readStream usingType: ZnApplicationFormUrlEncodedEntity designatedMimeType andLength: string size. self assert: (entity at: 'foo') equals: '1'. self assert: (entity at: 'bar') equals: '2'! ! "Zinc-Tests"! ----End fileIn----! ----QUIT----an Array(17 April 2013 1:06:57 pm) Pharo.image priorSource: 230979! ----STARTUP----an Array(17 April 2013 1:06:58 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(17 April 2013 1:06:58 pm) Pharo-20599.image priorSource: 238601! ----STARTUP----an Array(7 May 2013 1:47:10 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/7/2013 13:38' prior: 33775116! commentForCurrentUpdate ^ '-> move to updates.pharo.org'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/7/2013 13:38'! script573 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-EstebanLorenzano.67.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/7/2013 13:37'! update20599 "update"! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/7/2013 13:38'! update20600 "self new update20600" self withUpdateLog: '-> move to updates.pharo.org'. self loadTogether: self script573 merge: false. self flushCaches. ! ! "ScriptLoader20"! !UpdateStreamer methodsFor: 'accessing' stamp: 'MarcusDenker 5/7/2013 13:36' prior: 54521003! path "Part ... in the following http:// server / path /updates.list" ^ path ifNil: [ path := 'pharo'].! ! !UpdateStreamer methodsFor: 'accessing' stamp: 'MarcusDenker 5/7/2013 13:35' prior: 54521506! server pharoServer ifNil: [pharoServer := 'updates.pharo.org/']. ^ pharoServer! ! !SmalltalkImage methodsFor: '*Zinc-System-Support' stamp: 'MarcusDenker 5/7/2013 13:34' prior: 33568242! downloadSources "Try downloading the sources file from 2 different locations to the shared directory. Be silent when this does not work: a missing sources will be triggered later on. For now, use the VM directory." | sharedDirectory | self shouldDownloadSourcesFile ifFalse: [ ^ self ]. sharedDirectory := self vmDirectory. self sourcesDownloadClient url: 'http://files.pharo.org/sources/PharoV20.sources'; downloadTo: sharedDirectory; close. (sharedDirectory / self sourcesFile basename) exists ifTrue: [ ^ self ]. self sourcesDownloadClient url: 'http://stfx.eu/PharoV20.sources'; downloadTo: sharedDirectory; close. ! ! "UpdateStreamer-Core"! "Zinc-System-Support"! ----End fileIn----! ----QUIT----an Array(7 May 2013 1:47:12 pm) Pharo.image priorSource: 238778! ----STARTUP----an Array(7 May 2013 1:47:13 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(7 May 2013 1:47:13 pm) Pharo-20600.image priorSource: 249860! ----STARTUP----an Array(7 May 2013 1:51:04 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(7 May 2013 1:51:04 pm) Pharo.image priorSource: 250031! ----STARTUP----an Array(7 May 2013 1:51:05 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(7 May 2013 1:51:05 pm) Pharo-20600.image priorSource: 250212! ----STARTUP----an Array(7 May 2013 2:06:10 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/7/2013 14:04' prior: 33793484! commentForCurrentUpdate ^ '10406 backport 2.0: 5819 Implement a way to get the user directories based on the current OS https://pharo.fogbugz.com/f/cases/10406 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/7/2013 14:04'! script574 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.494.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.775.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.99.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.85.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.24.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.106.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/7/2013 14:04'! update20601 "self new update20601" self withUpdateLog: '10406 backport 2.0: 5819 Implement a way to get the user directories based on the current OS https://pharo.fogbugz.com/f/cases/10406 '. self loadTogether: self script574 merge: false. self flushCaches. ! ! "ScriptLoader20"! !UnixResolver methodsFor: 'origins' stamp: 'DamienCassou 3/25/2013 17:45' prior: 54514745! desktop ^ (self xdgUserDir: 'DESKTOP') ifNil: [ self home / 'Desktop' ]! ! !UnixResolver methodsFor: 'origins' stamp: 'DamienCassou 3/25/2013 17:45' prior: 54514849! documents ^ (self xdgUserDir: 'DOCUMENTS') ifNil: [ self home / 'Documents' ]! ! !UnixResolver methodsFor: 'origins' stamp: 'DamienCassou 4/11/2013 15:31' prior: 54514965! home "Value of the $HOME environment variable. When NativeBoost is not available, do your best to answer something not too stupid." ^ [ self resolveString: (self nbGetEnv: 'HOME') ] on: Error do: [ (self resolveString: self class primitiveGetUntrustedUserDirectory) parent parent parent "don't know any better default" ]! ! !UnixResolver methodsFor: 'helpers' stamp: 'DamienCassou 3/25/2013 17:55'! nbGetEnv: str "This method calls a Standard C library getenv() function" ^ self nbCall: #(#String #getenv #(#String #str)) module: NativeBoost CLibrary! ! !UnixResolver methodsFor: 'origins' stamp: 'DamienCassou 4/11/2013 15:31' prior: 54515192! preferences "Value of $XDG_CONFIG_HOME or, if unset, $HOME/.config" "http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html" ^ (self nbGetEnv: 'XDG_CONFIG_HOME') ifNotNil: [ :home | self resolveString: home ] ifNil: [ self home / '.config' ] ! ! !UnixResolver methodsFor: 'helpers' stamp: 'DamienCassou 3/25/2013 17:39'! xdgParseUserDirLine: aStream "Format is XDG_xxx_DIR=""$HOME/yyy"", where yyy is a shell-escaped homedir-relative path, or XDG_xxx_DIR=""/yyy"", where /yyy is an absolute path. No other format is supported." | path firstChar | (aStream next = $") ifFalse: [ ^ nil ]. firstChar := aStream next. (#($$ $/) includes: firstChar) ifFalse: [ ^ nil ]. path := firstChar = $$ ifTrue: [ (aStream next: 5) = 'HOME/' ifFalse: [ ^ nil ]. self home / (aStream upTo: $") ] ifFalse: [ self resolveString: '/', (aStream upTo: $") ]. ^ path isDirectory ifTrue: [ path ] ifFalse: [ nil ]! ! !UnixResolver methodsFor: 'helpers' stamp: 'DamienCassou 3/25/2013 17:57'! xdgUserDir: userDirName "Read ~/.config/user-dirs.dirs to find the directory of userDirName (e.g., 'DESKTOP')" "http://freedesktop.org/wiki/Software/xdg-user-dirs" "This file is written by xdg-user-dirs-update If you want to change or add directories, just edit the line you're interested in. All local changes will be retained on the next run Format is XDG_xxx_DIR=""$HOME/yyy"", where yyy is a shell-escaped homedir-relative path, or XDG_xxx_DIR=""/yyy"", where /yyy is an absolute path. No other format is supported." | configFile | configFile := self preferences / 'user-dirs.dirs'. (configFile isFile and: [ configFile isReadable ]) ifFalse: [ ^ nil ]. configFile readStreamDo: [ :stream | [ stream atEnd ] whileFalse: [ ((stream peek ~= $#) and: [ (stream upTo: $=) = ('XDG_', userDirName, '_DIR') ]) ifTrue: [ ^ self xdgParseUserDirLine: stream ] ifFalse: [ stream nextLine ] ] ]. ^ nil! ! "FileSystem-Core"! ----End fileIn----! ----QUIT----an Array(7 May 2013 2:06:13 pm) Pharo.image priorSource: 250383! ----STARTUP----an Array(7 May 2013 2:06:14 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(7 May 2013 2:06:14 pm) Pharo-20601.image priorSource: 263520! ----STARTUP----an Array(7 May 2013 2:46:07 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/7/2013 14:42' prior: 33805086! commentForCurrentUpdate ^ '10396 backport 2.0 10395 DNU SmallInteger>>#add: when loading metacello configuration https://pharo.fogbugz.com/f/cases/10396 10394 Duplicated instance #model in NewList (already defined in MorphicModel) https://pharo.fogbugz.com/f/cases/10394 10387 backport 2.0: 10102 SocketStream>>next: should not signal ConncetionClosed https://pharo.fogbugz.com/f/cases/10387 10336 Port 2.0: Document difference between TextModel and TextInputFieldModel https://pharo.fogbugz.com/f/cases/10336 10311 Backport 2.0: 10228 Fix tab key for autocompletion https://pharo.fogbugz.com/f/cases/10311'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/7/2013 14:43'! script575 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.777.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.77.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/7/2013 14:43'! update20602 "self new update20602" self withUpdateLog: '10396 backport 2.0 10395 DNU SmallInteger>>#add: when loading metacello configuration https://pharo.fogbugz.com/f/cases/10396 10394 Duplicated instance #model in NewList (already defined in MorphicModel) https://pharo.fogbugz.com/f/cases/10394 10387 backport 2.0: 10102 SocketStream>>next: should not signal ConncetionClosed https://pharo.fogbugz.com/f/cases/10387 10336 Port 2.0: Document difference between TextModel and TextInputFieldModel https://pharo.fogbugz.com/f/cases/10336 10311 Backport 2.0: 10228 Fix tab key for autocompletion https://pharo.fogbugz.com/f/cases/10311'. self loadTogether: self script575 merge: false. self flushCaches. ! ! "ScriptLoader20"! !TextModel commentStamp: '' prior: 52742743! I handle basic multi-line text. Try: "self example"! !TextInputFieldModel commentStamp: '' prior: 52714878! I handle one line of text.! !NewList commentStamp: '' prior: 28370504! NewList is a new morph as replacement for PluggableListMorph. The API used is hardcoded, but NewListAdapter has been introduced to hold this "pluggable" behavior! !NECMenuMorph methodsFor: 'actions' stamp: 'JohanBrichau 4/5/2013 22:30'! insertCommonPrefixOrSelected "Return value: true if the user input has been handled, regardless of whether a prefix was inserted" | prefix | context model isEmpty ifTrue: [^ false]. context model entries size = 1 ifTrue: [ ^ self insertSelected ]. prefix := context model commonPrefix. prefix = context model narrowString ifTrue:[^ self insertSelected]. self flag: 'Pending issue 7308, "controller editor wordAtCaret" below should be changed to "context completionToken"'. prefix size > controller editor wordAtCaret size ifTrue: [ self insertCompletion: prefix. context narrowWith: controller editor wordAtCaret ]. ^ true! ! !TextModel commentStamp: '' prior: 33829065! I handle basic multi-line text. Try: "self example"! !TextInputFieldModel commentStamp: '' prior: 33829186! I handle one line of text.! !TextModel class methodsFor: 'example' stamp: 'SeanDeNigris 4/19/2013 22:50' prior: 52755220! example | instance | instance := self new. instance openWithSpec. instance text: 'This is a test. If this had been an actual emergency...'.! ! !NECController methodsFor: 'keyboard' stamp: 'JohanBrichau 4/5/2013 22:30' prior: 27787019! handleKeystrokeBefore: aKeyboardEvent editor: anEditor "I return a boolean. true when I have handled the event and no futher processing is needed by the caller." | keyCharacter controlKeyPressed isSpaceKey | self flag: #fixme. "this method should be split up". self setEditor: anEditor. self setModel: editor model. keyCharacter := aKeyboardEvent keyCharacter. controlKeyPressed := aKeyboardEvent controlKeyPressed. isSpaceKey := keyCharacter = Character null or: [ keyCharacter = Character space ]. self isMenuOpen ifFalse: [ ^ self handleKeystrokeWithoutMenu: aKeyboardEvent ]. (keyCharacter = Character home and: [ self captureNavigationKeys ]) ifTrue: [ menuMorph home. ^ true]. (keyCharacter = Character end and: [controlKeyPressed not and: [ self captureNavigationKeys ]]) ifTrue: [ menuMorph end. ^ true]. (keyCharacter = Character arrowRight and: [ self captureNavigationKeys ]) ifTrue: [ menuMorph showDetail. ^ true]. (keyCharacter = Character arrowLeft and: [ self captureNavigationKeys ]) ifTrue: [ ^ self leftArrow ]. keyCharacter = Character arrowUp ifTrue: [ menuMorph moveUp. ^ true]. keyCharacter = Character arrowDown ifTrue: [ menuMorph moveDown. ^ true]. keyCharacter = Character pageUp ifTrue: [ menuMorph pageUp. ^ true]. keyCharacter = Character pageDown ifTrue: [ menuMorph pageDown. ^ true]. (keyCharacter = Character cr and: [ NECPreferences useEnterToAccept]) ifTrue: [ menuMorph insertSelected ifTrue: [^ true]]. keyCharacter = Character tab ifTrue: [ NECPreferences expandPrefixes ifFalse: [ menuMorph insertSelected ifTrue: [^ true]] ifTrue: [ menuMorph insertCommonPrefixOrSelected ifTrue: [^ true]]]. self flag: #todo. "Removing for now... most of the shortcuts are broken and no time or need now to fix them" "(keyCharacter = $h and: [ controlKeyPressed ]) ifTrue: [ menuMorph help. ^ true ]. (keyCharacter = $t and: [ controlKeyPressed ]) ifTrue: [ menuMorph expand. ^ true ]. (keyCharacter = $u and: [ controlKeyPressed ]) ifTrue: [ menuMorph switchToUntyped. ^ true ]. " "All keys but the alphanumeric chars (without command and control ) and the backspace key do close the menu" keyCharacter = Character backspace ifTrue: [ editor isCaretBehindChar not ifTrue: [ self closeMenu]. ^ false]. (controlKeyPressed not & aKeyboardEvent commandKeyPressed not and: [aKeyboardEvent keyCharacter isCompletionCharacter ]) ifFalse: [ self closeMenu. ^ keyCharacter = Character escape]. ^ false.! ! !MetacelloAbstractVersionConstructor methodsFor: 'api callbacks' stamp: 'EstebanLorenzano 4/24/2013 18:46' prior: 25767186! setFor: attributeList do: aBlock "conditional version support" attributeList asMetacelloAttributeList do: [ :attribute | | blockList | blockList := self attributeMap at: attribute ifAbsentPut: [ OrderedCollection new ]. blockList add: aBlock. self addAttribute: attribute ]! ! !NewList commentStamp: '' prior: 33829269! NewList is a new morph as replacement for PluggableListMorph. The API used is hardcoded, but NewListAdapter has been introduced to hold this "pluggable" behavior! !SocketStream methodsFor: 'stream in' stamp: 'MarcusDenker 5/7/2013 14:41' prior: 50455827! next: anInteger "Read count elements and return them in a collection. If the receiver is #atEnd before count elements were read, return a smaller collection and don't signal ConnectionClosed." ^ self nextInto: (self streamBuffer: anInteger)! ! !NECModel methodsFor: 'accessing' stamp: 'JohanBrichau 4/5/2013 22:08'! narrowString ^ narrowString! ! !MCHttpRepository methodsFor: 'i/o' stamp: 'EstebanLorenzano 4/25/2013 10:54' prior: 24806372! readStreamForFileNamed: aString do: aBlock | client | self displayProgress: 'Downloading ', aString during: [ client := self httpClient. client ifFail: [ :exception | self error: 'Could not load ', aString, ': ', exception printString ]; get: (self urlForFileNamed: aString). self assertBinaryResponse: client response. "immediately cache the version and avoid an unnecessary serialization" self cacheRawVersionNamed: aString stream: client contents ]. ^ aBlock value: client contents readStream! ! NECMenuMorph removeSelector: #insertCommonPrefix! "Metacello-Core"! "Monticello"! "NECompletion"! "Network-Kernel"! "NewList"! "Spec-Widgets"! ----End fileIn----! ----QUIT----an Array(7 May 2013 2:46:17 pm) Pharo.image priorSource: 263691! ----STARTUP----an Array(7 May 2013 2:46:18 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(7 May 2013 2:46:18 pm) Pharo-20602.image priorSource: 280843! ----STARTUP----an Array(13 May 2013 9:26:53 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(13 May 2013 9:26:53 am) Pharo.image priorSource: 281014! ----STARTUP----an Array(13 May 2013 9:26:54 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(13 May 2013 9:26:54 am) Pharo-20602.image priorSource: 281196! ----STARTUP----an Array(14 May 2013 8:53:47 am) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/14/2013 08:52' prior: 33818394! commentForCurrentUpdate ^ '10537 Backport 2.0: StartupPreferences interferes with zeroconf pharo binary https://pharo.fogbugz.com/f/cases/10537 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/14/2013 08:52'! script576 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.777.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.79.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/14/2013 08:52'! update20603 "self new update20603" self withUpdateLog: '10537 Backport 2.0: StartupPreferences interferes with zeroconf pharo binary https://pharo.fogbugz.com/f/cases/10537 '. self loadTogether: self script576 merge: false. self flushCaches. ! ! "ScriptLoader20"! !PreferencesHandler methodsFor: 'private' stamp: 'CamilloBruni 5/9/2013 20:29' prior: 29948833! lookInFolder: folder forFilesMatching: pattern | result files | result := OrderedCollection new. folder isDirectory ifFalse: [ ^ nil ]. files := folder filesMatching: pattern. files do: [ :e | result add: e ]. ^ result isEmpty ifTrue: [ nil ] ifFalse: [ result ]! ! "StartupPreferences"! ----End fileIn----! ----QUIT----an Array(14 May 2013 8:53:49 am) Pharo.image priorSource: 281369! ----STARTUP----an Array(14 May 2013 8:53:50 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(14 May 2013 8:53:50 am) Pharo-20603.image priorSource: 291734! ----STARTUP----an Array(17 May 2013 11:14:49 am) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/17/2013 11:13' prior: 33836075! commentForCurrentUpdate ^ '10653 Some Jenkins images show a stdout is closed error https://pharo.fogbugz.com/f/cases/10653'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/17/2013 11:13'! script577 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.777.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.81.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/17/2013 11:13'! update20604 "self new update20604" self withUpdateLog: '10653 Some Jenkins images show a stdout is closed error https://pharo.fogbugz.com/f/cases/10653'. self loadTogether: self script577 merge: false. self flushCaches. ! ! "ScriptLoader20"! !EvaluateCommandLineHandler methodsFor: 'activation' stamp: 'DamienCassou 5/16/2013 18:15' prior: 21247976! activate self activateHelp. self arguments ifEmpty: [ ^ self evaluateStdIn ]. self evaluateArguments. (self hasOption: 'save') ifTrue: [ Smalltalk snapshot: true andQuit: true ] ifFalse: [ self quit ]! ! !EvaluateCommandLineHandler methodsFor: 'activation' stamp: 'DamienCassou 5/16/2013 18:21' prior: 21248189! evaluateArguments | args | args := ((self arguments size > 1 and: [ self arguments first = '--save' ]) ifTrue: [ self arguments allButFirst ] ifFalse: [ self arguments ]) joinUsing: Character space. args ifEmpty: [ ^ self ]. self evaluate: args! ! "System-CommandLine"! ----End fileIn----! ----QUIT----an Array(17 May 2013 11:14:51 am) Pharo.image priorSource: 291907! ----STARTUP----an Array(17 May 2013 11:14:52 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(17 May 2013 11:14:52 am) Pharo-20604.image priorSource: 302533! ----STARTUP----an Array(17 May 2013 12:50:30 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(17 May 2013 12:50:30 pm) Pharo.image priorSource: 302708! ----STARTUP----an Array(17 May 2013 12:50:31 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(17 May 2013 12:50:31 pm) Pharo-20604.image priorSource: 302893! ----STARTUP----an Array(27 May 2013 5:33:46 pm) as /builds/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 5/27/2013 17:31' prior: 33846614! commentForCurrentUpdate ^ '10653 Some Jenkins images show a stdout is closed error https://pharo.fogbugz.com/f/cases/10653'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 5/27/2013 17:31'! script578 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-EstebanLorenzano.ducasse.294.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.777.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 5/27/2013 17:31'! update20605 "self new update20605" self withUpdateLog: '10653 Some Jenkins images show a stdout is closed error https://pharo.fogbugz.com/f/cases/10653'. self loadTogether: self script578 merge: false. self flushCaches. ! ! "ScriptLoader20"! !EvaluateCommandLineHandler commentStamp: '' prior: 21247357! Usage: eval [--help] [--save] --help list this help message --save save the image after evaluation of the expression a valid Smalltalk expression which is evaluated and the result is printed on stdout Documentation: A CommandLineHandler that reads a string from the command line, outputs the evaluated result and quits the image. This handler either evaluates the arguments passed to the image: $PHARO_VM my.image eval 1 + 2 or it can read directly from stdin: echo "1+2" | $PHARO_VM my.image eval Important: don't manually save the image at the end of the expression by calling something like 'Smalltalk snapshot: true andSave: true'!! Instead, use the safer --save option.! !EvaluateCommandLineHandler commentStamp: '' prior: 33867473! Usage: eval [--help] [--save] --help list this help message --save save the image after evaluation of the expression a valid Smalltalk expression which is evaluated and the result is printed on stdout Documentation: A CommandLineHandler that reads a string from the command line, outputs the evaluated result and quits the image. This handler either evaluates the arguments passed to the image: $PHARO_VM my.image eval 1 + 2 or it can read directly from stdin: echo "1+2" | $PHARO_VM my.image eval Important: don't manually save the image at the end of the expression by calling something like 'Smalltalk snapshot: true andSave: true'!! Instead, use the safer --save option.! "System-CommandLine"! ----End fileIn----! ----QUIT----an Array(27 May 2013 5:33:48 pm) Pharo.image priorSource: 303068! ----STARTUP----an Array(27 May 2013 5:33:50 pm) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(27 May 2013 5:33:50 pm) Pharo-20605.image priorSource: 314708! ----STARTUP----an Array(1 June 2013 9:32:53 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(1 June 2013 9:32:53 am) Pharo.image priorSource: 314881! ----STARTUP----an Array(1 June 2013 9:32:54 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(1 June 2013 9:32:54 am) Pharo-20605.image priorSource: 315064! ----STARTUP----an Array(1 June 2013 10:11:17 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(1 June 2013 10:11:17 am) Pharo.image priorSource: 315237! ----STARTUP----an Array(1 June 2013 10:11:19 am) as /builds/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(1 June 2013 10:11:19 am) Pharo-20605.image priorSource: 315421! ----STARTUP----an Array(6 June 2013 1:32:35 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 6/5/2013 14:17' prior: 33857775! commentForCurrentUpdate ^ '10415 Integrate 2.0: 10411 flush after nextChunkPut: https://pharo.fogbugz.com/f/cases/10415'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 6/5/2013 14:18'! script579 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.777.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-EstebanLorenzano.801.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 6/5/2013 14:18'! update20606 "self new update20606" self withUpdateLog: '10415 Integrate 2.0: 10411 flush after nextChunkPut: https://pharo.fogbugz.com/f/cases/10415'. self loadTogether: self script579 merge: false. self flushCaches. ! ! "ScriptLoader20"! !RemoteString methodsFor: 'accessing' stamp: 'ThierryGoubier 5/28/2013 14:16' prior: 32254187! fileStream "Answer the file stream with position set at the beginning of my string. Answer a read only copy to avoid syntax errors when accessed via multiple processes." | theFile | (sourceFileNumber == nil or: [(SourceFiles at: sourceFileNumber) == nil]) ifTrue: [^ nil]. theFile := (SourceFiles at: sourceFileNumber) flush readOnlyCopy. filePositionHi > theFile size ifTrue: [ self error: 'RemoteString past end of file' ]. theFile position: filePositionHi. ^ theFile! ! !RemoteString methodsFor: 'accessing' stamp: 'ThierryGoubier 5/28/2013 14:18' prior: 32255637! string "Answer the receiver's string if remote files are enabled. Use a read only copy to avoid syntax errors when accessed via multiple processes." | theFile | (sourceFileNumber == nil or: [(SourceFiles at: sourceFileNumber) == nil]) ifTrue: [^'']. theFile := (SourceFiles at: sourceFileNumber) flush readOnlyCopy. ^[filePositionHi > theFile size ifTrue: [ self error: 'RemoteString past end of file' ]. theFile position: filePositionHi. theFile nextChunk] ensure: [theFile close] ! ! "Files"! ----End fileIn----! ----QUIT----an Array(6 June 2013 1:32:37 pm) Pharo.image priorSource: 315596! ----STARTUP----an Array(6 June 2013 1:32:39 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(6 June 2013 1:32:39 pm) Pharo-20606.image priorSource: 326733! ----STARTUP----an Array(7 June 2013 4:36:16 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(7 June 2013 4:36:17 pm) Pharo.image priorSource: 326947! ----STARTUP----an Array(7 June 2013 4:36:19 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(7 June 2013 4:36:19 pm) Pharo-20606.image priorSource: 327171! ----STARTUP----an Array(13 June 2013 5:08:53 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(13 June 2013 5:08:53 pm) Pharo.image priorSource: 327385! ----STARTUP----an Array(13 June 2013 5:08:55 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(13 June 2013 5:08:55 pm) Pharo-20606.image priorSource: 327610! ----STARTUP----an Array(18 June 2013 9:58:59 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 6/18/2013 09:56' prior: 33870343! commentForCurrentUpdate ^ '10938 backport 2.0 : an MCOrganizationDefinition should only remove empty categories during unload https://pharo.fogbugz.com/f/cases/10938 10909 Backport Pharo2.0: Prepare isHeadless for new VMs with double dash -- arguments https://pharo.fogbugz.com/f/cases/10909'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 6/18/2013 09:56'! script580 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.762.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-MaxLeske.311.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1346.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.779.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.214.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-MarcusDenker.109.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 6/18/2013 09:57'! update20607 "self new update20607" self withUpdateLog: '10938 backport 2.0 : an MCOrganizationDefinition should only remove empty categories during unload https://pharo.fogbugz.com/f/cases/10938 10909 Backport Pharo2.0: Prepare isHeadless for new VMs with double dash -- arguments https://pharo.fogbugz.com/f/cases/10909'. self loadTogether: self script580 merge: false. self flushCaches. ! ! "ScriptLoader20"! !MCOrganizationDefinition methodsFor: 'unloading' stamp: 'ChristopheDemarey 6/17/2013 17:22' prior: 24885814! unload categories do: [ :category | (SystemOrganization isEmptyCategoryNamed: category) ifTrue: [ SystemOrganization removeCategory: category ] ] ! ! !SmalltalkImage methodsFor: 'testing' stamp: 'CamilloBruni 6/13/2013 17:41' prior: 50360965! isHeadless "Check if vm were run with headless parameter. Different VMs for different platform have different multiple way(s) to indicate that" -1000 to: 1000 do: [ :n | (#('display=none' '-headless' '-vm-display-null' '-nodisplay' '--headless' '--vm-display-null' '--nodisplay') includes: (self vm getSystemAttribute: n)) ifTrue: [ ^ true ] ]. ^ false ! ! !SmalltalkImage methodsFor: 'testing' stamp: 'CamilloBruni 6/13/2013 17:42' prior: 50361366! isInteractive "Check if vm were run with headless parameter. Different VMs for different platform have different multiple way(s) to indicate that" "non-headless mode is always interactive" self isHeadless ifFalse: [ ^ true ]. -1000 to: 1000 do: [ :n | (#('-interactive' '--interactive') includes: (self vm getSystemAttribute: n)) ifTrue: [ ^ true ]]. ^ false! ! "Monticello"! "System-Support"! ----End fileIn----! ----QUIT----an Array(18 June 2013 9:59:05 am) Pharo.image priorSource: 327826! ----STARTUP----an Array(18 June 2013 9:59:08 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(18 June 2013 9:59:08 am) Pharo-20607.image priorSource: 339378! ----STARTUP----an Array(25 June 2013 11:23:16 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(25 June 2013 11:23:17 am) Pharo.image priorSource: 339594! ----STARTUP----an Array(25 June 2013 11:23:19 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(25 June 2013 11:23:19 am) Pharo-20607.image priorSource: 339821! ----STARTUP----an Array(25 June 2013 11:30:46 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 6/25/2013 11:16' prior: 33882575! commentForCurrentUpdate ^ '10888 Backport 2.0: Compound Extension Methods Unpackaged https://pharo.fogbugz.com/f/cases/10888/Backport-2-0-Compound-Extension-Methods-Unpackaged 10730 Fix for stack serialization with Fuel https://pharo.fogbugz.com/f/cases/10730/Fix-for-stack-serialization-with-Fuel 10994 Backport 2.0: Delays do not work properly directly on image startup https://pharo.fogbugz.com/f/cases/10994/Backport-2-0-Delays-do-not-work-properly-directly-on-image-startup '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 6/25/2013 11:16'! script581 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1348.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.779.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.439.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.462.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 6/25/2013 11:19'! update20608 "self new update20608" Gofer it squeaksource3: 'Fuel'; configuration; load. ((Smalltalk at: #ConfigurationOfFuel) project version: '1.9.1') load. . self withUpdateLog: '10888 Backport 2.0: Compound Extension Methods Unpackaged https://pharo.fogbugz.com/f/cases/10888/Backport-2-0-Compound-Extension-Methods-Unpackaged 10730 Fix for stack serialization with Fuel https://pharo.fogbugz.com/f/cases/10730/Fix-for-stack-serialization-with-Fuel 10994 Backport 2.0: Delays do not work properly directly on image startup https://pharo.fogbugz.com/f/cases/10994/Backport-2-0-Delays-do-not-work-properly-directly-on-image-startup '. self loadTogether: self script581 merge: false. ScriptLoader new unloadPackageNamed: 'ConfigurationOfFuel'; cleanRepositories. self flushCaches. ! ! "ScriptLoader20"! !ConfigurationOfFuel commentStamp: '' prior: 0! Fuel is a general-purpose object serialization framework. See more information in our website: http://rmod.lille.inria.fr/web/pier/software/Fuel/! !ConfigurationOfFuel commentStamp: '' prior: 33905430! Fuel is a general-purpose object serialization framework. See more information in our website: http://rmod.lille.inria.fr/web/pier/software/Fuel/! !ConfigurationOfFuel class methodsFor: 'development support' stamp: 'MartinDias 2/19/2011 03:09'! DevelopmentSupport "See the methods in the 'development support' category on the class-side of MetacelloBaseConfiguration. Decide what development support methods you would like to use and copy them the the class-side of your configuration." ! ! !ConfigurationOfFuel class methodsFor: 'private-hacks' stamp: 'MaxLeske 2/27/2013 22:25'! addClassDescriptionTrait "Don't name the category 'Fuel-Hacks'. That category will be nuked on load" Smalltalk at: #MetacelloSqueakPlatform ifAbsent: [ ^ self ]. Trait named: #TClassAndTraitDescription uses: {} category: 'FuelHacks'! ! !ConfigurationOfFuel class methodsFor: 'private-hacks' stamp: 'MaxLeske 2/27/2013 23:33'! addEnvironment "Don't name the category 'Fuel-Hacks'. That category will be nuked on load" Smalltalk at: #Environment ifPresent: [ :x | ^ self ]. Object subclass: #Environment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'FuelHacks' ! ! !ConfigurationOfFuel class methodsFor: 'private-hacks' stamp: 'MaxLeske 2/27/2013 22:25'! addSqueakHacks self addClassDescriptionTrait; addEnvironment! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MartinDias 2/19/2011 03:09'! baseConfigurationClassIfAbsent: aBlock ^Smalltalk at: #MetacelloBaseConfiguration ifAbsent: [ self ensureMetacelloBaseConfiguration. Smalltalk at: #MetacelloBaseConfiguration ifAbsent: aBlock ]. ! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MartinDias 2/19/2011 03:09'! ensureMetacello (self baseConfigurationClassIfAbsent: []) ensureMetacello! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MartinDias 2/19/2011 03:09'! ensureMetacelloBaseConfiguration Smalltalk at: #MetacelloBaseConfiguration ifAbsent: [ | repository version | repository := MCHttpRepository location: 'http://seaside.gemstone.com/ss/metacello' user: '' password: ''. repository versionReaderForFileNamed: 'Metacello-Base-DaleHenrichs.2.mcz' do: [ :reader | version := reader version. version load. version workingCopy repositoryGroup addRepository: repository ] ]! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MaxLeske 4/14/2013 09:38'! ensureMetacelloForPharo11x [ Smalltalk at: #SystemVersion ifPresent: [ :systemVersion | ((systemVersion current version findString: 'Pharo-1.1' startingAt: 1) > 0) ifTrue: [ Gofer it squeaksource: 'MetacelloRepository'; package: 'ConfigurationOfMetacello'; load. (Smalltalk at: #ConfigurationOfMetacello) load ] ] ] on: Deprecation do: [ :exception | exception resume ]! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MaxLeske 4/15/2013 12:05'! fixSqueakPlatformAttributes | versions | versions := { 'Squeak4.3'. 'Squeak4.4'. 'Squeak4.5' }. Smalltalk at: #SystemVersion ifPresent: [ :systemVersion | (versions anySatisfy: [ :version | (systemVersion current version findString: version startingAt: 1) > 0 ]) ifFalse: [ ^ self ] ]. Smalltalk at: #MetacelloSqueakPlatform ifPresent: [ :platform | Utilities setAuthorInitials: 'MaxLeske'. (Smalltalk at: #MetacelloSqueakPlatform) compile: self newSqueakPlatformAttributesSource. Utilities setAuthorInitials: '' ]! ! !ConfigurationOfFuel class methodsFor: 'metacello tool support' stamp: 'MartinDias 2/19/2011 03:09'! isMetacelloConfig "Answer true and the Metacello tools will operate on you" ^true! ! !ConfigurationOfFuel class methodsFor: 'loading' stamp: 'MartinDias 2/19/2011 03:09'! load "Load the #stable version defined for this platform. The #stable version is the version that is recommended to be used on this platform." "self load" ^(self project version: #stable) load! ! !ConfigurationOfFuel class methodsFor: 'loading' stamp: 'MartinDias 2/19/2011 03:09'! loadBleedingEdge "Load the latest versions of the mcz files defined for this project. It is not likely that the #bleedingEdge has been tested." "self loadBleedingEdge" ^(self project version: #bleedingEdge) load! ! !ConfigurationOfFuel class methodsFor: 'loading' stamp: 'MarianoMartinezPeck 5/2/2012 21:40'! loadDevelopment "Load the #development version defined for this platform. The #development version will change over time and is not expected to be stable." "self loadDevelopment" ^(self project version: #bleedingEdge) load: 'DevelopmentGroup'! ! !ConfigurationOfFuel class methodsFor: 'hudson' stamp: 'MartinDias 5/18/2012 17:58'! loadInHudson "Load the latest versions of the mcz files defined for this project. It is not likely that the #bleedingEdge has been tested." "self loadBleedingEdge" (self project version: #bleedingEdge) load: #('DevelopmentGroup'). (Smalltalk at: #FLUtilities) cleanUpEverything. (Smalltalk at: #FLLogoUtilities) installLogo.! ! !ConfigurationOfFuel class methodsFor: 'private' stamp: 'MaxLeske 12/29/2012 17:12'! newSqueakPlatformAttributesSource ^ 'defaultPlatformAttributes | attributes versionString | attributes := OrderedCollection with: #squeakCommon with: #squeak. Smalltalk at: #SystemVersion ifPresent: [:cl | versionString := cl current version. (versionString beginsWith: ''Squeak3.10'') ifTrue: [attributes add: #''squeak3.10.x'']. (versionString beginsWith: ''Squeak4'') ifTrue: [attributes add: #''squeak4.x''. (versionString beginsWith: ''Squeak4.1'') ifTrue: [attributes add: #''squeak4.1.x''] ifFalse: [(versionString beginsWith: ''Squeak4.2'') ifTrue: [attributes add: #''squeak4.2.x''] ifFalse: [ (versionString beginsWith: ''Squeak4.3'') ifTrue: [ attributes add: #''squeak4.3.x'' ] ifFalse: [ (versionString beginsWith: ''Squeak4.4'') ifTrue: [ attributes add: #''squeak4.4.x'' ] ] ] ] ] ]. ^ attributes'! ! !ConfigurationOfFuel class methodsFor: 'accessing' stamp: 'MaxLeske 12/29/2012 19:02'! project "ensure that Metacello has been bootstrapped" self new project. "fix Metacello" self ensureMetacelloForPharo11x; fixSqueakPlatformAttributes; addSqueakHacks. ^ self new project! ! !ConfigurationOfFuel class methodsFor: 'hudson' stamp: 'MarianoMartinezPeck 7/23/2012 18:18'! testsCategoriesForHudson "Actually this method should be renamed to testsPackagesForHudson because Hudson expects a list of pacakges, not categories." ^ #( 'FuelTests' 'FuelProgressUpdate-Tests' 'FuelBenchmarks-Tests' 'FuelCompression-Tests' 'FuelMetalevelTests' 'FuelDebug-Tests')! ! !ConfigurationOfFuel class methodsFor: 'development support' stamp: 'MartinDias 2/19/2011 03:09'! validate "Check the configuration for Errors, Critical Warnings, and Warnings (see class comment for MetacelloMCVersionValidator for more information). Errors identify specification issues that will result in unexpected behaviour when you load the configuration. Critical Warnings identify specification issues that may result in unexpected behavior when you load the configuration. Warnings identify specification issues that are technically correct, but are worth take a look at." "self validate" self ensureMetacello. ^ ((Smalltalk at: #MetacelloToolBox) validateConfiguration: self debug: #() recurse: false) explore! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 5/24/2011 15:26'! baseline10: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelBenchmarks' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarksMC2' with: [ spec requires: 'FuelBenchmarks'; requires: 'Monticello2' ]; package: 'FuelBenchmarksMagma' with: [ spec requires: 'FuelBenchmarks'; requires: 'Magma' ]. spec project: 'Monticello2' with: [ spec className: 'ConfigurationOfMonticello2'; loads: #('DEFAULT'); file: 'ConfigurationOfMonticello2'; repository: 'http://source.wiresong.ca/mc/' ]. spec project: 'Magma' with: [ spec className: 'ConfigurationOfMagma'; loads: #('default'); file: 'ConfigurationOfMagma'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec group: 'default' with: #('Fuel' 'Benchmarks' ); group: 'Core' with: #('Fuel'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'MC2Benchmarks' with: #('FuelBenchmarksMC2'); group: 'MagmaBenchmarks' with: #('FuelBenchmarksMagma') ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 5/24/2011 15:26'! baseline11: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelBenchmarks' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarksMC2' with: [ spec requires: 'FuelBenchmarks'; requires: 'Monticello2' ]; package: 'FuelBenchmarksMagma' with: [ spec requires: 'FuelBenchmarks'; requires: 'Magma' ]; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]. spec project: 'Monticello2' with: [ spec className: 'ConfigurationOfMonticello2'; loads: #('DEFAULT'); file: 'ConfigurationOfMonticello2'; repository: 'http://source.wiresong.ca/mc/' ]. spec project: 'Magma' with: [ spec className: 'ConfigurationOfMagma'; loads: #('default'); file: 'ConfigurationOfMagma'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec group: 'default' with: #('Fuel' 'Benchmarks' ); group: 'Core' with: #('Fuel'); group: 'CoreWithProgressBar' with: #('Fuel' 'FuelProgressUpdate'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'MC2Benchmarks' with: #('FuelBenchmarksMC2'); group: 'MagmaBenchmarks' with: #('FuelBenchmarksMagma') ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 5/15/2011 19:00'! baseline12: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelBenchmarks' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarksMC2' with: [ spec requires: 'FuelBenchmarks'; requires: 'Monticello2' ]; package: 'FuelBenchmarksMagma' with: [ spec requires: 'FuelBenchmarks'; requires: 'Magma' ]; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelContainer' with: [ spec requires: 'Fuel' ]; package: 'FuelTests' with: [ spec requires: 'Fuel' ]. spec project: 'Monticello2' with: [ spec className: 'ConfigurationOfMonticello2'; loads: #('DEFAULT'); file: 'ConfigurationOfMonticello2'; repository: 'http://source.wiresong.ca/mc/' ]. spec project: 'Magma' with: [ spec className: 'ConfigurationOfMagma'; loads: #('default'); file: 'ConfigurationOfMagma'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec group: 'default' with: #('Fuel' 'Tests' 'Benchmarks' ); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Fuel' 'FuelProgressUpdate' 'FuelContainer'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'MC2Benchmarks' with: #('FuelBenchmarksMC2'); group: 'MagmaBenchmarks' with: #('FuelBenchmarksMagma') ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 10/12/2011 12:12'! baseline15: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelContainer' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests') ]; package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelLogo'. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'default' with: #('Core' 'Tests' 'Benchmarks'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Fuel' 'FuelProgressUpdate' 'FuelContainer'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm') ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 10/12/2011 12:12'! baseline16: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelContainer' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests') ]; package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelLogo'; package: 'FuelExamples' with: [ spec requires: 'FuelProgressUpdate']; package: 'FuelPackageLoader' with: [ spec requires: 'Fuel' ]; package: 'FuelPackageLoaderTests' with: [ spec requires: #('FuelPackageLoader' 'FuelTests' ) ]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'default' with: #('Core' 'Tests' 'Benchmarks' 'Examples'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Fuel' 'FuelProgressUpdate' 'FuelContainer'); group: 'Tests' with: #('FuelTests'); group: 'Examples' with: #('FuelExamples'); group: 'PackageLoader' with: #('FuelPackageLoader'); group: 'PackageLoaderWithTests' with: #('FuelPackageLoader' 'FuelPackageLoaderTests'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm') ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MarianoMartinezPeck 10/27/2011 12:37'! baseline17: spec spec for: #pharo do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelContainer' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests') ]; package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelLogo'; package: 'FuelExamples' with: [ spec requires: 'FuelProgressUpdate']; package: 'FuelPackageLoader' with: [ spec requires: 'Fuel' ]; package: 'FuelPackageLoaderTests' with: [ spec requires: #('FuelPackageLoader' 'FuelTests' ) ]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'default' with: #('Core' 'Tests' 'Benchmarks' 'Examples'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Fuel' 'FuelProgressUpdate'); group: 'Tests' with: #('FuelTests'); group: 'Examples' with: #('FuelExamples'); group: 'PackageLoader' with: #('FuelPackageLoader'); group: 'PackageLoaderWithTests' with: #('FuelPackageLoader' 'FuelPackageLoaderTests'); group: 'Benchmarks' with: #('FuelBenchmarks'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelLogo' 'Examples' 'PackageLoaderWithTests' 'FuelContainer') ]. spec for: #'pharo1.2.x' do: [ spec package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'Fuel' )]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' )]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MaxLeske 12/29/2012 23:24'! baseline181: spec spec for: #squeakCommon do: [ spec blessing: #baseline. spec repository: 'http://ss3.gemstone.com/ss/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelDebug' with: [ spec requires: 'Fuel' ]; package: 'FuelUtilities'; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests' 'FuelUtilities') ]; package: 'FuelCompression' with: [ spec requires: #('Fuel' 'FuelTests' ) ]. spec package: 'FuelCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak44' ) ]; package: 'FuelCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak45' ) ]; package: 'FuelCompatibilityBeforeSqueak45' with: [ spec requires: #( 'Fuel' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak44' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak45' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak45' with: [ spec requires: #( 'FuelTests' ) ]. spec package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' ) ]; package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'FuelCompatibilityBeforePharo14' ) ]; package: 'FuelCompatibilityBeforePharo14' with: [ spec requires: #( 'FuelCompatibilityBeforePharo20' ) ]; package: 'FuelCompatibilityBeforePharo20' with: [ spec requires: #( 'FuelCompatibilityBeforePharo21' ) ]; package: 'FuelCompatibilityBeforePharo21' with: [ spec requires: #( 'Fuel' ) ]; package: 'FuelTestsCompatibilityBeforePharo21' with: [ spec requires: #( 'FuelTests' ) ]. spec group: 'default' with: #('Core' 'Tests'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Core' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'). ]. spec for: #pharo do: [ spec package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelPackageLoader' with: [ spec requires: #('Fuel' 'FuelMetalevel' ) ]; package: 'FuelPackageLoaderMetacello' with: [ spec requires: #( 'FuelPackageLoader' ) ]; package: 'FuelPackageLoaderTests' with: [ spec requires: #('FuelPackageLoader' 'FuelTests' )]; package: 'FuelPreview' with: [ spec requires: #( 'FuelDebug' 'Roassal')]; package: 'FuelMetalevel' with: [ spec requires: #( 'Fuel' )]; package: 'FuelMetalevelTests' with: [ spec requires: #('FuelMetalevel' 'FuelTests' )]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Roassal' with: [ spec className: 'ConfigurationOfRoassal'; loads: #('default'); file: 'ConfigurationOfRoassal'; repository: 'http://www.squeaksource.com/Roassal' ]. spec project: 'FileSystem' with: [ spec className: 'ConfigurationOfFilesystem'; loads: #('default'); file: 'ConfigurationOfFilesystem'; repository: 'http://www.squeaksource.com/fs' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'CoreWithExtras' with: #('Core' 'FuelMetalevel' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests' ); group: 'PackageLoader' with: #('FuelPackageLoader' 'FuelPackageLoaderMetacello'); group: 'PackageLoaderWithTests' with: #('PackageLoader' 'FuelPackageLoaderTests'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'FuelMetalevelTests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' PackageLoader 'PackageLoaderWithTests' 'FuelDebug' 'FuelUtilities'). ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem'; package: 'FuelFileSystemTests' with: [ spec requires: #('FuelTests')]; package: 'FuelCommandLineHandler'. spec group: 'DevelopmentGroup' with: #('FuelFileSystem' 'FuelFileSystemTests' 'FuelCommandLineHandler'). spec group: 'Core' with: #('FuelCompatibilityBeforePharo21'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo21'). ]. spec for: #'pharo1.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo20'). ]. spec for: #'pharo1.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo14'). ]. spec for: #'pharo1.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'Fuel' with: [ spec preLoadDoIt: #preLoadInPharo11]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). ]. spec for: #'squeak4.1.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak42'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak42'). ]. spec for: #'squeak4.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak44'). ]. spec for: #'squeak4.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak44'). ]. spec for: #'squeak4.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak45'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak45'). ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MaxLeske 2/18/2013 23:03'! baseline182: spec spec for: #squeakCommon do: [ spec blessing: #baseline. spec repository: 'http://ss3.gemstone.com/ss/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelDebug' with: [ spec requires: 'Fuel' ]; package: 'FuelUtilities'; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests' 'FuelUtilities') ]; package: 'FuelCompression' with: [ spec requires: #('Fuel' 'FuelTests' ) ]. spec package: 'FuelCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak44' ) ]; package: 'FuelCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak45' ) ]; package: 'FuelCompatibilityBeforeSqueak45' with: [ spec requires: #( 'Fuel' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak44' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak45' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak45' with: [ spec requires: #( 'FuelTests' ) ]. spec package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' ) ]; package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'FuelCompatibilityBeforePharo14' ) ]; package: 'FuelCompatibilityBeforePharo14' with: [ spec requires: #( 'FuelCompatibilityBeforePharo20' ) ]; package: 'FuelCompatibilityBeforePharo20' with: [ spec requires: #( 'FuelCompatibilityBeforePharo21' ) ]; package: 'FuelCompatibilityBeforePharo21' with: [ spec requires: #( 'Fuel' ) ]; package: 'FuelTestsCompatibilityBeforePharo20' with: [ spec requires: #( 'FuelCompatibilityBeforePharo21' 'FuelTestsCompatibilityBeforePharo21' ) ]; package: 'FuelTestsCompatibilityBeforePharo21' with: [ spec requires: #( 'FuelTests' ) ]. spec group: 'default' with: #('Core' 'Tests'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Core' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'). ]. spec for: #pharo do: [ spec package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelPackageLoader' with: [ spec requires: #('Fuel' 'FuelMetalevel' ) ]; package: 'FuelPackageLoaderMetacello' with: [ spec requires: #( 'FuelPackageLoader' ) ]; package: 'FuelPackageLoaderTests' with: [ spec requires: #('FuelPackageLoader' 'FuelTests' )]; package: 'FuelPreview' with: [ spec requires: #( 'FuelDebug' 'Roassal')]; package: 'FuelMetalevel' with: [ spec requires: #( 'Fuel' )]; package: 'FuelMetalevelTests' with: [ spec requires: #('FuelMetalevel' 'FuelTests' )]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Roassal' with: [ spec className: 'ConfigurationOfRoassal'; loads: #('default'); file: 'ConfigurationOfRoassal'; repository: 'http://www.squeaksource.com/Roassal' ]. spec project: 'FileSystem' with: [ spec className: 'ConfigurationOfFilesystem'; loads: #('default'); file: 'ConfigurationOfFilesystem'; repository: 'http://www.squeaksource.com/fs' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'CoreWithExtras' with: #('Core' 'FuelMetalevel' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests' ); group: 'PackageLoader' with: #('FuelPackageLoader' 'FuelPackageLoaderMetacello'); group: 'PackageLoaderWithTests' with: #('PackageLoader' 'FuelPackageLoaderTests'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'FuelMetalevelTests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' PackageLoader 'PackageLoaderWithTests' 'FuelDebug' 'FuelUtilities'). ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem'; package: 'FuelFileSystemTests' with: [ spec requires: #('FuelTests')]; package: 'FuelCommandLineHandler'. spec group: 'DevelopmentGroup' with: #('FuelFileSystem' 'FuelFileSystemTests' 'FuelCommandLineHandler'). spec group: 'Core' with: #('FuelCompatibilityBeforePharo21'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo21'). ]. spec for: #'pharo1.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo20'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo14'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'Fuel' with: [ spec preLoadDoIt: #preLoadInPharo11]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'squeak4.1.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak42'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak42'). ]. spec for: #'squeak4.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak44'). ]. spec for: #'squeak4.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak44'). ]. spec for: #'squeak4.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak45'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak45'). ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MMP 6/10/2012 19:52'! baseline18: spec spec for: #squeakCommon do: [ spec blessing: #baseline. spec repository: 'http://ss3.gemstone.com/ss/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelDebug' with: [ spec requires: 'Fuel' ]; package: 'FuelUtilities'; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests' 'FuelUtilities') ]; package: 'FuelCompression' with: [ spec requires: #('Fuel' 'FuelTests' ) ]. spec package: 'FuelCompatibilityForSqueak' with: [ spec requires: #( 'FuelCompatibilityBeforePharo12' ) ]; package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' ) ]; package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'FuelCompatibilityBeforePharo14' ) ]; package: 'FuelCompatibilityBeforePharo14' with: [ spec requires: #( 'FuelCompatibilityBeforePharo20' ) ]; package: 'FuelCompatibilityBeforePharo20' with: [ spec requires: #( 'Fuel' ) ]. spec package: 'FuelTestsCompatibilityForSqueak' with: [ spec requires: #( 'FuelTests' ) ]. spec group: 'default' with: #('Core' 'Tests'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Core' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'). ]. spec for: #pharo do: [ spec package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelPackageLoader' with: [ spec requires: #('Fuel' 'FuelMetalevel' ) ]; package: 'FuelPackageLoaderMetacello' with: [ spec requires: #( 'FuelPackageLoader' ) ]; package: 'FuelPackageLoaderTests' with: [ spec requires: #('FuelPackageLoader' 'FuelTests' )]; package: 'FuelPreview' with: [ spec requires: #( 'FuelDebug' 'Roassal')]; package: 'FuelMetalevel' with: [ spec requires: #( 'Fuel' )]; package: 'FuelMetalevelTests' with: [ spec requires: #('FuelMetalevel' 'FuelTests' )]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Roassal' with: [ spec className: 'ConfigurationOfRoassal'; loads: #('default'); file: 'ConfigurationOfRoassal'; repository: 'http://www.squeaksource.com/Roassal' ]. spec project: 'FileSystem' with: [ spec className: 'ConfigurationOfFilesystem'; loads: #('default'); file: 'ConfigurationOfFilesystem'; repository: 'http://www.squeaksource.com/fs' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'CoreWithExtras' with: #('Core' 'FuelMetalevel' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests' ); group: 'PackageLoader' with: #('FuelPackageLoader' 'FuelPackageLoaderMetacello'); group: 'PackageLoaderWithTests' with: #('PackageLoader' 'FuelPackageLoaderTests'); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'FuelMetalevelTests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' PackageLoader 'PackageLoaderWithTests' 'FuelDebug' 'FuelUtilities'). ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem'; package: 'FuelFileSystemTests' with: [ spec requires: #('FuelTests')]; package: 'FuelCommandLineHandler'. spec group: 'DevelopmentGroup' with: #('FuelFileSystem' 'FuelFileSystemTests' 'FuelCommandLineHandler'). ]. spec for: #'pharo1.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo20'). ]. spec for: #'pharo1.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo14'). ]. spec for: #'pharo1.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'Fuel' with: [ spec preLoadDoIt: #preLoadInPharo11]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). ]. spec for: #squeak do: [ spec group: 'Core' with: #('FuelCompatibilityForSqueak'). spec group: 'Tests' with: #('FuelTestsCompatibilityForSqueak'). ]. ! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MaxLeske 2/27/2013 23:24'! baseline19: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://ss3.gemstone.com/ss/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelDebug' with: [ spec requires: 'Fuel' ]; package: 'FuelUtilities'; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests' 'FuelUtilities') ]. spec package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' ) ]; package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'FuelCompatibilityBeforePharo14' ) ]; package: 'FuelCompatibilityBeforePharo14' with: [ spec requires: #( 'FuelCompatibilityBeforePharo20' ) ]; package: 'FuelCompatibilityBeforePharo20' with: [ spec requires: #( 'Fuel' ) ]. spec package: 'FuelCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak44' ) ]; package: 'FuelCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelCompatibilityBeforeSqueak45' ) ]; package: 'FuelCompatibilityBeforeSqueak45' with: [ spec requires: #( 'Fuel' ) ]. spec package: 'FuelTestsCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelTestsCompatibilityBeforePharo20' ) ]; package: 'FuelTestsCompatibilityBeforePharo20' with: [ spec requires: #( 'FuelTestsCompatibilityBeforePharo21' ) ]; package: 'FuelTestsCompatibilityBeforePharo21' with: [ spec requires: #( 'FuelTests' ) ]. spec package: 'FuelTestsCompatibilityBeforeSqueak42' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak43' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak43' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak44' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak44' with: [ spec requires: #( 'FuelTestsCompatibilityBeforeSqueak45' ) ]; package: 'FuelTestsCompatibilityBeforeSqueak45' with: [ spec requires: #( 'FuelTests' ) ]. spec group: 'default' with: #('Core' 'Tests'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Core' 'FuelProgressUpdate'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'). ]. spec for: #pharo do: [ spec package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelPreview' with: [ spec requires: #( 'FuelDebug' 'Roassal')]; package: 'FuelMetalevel' with: [ spec requires: #( 'Fuel' )]; package: 'FuelMetalevelTests' with: [ spec requires: #('FuelMetalevel' 'FuelTests' )]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Roassal' with: [ spec className: 'ConfigurationOfRoassal'; loads: #('default'); file: 'ConfigurationOfRoassal'; repository: 'http://www.squeaksource.com/Roassal' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'CoreWithExtras' with: #('Core' 'FuelMetalevel' 'FuelProgressUpdate'); group: 'Tests' with: #('FuelTests' ); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'FuelMetalevelTests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelDebug' 'FuelUtilities'). ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelTools-Debugger' with: [ spec requires: #('Fuel' ) ]; package: 'FuelCommandLineHandler' with: [ spec requires: #('Fuel' ) ]; package: 'FuelSystem-FileRegistry' with: [ spec requires: #('Fuel' ) ]. spec group: 'kernel' with: #( 'FuelCommandLineHandler' ). spec group: 'Core' with: #('FuelCommandLineHandler' 'FuelSystem-FileRegistry' 'FuelTools-Debugger'). ]. spec for: #'pharo1.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo20'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo14'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo20'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'Fuel' with: [ spec preLoadDoIt: #preLoadInPharo11]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforePharo12'). ]. spec for: #'squeak4.1.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak42'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak42'). ]. spec for: #'squeak4.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak43'). ]. spec for: #'squeak4.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak44'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak44'). ]. spec for: #'squeak4.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforeSqueak45'). spec group: 'Tests' with: #('FuelTestsCompatibilityBeforeSqueak45'). ].! ! !ConfigurationOfFuel methodsFor: 'baselines' stamp: 'MartinDias 3/25/2013 18:21'! baseline19AlphaForTanker: spec spec for: #squeakCommon do: [ spec blessing: #baseline. spec repository: 'http://ss3.gemstone.com/ss/Fuel'. spec package: 'Fuel'; package: 'FuelTests' with: [ spec requires: 'Fuel' ]; package: 'FuelDebug' with: [ spec requires: 'Fuel' ]; package: 'FuelUtilities'; package: 'FuelProgressUpdate' with: [ spec requires: 'Fuel' ]; package: 'FuelBenchmarks' with: [ spec requires: #('Fuel' 'FuelTests' 'FuelUtilities') ]; package: 'FuelCompression' with: [ spec requires: #('Fuel' 'FuelTests' ) ]. spec package: 'FuelCompatibilityForSqueak' with: [ spec requires: #( 'FuelCompatibilityBeforePharo12' ) ]; package: 'FuelCompatibilityBeforePharo12' with: [ spec requires: #( 'FuelCompatibilityBeforePharo13' ) ]; package: 'FuelCompatibilityBeforePharo13' with: [ spec requires: #( 'FuelCompatibilityBeforePharo14' ) ]; package: 'FuelCompatibilityBeforePharo14' with: [ spec requires: #( 'FuelCompatibilityBeforePharo20' ) ]; package: 'FuelCompatibilityBeforePharo20' with: [ spec requires: #( 'Fuel' ) ]. spec package: 'FuelTestsCompatibilityForSqueak' with: [ spec requires: #( 'FuelTests' ) ]. spec group: 'default' with: #('Core' 'Tests'); group: 'Core' with: #('Fuel'); group: 'CoreWithExtras' with: #('Core' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests'); group: 'Benchmarks' with: #('FuelBenchmarks'). ]. spec for: #pharo do: [ spec package: 'FuelBenchmarksMagma' with: [ spec requires: #('FuelBenchmarks' 'MagmaBase') ]; package: 'FuelBenchmarksSIXX' with: [ spec requires: #('FuelBenchmarks' 'SIXX') ]; package: 'FuelBenchmarksStomp' with: [ spec requires: #('FuelBenchmarks' 'StOMP') ]; package: 'FuelProgressUpdateBenchmarks' with: [ spec requires: #('FuelBenchmarks' 'FuelProgressUpdate') ]; package: 'FuelBenchmarksSRP' with: [ spec requires: #('FuelBenchmarks' 'SRP') ]; package: 'FuelBenchmarksEsAndEm' with: [ spec requires: #('FuelBenchmarks' 'EsAndEm') ]; package: 'FuelPreview' with: [ spec requires: #( 'FuelDebug' 'Roassal')]; package: 'FuelMetalevel' with: [ spec requires: #( 'Fuel' )]; package: 'FuelMetalevelTests' with: [ spec requires: #('FuelMetalevel' 'FuelTests' )]. spec project: 'MagmaBase' with: [ spec className: 'ConfigurationOfMaBase'; loads: #('default'); file: 'ConfigurationOfMaBase'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'SIXX' with: [ spec className: 'ConfigurationOfSIXX'; loads: #('default'); file: 'ConfigurationOfSIXX'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'StOMP' with: [ spec className: 'ConfigurationOfStOMP'; loads: #('default'); file: 'ConfigurationOfStOMP'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Roassal' with: [ spec className: 'ConfigurationOfRoassal'; loads: #('default'); file: 'ConfigurationOfRoassal'; repository: 'http://www.squeaksource.com/Roassal' ]. spec package: 'SRP' with: [ spec repository: 'http://www.squeaksource.com/SRP' ]. spec package: 'EsAndEm' with: [ spec repository: 'http://source.wiresong.ca/mc' ]. spec group: 'CoreWithExtras' with: #('Core' 'FuelMetalevel' 'FuelProgressUpdate' 'FuelCompression'); group: 'Tests' with: #('FuelTests' ); group: 'BenchmarksSIXX' with: #('Benchmarks' 'FuelBenchmarksSIXX'); group: 'BenchmarksAllBinarySerializers' with: #('Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelBenchmarksStomp' 'FuelBenchmarksMagma' 'FuelBenchmarksSRP' 'FuelBenchmarksEsAndEm'); group: 'DevelopmentGroup' with: #('CoreWithExtras' 'Tests' 'FuelMetalevelTests' 'Benchmarks' 'FuelProgressUpdateBenchmarks' 'FuelDebug' 'FuelUtilities'). ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelCommandLineHandler'. spec group: 'DevelopmentGroup' with: #('FuelCommandLineHandler'). ]. spec for: #'pharo1.4.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo20'). ]. spec for: #'pharo1.3.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo14'). ]. spec for: #'pharo1.2.x' do: [ spec group: 'Core' with: #('FuelCompatibilityBeforePharo13'). ]. spec for: #'pharo1.1.x' do: [ spec package: 'Fuel' with: [ spec preLoadDoIt: #preLoadInPharo11]. spec group: 'Core' with: #('FuelCompatibilityBeforePharo12'). ]. spec for: #squeak do: [ spec group: 'Core' with: #('FuelCompatibilityForSqueak'). spec group: 'Tests' with: #('FuelTestsCompatibilityForSqueak'). ]. ! ! !ConfigurationOfFuel methodsFor: 'symbolic versions' stamp: 'MartinDias 2/25/2013 18:44'! development: spec spec for: #common version: '1.9'! ! !ConfigurationOfFuel methodsFor: 'do-its' stamp: 'MaxLeske 12/30/2012 10:13'! preLoadInPharo11 Author useAuthor: 'MarianoMartinezPeck' during: [ SequenceableCollection compile: 'shuffleBy: aRandom self size to: 2 by: -1 do: [ :i | self swap: i with: (aRandom nextInt: i) ] ' ]! ! !ConfigurationOfFuel methodsFor: 'accessing' stamp: 'MartinDias 2/19/2011 03:09'! project ^ project ifNil: [ | constructor | "Bootstrap Metacello if it is not already loaded" (self class baseConfigurationClassIfAbsent: []) ensureMetacello. "Construct Metacello project" constructor := (Smalltalk at: #MetacelloVersionConstructor) on: self. project := constructor project. project loadType: #linear. "change to #atomic if desired" project ]! ! !ConfigurationOfFuel methodsFor: 'symbolic versions' stamp: 'MaxLeske 5/18/2013 11:20'! stable: spec spec for: #common version: '1.9.1'! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 5/24/2011 15:26'! version10: spec spec for: #pharo do: [ spec blessing: #release. spec package: 'Fuel' with: 'Fuel-MartinDias.84'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.4'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.1'; package: 'FuelBenchmarksMC2' with: 'FuelBenchmarksMC2-MartinDias.1' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 5/24/2011 15:26'! version11: spec spec for: #pharo do: [ spec blessing: #release. spec package: 'Fuel' with: 'Fuel-MartinDias.84'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.4'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.4'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.1'; package: 'FuelBenchmarksMC2' with: 'FuelBenchmarksMC2-MartinDias.1' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 5/24/2011 15:25'! version12: spec spec for: #pharo do: [ spec blessing: #release. spec package: 'Fuel' with: 'Fuel-MartinDias.193'; package: 'FuelTests' with: 'FuelTests-MartinDias.2'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MarianoMartinezPeck.9'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.6'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.1'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.3'; package: 'FuelBenchmarksMC2' with: 'FuelBenchmarksMC2-MartinDias.1' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 6/1/2011 14:04'! version13: spec spec for: #pharo do: [ spec blessing: #release. spec description: ' - Class serialization without ClassBuilder. - MethodContext and BlockClosure serialization. - Some fixes on configuration itself '. spec package: 'Fuel' with: 'Fuel-MarianoMartinezPeck.225'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.21'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MarianoMartinezPeck.20'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.6'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.1'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.3'; package: 'FuelBenchmarksMC2' with: 'FuelBenchmarksMC2-MartinDias.1' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 6/1/2011 14:03'! version14: spec spec for: #pharo do: [ spec blessing: #release. spec description: ' - New support for serialization in memory - Name refactorings in some hierarchies and protocols. - Object cluster big refactoring - Hack that avoids several OrderedCollection>>makeRoomAtLast. - Other cleanups '. spec package: 'Fuel' with: 'Fuel-MartinDias.243'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.33'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.26'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.8'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.1'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.3'; package: 'FuelBenchmarksMC2' with: 'FuelBenchmarksMC2-MartinDias.1' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 8/13/2011 05:31'! version15: spec spec for: #pharo do: [ spec blessing: #release. spec description: ' - Initialize instances after materialization implementing #fuelAfterMaterialization. - Ignore transient instance variables overriding #fuelIgnoredInstanceVariableNames. - Limit serialization progress bar to update at most once every 250 milliseconds. - Traits are serialized and materialized as a regular objects (http://code.google.com/p/fuel/issues/detail?id=59). - Removed mappers system cache (Eliot). - Many new tests. - Benchmarks: compare Fuel against StOMP, SRP, SIXX, Magma, EsAndEm and Fuel with progress bar. - Benchmarks: new samples, scripts, and CSV exporter. - Benchmarks: measure serialization stream size. - Removed some redundant #fuelAccept:. - Several aesthetic changes in protocols, categories and comments. - Now #materialize answers the materialized root. - Removed special cluster for HashedCollection.Now #rehash is sended via #fuelAfterMaterialization. - MethodContext serialization does not serialize temps (http://code.google.com/p/fuel/issues/detail?id=61). - Classes and Traits now serialize its environment (testCreateWithSmalltalkGlobalsEnvironment). - Fixed serialization of non-octet characters (testCharacter). - Fixed a bug serializing the system dictionary. FLWellKnownObjectsCluster handles it. (testSmalltalkGlobals). - Fixed a bug serializing class variables (testClassVariable). - Fixed a bug when serializing a collection with size greater than 1^16 with repeated elements inside. - Fixed testTwoCompiledMethodsReferencingSameClassVariable. - Optimization: instanceIndexes are directly created with the exact size (Henrik). '. spec package: 'Fuel' with: 'Fuel-MartinDias.267'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.77'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.62'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.14'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.1'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MarianoMartinezPeck.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 9/24/2011 19:40'! version161: spec spec for: #pharo do: [ spec blessing: #development. spec description: ' . '. spec package: 'Fuel' with: 'Fuel-MarianoMartinezPeck.444'; package: 'FuelTests' with: 'FuelTests-MartinDias.118'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.77'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.24'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MartinDias.42'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MartinDias.3'; package: 'FuelContainer' with: 'FuelContainer-MarianoMartinezPeck.2'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.7'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 8/18/2011 23:30'! version16: spec spec for: #pharo do: [ spec blessing: #release. spec description: ' This version does not add any new concrete functionality but has two main achievements: a performance improvement and a design clean up. Many changes included in this release are part of a design clean up. They are a necessary step forward to new functionalities that are coming soon. They make code more understandable. They enable simpler extension. Happily they also helped to improve serialization performance by reducing unnecessary interactions. And is specially important a bottleneck in graph analysis stage we have attacked, obtaining great results. Details: - Removed explicit references to cluster classes scattered around the system. For example, in previous versions Float>>fuelCluster has an explicit reference to FLFloatCluster. This version replaces this by a double dispatch interaction. - Clusters: Better reification. Removed annoying IDs. Removed Singleton instance creation machanism, now mappers manage uniqueness in a better way. - Mappers: They were simplified. New mapping machanism inspired on Chain of Responsibility pattern. The global objects detection has been reduced considerably. - Analyzer: Part of its behavior and state has been moved to a new abstraction called "clusterization". '. spec package: 'Fuel' with: 'Fuel-MartinDias.338'; package: 'FuelTests' with: 'FuelTests-MartinDias.84'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.68'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.15'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.1'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MarianoMartinezPeck.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 10/14/2011 02:51'! version17: spec spec for: #pharo do: [ spec blessing: #release. spec description: ' The list of changes includes performance optimizations, design clean-ups, and new features. - The FLSerializer and FLMaterializer API has changed. They are no longer implementing the algorithms but are a kind of Façade. - Serialization substitutions: "Store this object instead of me." - Global sends: "Restore me by sending this selector to this global" - Versioning the stream: We prefix the stream with a version number that should match when loading. - Performance optimizations on instances of: - Word-like classes. (We thank a lot to Henrik Sperre Johansen for your help!!) - ByteString and Symbol. - Date, Time, Duration and DateAndTime. - Point and Rectangle. - MethodDictionary. Now materialization is 2000x faster, thanks to its new rehash without become. - Huge clean-up in Tests package.'. spec package: 'Fuel' with: 'Fuel-MartinDias.479'; package: 'FuelTests' with: 'FuelTests-MartinDias.157'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.88'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.27'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.2'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MartinDias.43'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MartinDias.6'; package: 'FuelExamples' with: 'FuelExamples-MartinDias.5'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.3'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.7'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 1/1/2013 19:26'! version181: spec spec for: #'squeakCommon' do: [ spec blessing: #release. spec description: ' - same as 1.8 - fix: serialization / materialization of Date objects. - do not use Pharo compatibility packages for Squeak - use individual compatibility packages for Squeak - new compatibility fixes - supported images: Pharo 1.1.1, 1.1.2, 1.2, 1.3, 1.4, 2.0 Squeak 4.1, 4.2, 4.3, 4.4'. spec package: 'Fuel' with: 'Fuel-MaxLeske.686'; package: 'FuelTests' with: 'FuelTests-MartinDias.267'; package: 'FuelDebug' with: 'FuelDebug-MartinDias.8'; package: 'FuelUtilities' with: 'FuelUtilities-MartinDias.1'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.54'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.140'; package: 'FuelCompression' with: 'FuelCompression-MartinDias.9'; package: 'FuelCompatibilityBeforeSqueak42' with: 'FuelCompatibilityBeforeSqueak42-MaxLeske.1'; package: 'FuelCompatibilityBeforeSqueak44' with: 'FuelCompatibilityBeforeSqueak44-MaxLeske.4'; package: 'FuelCompatibilityBeforeSqueak45' with: 'FuelCompatibilityBeforeSqueak45-MaxLeske.3'; package: 'FuelTestsCompatibilityBeforeSqueak42' with: 'FuelTestsCompatibilityBeforeSqueak42-MaxLeske.2'; package: 'FuelTestsCompatibilityBeforeSqueak44' with: 'FuelTestsCompatibilityBeforeSqueak44-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforeSqueak45' with: 'FuelTestsCompatibilityBeforeSqueak45-MaxLeske.6'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MartinDias.8'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.3'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MartinDias.3'; package: 'FuelCompatibilityBeforePharo20' with: 'FuelCompatibilityBeforePharo20-MaxLeske.12'; package: 'FuelCompatibilityBeforePharo21' with: 'FuelCompatibilityBeforePharo21-MaxLeske.3'; package: 'FuelTestsCompatibilityBeforePharo21' with: 'FuelTestsCompatibilityBeforePharo21-MaxLeske.5' ]. spec for: #'pharo' do: [ spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8.3'; project: 'Roassal' with: '1.0'; project: 'FileSystem' with: '2.0.4'. spec package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.7'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-MartinDias.4'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MartinDias.2'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.12'; package: 'FuelBenchmarksSRP' with: 'FuelBenchmarksSRP-MartinDias.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MartinDias.4'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MarianoMartinezPeck.105'; package: 'FuelPackageLoaderMetacello' with: 'FuelPackageLoaderMetacello-MarianoMartinezPeck.3'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MarianoMartinezPeck.32'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.10'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.50'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MartinDias.43'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem' with: 'FuelFileSystem-PavelKrivanek.4'; package: 'FuelFileSystemTests' with: 'FuelFileSystemTests-MarianoMartinezPeck.2'; package: 'FuelCommandLineHandler' with: 'FuelCommandLineHandler-MarianoMartinezPeck.3'. ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MaxLeske 2/19/2013 20:20'! version182: spec spec for: #'squeakCommon' do: [ spec blessing: #release. spec description: ' - Date / DateAndTime are now serialized consistently across different images (Squeak and Pharo) - improvements to compatibility packages '. spec package: 'Fuel' with: 'Fuel-MaxLeske.687'; package: 'FuelTests' with: 'FuelTests-MartinDias.267'; package: 'FuelDebug' with: 'FuelDebug-MartinDias.8'; package: 'FuelUtilities' with: 'FuelUtilities-MartinDias.1'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.54'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.140'; package: 'FuelCompression' with: 'FuelCompression-MartinDias.9'; package: 'FuelCompatibilityBeforeSqueak42' with: 'FuelCompatibilityBeforeSqueak42-MaxLeske.1'; package: 'FuelCompatibilityBeforeSqueak44' with: 'FuelCompatibilityBeforeSqueak44-MaxLeske.4'; package: 'FuelCompatibilityBeforeSqueak45' with: 'FuelCompatibilityBeforeSqueak45-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforeSqueak42' with: 'FuelTestsCompatibilityBeforeSqueak42-MaxLeske.2'; package: 'FuelTestsCompatibilityBeforeSqueak44' with: 'FuelTestsCompatibilityBeforeSqueak44-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforeSqueak45' with: 'FuelTestsCompatibilityBeforeSqueak45-MaxLeske.6'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MaxLeske.9'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.3'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MartinDias.3'; package: 'FuelCompatibilityBeforePharo20' with: 'FuelCompatibilityBeforePharo20-MaxLeske.17'; package: 'FuelCompatibilityBeforePharo21' with: 'FuelCompatibilityBeforePharo21-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo20' with: 'FuelTestsCompatibilityBeforePharo20-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo21' with: 'FuelTestsCompatibilityBeforePharo21-MaxLeske.5' ]. spec for: #'pharo' do: [ spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8.3'; project: 'Roassal' with: '1.0'; project: 'FileSystem' with: '2.0.4'. spec package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.7'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-MartinDias.4'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MartinDias.2'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.12'; package: 'FuelBenchmarksSRP' with: 'FuelBenchmarksSRP-MartinDias.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MartinDias.4'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MarianoMartinezPeck.105'; package: 'FuelPackageLoaderMetacello' with: 'FuelPackageLoaderMetacello-MarianoMartinezPeck.3'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MarianoMartinezPeck.32'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.10'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.50'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MartinDias.43'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem' with: 'FuelFileSystem-PavelKrivanek.4'; package: 'FuelFileSystemTests' with: 'FuelFileSystemTests-MarianoMartinezPeck.2'; package: 'FuelCommandLineHandler' with: 'FuelCommandLineHandler-MarianoMartinezPeck.3'. ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 5/26/2012 01:47'! version18: spec spec for: #'squeakCommon' do: [ spec blessing: #release. spec description: ' - Improved API for customizing how graph is traced. - FuelMetalevel: serialization of stuff like classes and compiled methods moved to an optional package. - Customize objects to be treated as globals. - Migrations: declare at materialization time class and variables renames. - Weak references properly managed. Thanks to Juan Vuletich and Levente. - Thanks Pavel for helping us improving FuelPackageLoader with wonderful ideas and bug reports. - Serialization speed up on large graphs by using specialized collections. Thanks Levente. - Encoder and Decoder: new reifications that clarify the design. Thanks Colin Putney. - Optimized serialization of clean BlockClosures, which do not need the whole stack of contexts. Thanks Juan Vuletich and Eliot Miranda. - Added a clear error hierarchy. - Debug facilities, including graph visualization using Roassal. Thanks Alexandre and Doru. - Many more new tests. Including those from extension packages, we have almost 600 tests. - Repository moved from squeaksource to ss3.'. spec package: 'Fuel' with: 'Fuel-MartinDias.685'; package: 'FuelTests' with: 'FuelTests-MartinDias.267'; package: 'FuelDebug' with: 'FuelDebug-MartinDias.8'; package: 'FuelUtilities' with: 'FuelUtilities-MartinDias.1'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.54'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.140'; package: 'FuelCompression' with: 'FuelCompression-MartinDias.9'; package: 'FuelCompatibilityForSqueak' with: 'FuelCompatibilityForSqueak-MMP.4'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MartinDias.8'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.3'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MartinDias.3'; package: 'FuelCompatibilityBeforePharo20' with: 'FuelCompatibilityBeforePharo20-MartinDias.4'. ]. spec for: #'pharo' do: [ spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8.3'; project: 'Roassal' with: '1.0'; project: 'FileSystem' with: '2.0.4'. spec package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.7'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-MartinDias.4'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MartinDias.2'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.12'; package: 'FuelBenchmarksSRP' with: 'FuelBenchmarksSRP-MartinDias.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MartinDias.4'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MarianoMartinezPeck.105'; package: 'FuelPackageLoaderMetacello' with: 'FuelPackageLoaderMetacello-MarianoMartinezPeck.3'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MarianoMartinezPeck.32'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.10'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.50'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MartinDias.43'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. ]. spec for: #'pharo2.0.x' do: [ spec package: 'FuelFileSystem' with: 'FuelFileSystem-PavelKrivanek.4'; package: 'FuelFileSystemTests' with: 'FuelFileSystemTests-MarianoMartinezPeck.2'; package: 'FuelCommandLineHandler' with: 'FuelCommandLineHandler-MarianoMartinezPeck.3'. ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 3/31/2012 12:09'! version18ForMarea: spec spec for: #pharo do: [ spec blessing: #beta. spec description: ' just a fixed version for marea paper '. spec package: 'Fuel' with: 'Fuel-MarianoMartinezPeck.618'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.214'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.105'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MarianoMartinezPeck.39'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MarianoMartinezPeck.6'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.2'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MarianoMartinezPeck.1'; package: 'FuelCompatibilityForSqueak' with: 'FuelCompatibilityForSqueak-MMP.4'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MarianoMartinezPeck.53'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MarianoMartinezPeck.7'; package: 'FuelExamples' with: 'FuelExamples-MarianoMartinezPeck.8'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.3'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.7'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'FuelCompression' with: 'FuelCompression-MarianoMartinezPeck.7'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.28'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MarianoMartinezPeck.15'; package: 'FuelPresentations' with: 'FuelPresentations-MartinDias.6'; package: 'FuelFileSystem' with: 'FuelFileSystem-MarianoMartinezPeck.3'; package: 'FuelFileSystemTests' with: 'FuelFileSystemTests-MarianoMartinezPeck.1'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.7'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MarianoMartinezPeck 1/19/2012 22:22'! version18beta1: spec spec for: #pharo do: [ spec blessing: #beta. spec description: ' == visibles to the user: - Metalevel serialization (serialization of classes, traits, compiled methods, etc) moved to a separate package FuelMetalevel. This makes Fuel core much smaller and eases the portability to other dialects such as Squeak and VW. It also makes sense, since almost nobody nobody uses "full" serialization for everything. - Previously methods were completely serialized by default. This includes for example, SortedCollection. Now, by default, methods are serialized as globals. Special treatment for DoIt: all methods by default continue to be considered as global unless they are a #DoIt, in which case it is serialized fully. - New special cluster for BlockClosures. Now "clean" closures avoid serializing the whole stack of contexts :) Thanks Juan Vuletich and Eliot Miranda. - Weak references properly managed. Thanks Juan Vuletich and Levente. - Fixed FLSerializer>>serialize:toFileNamed:. Thank you Norbert Hartl. - Store index references more efficiently by using less bytes when possible. It means reduction in stream size - Customize globals. Each user can add objects managed as global. It also lets the user to handle custom singletons. - Manual migrations: class and variables renames. - #visitSubstitution:by: - #visitGlobalSend:name:selector: - New FuelFileSystem compatibility package. It just adds a few extension methods to FileSystem streams. This way you can use Fuel with FileSystem streams out of the box. - New package FuelCompression, which is an experiment using a gzip stream. We discover some bugs in the streams, but in addition, some some tests failed and one crash the VM. So, do not consider this a production ready. But if you want to give us a hand… - New package FuelPreview for visualizating the object graph to serialize. This tool is based on Roassal. Thanks Tudor Girba and Alexander Bergel. - Official "port to Squeak". With this version, Fuel (only the core) works out of the box in Squeak 4.2 and 4.3. - This same version Fuel 1.8 can work in Pharo 1.1, 1.2, 1.3, 1.4, Squeak 4.2 and 4.3. You always need to load Fuel with Metacello and it will handle the compatibility packages. - Fuel code was migrated from http://www.squeaksource.com/Fuel to http://ss3.gemstone.com/ss/Fuel == not visibles: - Added new LargeIdentityHashedCollection. This improves up to 20% serialization speed with large graphs. Thanks Levente!!!!!! - Merged 9 primitive clusters in 1 -> FLHookPrimitiveCluster. - Rename DefaultMapper -> GeneralMapper - Some optimization with #to:do: - Removing streamFactory from both FLSerializer and FLMaterializer. They were not necessary and implementation simplifies a lot in this way. - Reification of Encoder and Decoder: they delegate in just a few basic methods of a stream, making easy to port. It means Fuel just needs 2 methods for the write stream and 3 from read stream. - Mappers directly map objects. - FuelShouldIgnoreFuel. - Added more and more benchmarks samples and test cases. Test coverage is about 90%. - No direct access anymore to streams. Everything pass from Encoder and Decoder '. spec package: 'Fuel' with: 'Fuel-MarianoMartinezPeck.615'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.214'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.105'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MarianoMartinezPeck.39'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MarianoMartinezPeck.6'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MarianoMartinezPeck.2'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MarianoMartinezPeck.1'; package: 'FuelCompatibilityForSqueak' with: 'FuelCompatibilityForSqueak-MMP.4'; package: 'FuelPackageLoader' with: 'FuelPackageLoader-MartinDias.52'; package: 'FuelPackageLoaderTests' with: 'FuelPackageLoaderTests-MarianoMartinezPeck.7'; package: 'FuelExamples' with: 'FuelExamples-MarianoMartinezPeck.8'; package: 'FuelContainer' with: 'FuelContainer-MartinDias.3'; package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MarianoMartinezPeck.6'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-mariano.3'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MarianoMartinezPeck.1'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.7'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MarianoMartinezPeck.3'; package: 'FuelLogo' with: 'FuelLogo-MartinDias.2'; package: 'FuelCompression' with: 'FuelCompression-MarianoMartinezPeck.7'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.28'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MarianoMartinezPeck.15'; package: 'FuelPresentations' with: 'FuelPresentations-MartinDias.6'; package: 'FuelFileSystem' with: 'FuelFileSystem-MarianoMartinezPeck.3'; package: 'FuelFileSystemTests' with: 'FuelFileSystemTests-MarianoMartinezPeck.1'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.7'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MaxLeske 5/18/2013 11:21'! version191: spec spec for: #common do: [ spec blessing: #release. spec description: ' - (fix) the graph that is serialized is exactly the one found during traversal of the graph. This allows for graphs that inlclude short delays - (enhancement) #fuelReplacement can be overridden to replace an object or class with another. This method should be quicker than using #visitSubstitution:by:'. spec package: 'Fuel' with: 'Fuel-MaxLeske.766'; package: 'FuelTests' with: 'FuelTests-MaxLeske.315'; package: 'FuelMetalevel' with: 'FuelMetalevel-MartinDias.71'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MartinDias.59'; package: 'FuelDebug' with: 'FuelDebug-MartinDias.12'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.10'; package: 'FuelUtilities' with: 'FuelUtilities-MartinDias.1'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.59'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MaxLeske.149'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MaxLeske.12'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MaxLeske.4'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MartinDias.3'; package: 'FuelCompatibilityBeforePharo20' with: 'FuelCompatibilityBeforePharo20-MaxLeske.18'; package: 'FuelCompatibilityBeforePharo21' with: 'FuelCompatibilityBeforePharo21-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo12' with: 'FuelTestsCompatibilityBeforePharo12-MaxLeske.3'; package: 'FuelTestsCompatibilityBeforePharo20' with: 'FuelTestsCompatibilityBeforePharo20-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo21' with: 'FuelTestsCompatibilityBeforePharo21-MaxLeske.5'; package: 'FuelCompatibilityBeforeSqueak42' with: 'FuelCompatibilityBeforeSqueak42-MaxLeske.2'; package: 'FuelCompatibilityBeforeSqueak44' with: 'FuelCompatibilityBeforeSqueak44-MaxLeske.4'; package: 'FuelCompatibilityBeforeSqueak45' with: 'FuelCompatibilityBeforeSqueak45-MaxLeske.7'; package: 'FuelTestsCompatibilityBeforeSqueak42' with: 'FuelTestsCompatibilityBeforeSqueak42-MaxLeske.4'; package: 'FuelTestsCompatibilityBeforeSqueak43' with: 'FuelTestsCompatibilityBeforeSqueak43-MaxLeske.1'; package: 'FuelTestsCompatibilityBeforeSqueak44' with: 'FuelTestsCompatibilityBeforeSqueak44-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforeSqueak45' with: 'FuelTestsCompatibilityBeforeSqueak45-MartinDias.8'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8.3'; project: 'Roassal' with: '1.61'. spec package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.7'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-MartinDias.4'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MartinDias.2'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.12'; package: 'FuelBenchmarksSRP' with: 'FuelBenchmarksSRP-MartinDias.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MartinDias.4'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec package: 'FuelCommandLineHandler' with: 'FuelCommandLineHandler-EstebanLorenzano.21'; package: 'FuelSystem-FileRegistry' with: 'FuelSystem-FileRegistry-EstebanLorenzano.3'; package: 'FuelTools-Debugger' with: 'FuelTools-Debugger-EstebanLorenzano.2' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 3/14/2013 15:52'! version19: spec spec for: #common do: [ spec blessing: #release. spec description: ' - (feature) Put back FLSerializer>>on: - (optimization) added clusters for SmallInteger - (fix) Date & DateAndTime (thanks Cami and Marcus) - (optmization) Optimized clusters for most common collections - (feature) Built-in support for header: - pre and post materialization actions (clean closures) - attach additional objects - materialize only the header - (fix) Substitutions are more safe - (feature) Support Drag&Drop of .fuel files - (feature) DoIt and not-installed CompiledMethods are serialized by default - (feature) New hooks #fuelNew and #fuelNew: that can be overriden for custom instantiation - (feature) Globals: - Added #globalEnvironment: to specify where the globals are looked-up - A SystemDictionary instance is treated as globals only when it is "Smalltalk globals" - Explicit references to "Smalltalk globals" changed to "self class environment" - (cleanup) Removed an unneeded cluster (FLWellKnownObjectsCluster)'. spec package: 'Fuel' with: 'Fuel-EstebanLorenzano.762'; package: 'FuelTests' with: 'FuelTests-MaxLeske.311'; package: 'FuelMetalevel' with: 'FuelMetalevel-MartinDias.71'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MartinDias.59'; package: 'FuelDebug' with: 'FuelDebug-MartinDias.12'; package: 'FuelPreview' with: 'FuelPreview-MartinDias.10'; package: 'FuelUtilities' with: 'FuelUtilities-MartinDias.1'; package: 'FuelProgressUpdate' with: 'FuelProgressUpdate-MartinDias.59'; package: 'FuelBenchmarks' with: 'FuelBenchmarks-MartinDias.148'; package: 'FuelCompatibilityBeforePharo12' with: 'FuelCompatibilityBeforePharo12-MaxLeske.10'; package: 'FuelCompatibilityBeforePharo13' with: 'FuelCompatibilityBeforePharo13-MaxLeske.4'; package: 'FuelCompatibilityBeforePharo14' with: 'FuelCompatibilityBeforePharo14-MartinDias.3'; package: 'FuelCompatibilityBeforePharo20' with: 'FuelCompatibilityBeforePharo20-MaxLeske.18'; package: 'FuelCompatibilityBeforePharo21' with: 'FuelCompatibilityBeforePharo21-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo12' with: 'FuelTestsCompatibilityBeforePharo12-MaxLeske.1'; package: 'FuelTestsCompatibilityBeforePharo20' with: 'FuelTestsCompatibilityBeforePharo20-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforePharo21' with: 'FuelTestsCompatibilityBeforePharo21-MaxLeske.5'; package: 'FuelCompatibilityBeforeSqueak42' with: 'FuelCompatibilityBeforeSqueak42-MaxLeske.2'; package: 'FuelCompatibilityBeforeSqueak44' with: 'FuelCompatibilityBeforeSqueak44-MaxLeske.4'; package: 'FuelCompatibilityBeforeSqueak45' with: 'FuelCompatibilityBeforeSqueak45-MaxLeske.7'; package: 'FuelTestsCompatibilityBeforeSqueak42' with: 'FuelTestsCompatibilityBeforeSqueak42-MaxLeske.4'; package: 'FuelTestsCompatibilityBeforeSqueak43' with: 'FuelTestsCompatibilityBeforeSqueak43-MaxLeske.1'; package: 'FuelTestsCompatibilityBeforeSqueak44' with: 'FuelTestsCompatibilityBeforeSqueak44-MaxLeske.5'; package: 'FuelTestsCompatibilityBeforeSqueak45' with: 'FuelTestsCompatibilityBeforeSqueak45-MartinDias.8'. spec project: 'MagmaBase' with: '1.0'; project: 'SIXX' with: '0.3.6'; project: 'StOMP' with: '1.8.3'; project: 'Roassal' with: '1.61'. spec package: 'FuelBenchmarksMagma' with: 'FuelBenchmarksMagma-MartinDias.7'; package: 'FuelBenchmarksSIXX' with: 'FuelBenchmarksSIXX-MartinDias.4'; package: 'FuelBenchmarksStomp' with: 'FuelBenchmarksStomp-MartinDias.2'; package: 'FuelProgressUpdateBenchmarks' with: 'FuelProgressUpdateBenchmarks-MartinDias.12'; package: 'FuelBenchmarksSRP' with: 'FuelBenchmarksSRP-MartinDias.4'; package: 'FuelBenchmarksEsAndEm' with: 'FuelBenchmarksEsAndEm-MartinDias.4'; package: 'SRP' with: 'SRP-MartinDias.12'; package: 'EsAndEm' with: 'EsAndEm-cwp.15'. spec package: 'FuelCommandLineHandler' with: 'FuelCommandLineHandler-EstebanLorenzano.21'; package: 'FuelSystem-FileRegistry' with: 'FuelSystem-FileRegistry-EstebanLorenzano.3'; package: 'FuelTools-Debugger' with: 'FuelTools-Debugger-EstebanLorenzano.2' ].! ! !ConfigurationOfFuel methodsFor: 'versions' stamp: 'MartinDias 3/25/2013 18:21'! version19AlphaForTanker: spec spec for: #pharo do: [ spec blessing: #beta. spec description: ' just a fixed version for Tanker'. spec package: 'Fuel' with: 'Fuel-MarianoMartinezPeck.718'; package: 'FuelTests' with: 'FuelTests-MarianoMartinezPeck.286'; package: 'FuelMetalevel' with: 'FuelMetalevel-MarianoMartinezPeck.60'; package: 'FuelMetalevelTests' with: 'FuelMetalevelTests-MarianoMartinezPeck.46'. ].! ! "ConfigurationOfFuel"! !FLVariablesMapping commentStamp: 'MartinDias 8/1/2011 03:01' prior: 21695682! I am used to materialize instance variables in an object, tolerating "class shape changing". Cases tolerated are: - instance variable added - instance variable order change - instance variable removed ! !FLIteratingCluster commentStamp: '' prior: 21557788! I am a template class whose algorithm for serialize a collection of objects consists on delegate the serialization of each individual object to the subclass.! !FLVariableObjectCluster commentStamp: 'MartinDias 5/30/2011 01:25' prior: 21693434! I am a generic cluster for objects with indexable variables.! !FLOptimizedObjectCluster methodsFor: 'serialize/materialize' stamp: 'MaxLeske 5/3/2013 09:32' prior: 21623392! serializeReferencesOf: anObject with: anEncoder (self references at: anObject ifAbsent: [ ^ self ]) do: [ :value | anEncoder encodeReferenceTo: value ]! ! !FLAnalysis methodsFor: 'mapping' stamp: 'MaxLeske 5/3/2013 15:35' prior: 21417006! mapAndTrace: anObject "Map an object to its cluster. Trace its references." firstMapper mapAndTrace: anObject fuelReplacement! ! !FLVariablesMapping commentStamp: 'MartinDias 8/1/2011 03:01' prior: 34002930! I am used to materialize instance variables in an object, tolerating "class shape changing". Cases tolerated are: - instance variable added - instance variable order change - instance variable removed ! !FLVariablesMapping class methodsFor: 'instance creation' stamp: 'MaxLeske 5/3/2013 17:03' prior: 21698777! materializing: aClass from: aDecoder ^ self basicNew initializeWithClass: aClass; initializeMaterializingFrom: aDecoder; yourself.! ! !FLVariablesMapping class methodsFor: 'instance creation' stamp: 'MaxLeske 5/3/2013 17:42'! newAnalyzing: anAnalysis references: aCollection ^ self basicNew initializeWithClass: anAnalysis references: aCollection; initializeAnalyzing; yourself! ! !FLVariablesMapping methodsFor: 'initialize-release' stamp: 'MaxLeske 5/3/2013 17:03'! initializeWithClass: aClass self initialize. theClass := aClass! ! !FLVariablesMapping methodsFor: 'initialize-release' stamp: 'MaxLeske 5/3/2013 17:42'! initializeWithClass: aClass references: aCollection self initialize. theClass := aClass. references := aCollection! ! !FLVariablesMapping methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 17:41'! references ^ references! ! !FLVariablesMapping methodsFor: 'serialize/materialize' stamp: 'MaxLeske 5/3/2013 17:41' prior: 21697914! serializeReferencesOf: anObject with: anEncoder (self references at: anObject ifAbsent: [ ^ self ]) do: [ :value | anEncoder encodeReferenceTo: value ].! ! !Object methodsFor: '*Fuel' stamp: 'MaxLeske 5/3/2013 15:18'! fuelReplacement ^ self! ! !FLDictionaryCollectionCluster methodsFor: 'serialize/materialize' stamp: 'MaxLeske 5/3/2013 09:54' prior: 21489623! serializeReferencesOf: anObject with: anEncoder | refs | refs := self references at: anObject ifAbsent: [ ^ self ]. anEncoder encodePositiveInteger: refs first. refs allButFirst do: [ :value | anEncoder encodeReferenceTo: value ] ! ! !FLIteratingCluster commentStamp: '' prior: 34003200! I am a template class whose algorithm for serialize a collection of objects consists on delegate the serialization of each individual object to the subclass.! !FLIteratingCluster methodsFor: 'analyzing' stamp: 'MaxLeske 5/4/2013 09:46' prior: 21558136! add: anObject traceWith: aAnalysis "Add an object to the cluster and trace references." objects addIfNotPresent: anObject ifPresentDo: [ ^ self ]. self referencesOf: anObject do: [ :aChild || actual | actual := aChild fuelReplacement. self addReferenceFrom: anObject to: actual. aAnalysis trace: actual ]! ! !FLIteratingCluster methodsFor: 'analyzing' stamp: 'MaxLeske 5/3/2013 15:22'! addReferenceFrom: anObject to: anotherObject | list | list := self references at: anObject ifAbsent: [ nil ]. list ifNil: [ self references at: anObject put: (list := OrderedCollection new) ]. list add: anotherObject! ! !FLIteratingCluster methodsFor: 'analyzing' stamp: 'MaxLeske 5/3/2013 10:48'! addReferencesFrom: anObject to: aCollection aCollection do: [ :ref | self addReferenceFrom: anObject to: ref ]! ! !FLIteratingCluster methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 08:36'! references ^ references ifNil: [ references := FLLargeIdentityDictionary new ]! ! !FLSimpleCollectionCluster methodsFor: 'serialize/materialize' stamp: 'MaxLeske 5/3/2013 09:49' prior: 21664204! serializeReferencesOf: anObject with: anEncoder | refs | refs := self references at: anObject ifAbsent: [ ^ self ]. anEncoder encodePositiveInteger: refs first. refs allButFirst do: [ :each | anEncoder encodeReferenceTo: each ] ! ! !FLSerialization methodsFor: 'private' stamp: 'MaxLeske 5/3/2013 09:27' prior: 21643807! analysisStep | anAnalysis | anAnalysis := analyzer analysisFor: root. clusters := anAnalysis clusterization clusters. encoder objectCount: anAnalysis clusterization objectCount ! ! !FLSerialization methodsFor: 'initialize-release' stamp: 'MaxLeske 5/3/2013 17:39' prior: 21643323! initializeWith: anEncoder root: anObject analyzer: anAnalyzer self initialize. encoder := anEncoder. root := anObject fuelReplacement. analyzer := anAnalyzer.! ! !FLPointerObjectCluster methodsFor: 'initialize-release' stamp: 'MaxLeske 5/3/2013 17:43' prior: 21633975! initializeAnalyzing: aClass super initializeAnalyzing: aClass. variablesMapping := FLVariablesMapping newAnalyzing: theClass references: self references! ! !FLVariableObjectCluster commentStamp: 'MartinDias 5/30/2011 01:25' prior: 34003444! I am a generic cluster for objects with indexable variables.! !FLVariableObjectCluster methodsFor: 'analyzing' stamp: 'MaxLeske 5/4/2013 11:05'! add: anObject traceWith: aAnalysis "Add an object to the cluster and trace references." objects addIfNotPresent: anObject ifPresentDo: [ ^ self ]. self referencesOf: anObject do: [ :aChild || actual | actual := aChild fuelReplacement. self addReferenceFrom: anObject to: actual. aAnalysis trace: actual ]. self variablePartReferencesOf: anObject do: [ :aChild || actual | actual := aChild fuelReplacement. self addVariableReferenceFrom: anObject to: actual. aAnalysis trace: actual ]! ! !FLVariableObjectCluster methodsFor: 'analyzing' stamp: 'MaxLeske 5/4/2013 10:35'! addVariableReferenceFrom: anObject to: anotherObject | list | list := self variableReferences at: anObject ifAbsent: [ nil ]. list ifNil: [ self variableReferences at: anObject put: (list := OrderedCollection new) ]. list add: anotherObject! ! !FLVariableObjectCluster methodsFor: 'serialize/materialize' stamp: 'MaxLeske 5/4/2013 10:24' prior: 21695271! serializeReferencesVariablePartOf: anObject with: anEncoder (self variableReferences at: anObject ifAbsent: [ ^ self ]) do: [ :value | anEncoder encodeReferenceTo: value ]! ! !FLVariableObjectCluster methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 17:31'! variableReferences ^ variableReferences ifNil: [ variableReferences := FLLargeIdentityDictionary new ]! ! FLPointCluster removeSelector: #serializeReferencesOf:with:! FLVariablesMapping removeSelector: #initializeWith:! FLVariablesMapping class removeSelector: #newAnalyzing:! FLVariableObjectCluster removeSelector: #referencesOf:do:! FLRectangleCluster removeSelector: #serializeReferencesOf:with:! "Fuel"! !FLReplacementClassMock class methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 16:28'! fuelReplacement ^ nil! ! !FLReplacementMock methodsFor: 'comparing' stamp: 'MaxLeske 5/3/2013 11:26'! = anObject ^ self class = anObject class! ! !FLReplacementMock methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 17:34'! dontIgnoreMe ignoreMe := false! ! !FLReplacementMock methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 17:34'! fuelReplacement ^ ignoreMe ifTrue: [ nil ] ifFalse: [ self ]! ! !FLReplacementMock methodsFor: 'accessing' stamp: 'MaxLeske 5/3/2013 17:34'! ignoreMe ^ ignoreMe := true! ! !FLSerializationTest methodsFor: 'running' stamp: 'MaxLeske 2/27/2013 21:49' prior: 21652444! tearDown super tearDown. "Traits should be cleaned before classFactory because it seems class factory only knwos how to clean classes, not traits." self tearDownTraits. self tearDownClassFactory. self tearDownGlobalVariables. self tearDownInstanceVariables! ! !FLSerializationTest methodsFor: 'running' stamp: 'MaxLeske 2/27/2013 21:49'! tearDownInstanceVariables self class withAllSuperclasses do: [ :class | class = TestCase ifTrue: [ ^ self ]. class instVarNames do: [ :varName | self instVarNamed: varName put: nil ] ]! ! !FLDelayedSerializationMock methodsFor: 'serializing' stamp: 'MaxLeske 5/2/2013 09:15'! run "Serialize the graph starting at the root object." self analysisStep. self headerStep. self instancesStep. (Delay forMilliseconds: 100) wait. self referencesStep. self trailerStep.! ! !FLDelayedSerializerMock methodsFor: 'protected' stamp: 'MaxLeske 5/4/2013 16:17'! setDefaultSerialization ^ serializationFactory := [:anObject :anEncoder | (FLDelayedSerializationMock with: anEncoder root: anObject analyzer: self analyzer) run; yourself ]! ! !FLBasicSerializationTest methodsFor: 'tests-graph-modification' stamp: 'MaxLeske 5/3/2013 17:38'! testFuelReplacement | object | self assert: (self resultOfSerializeAndMaterialize: FLReplacementClassMock) equals: nil. self assert: (self resultOfSerializeAndMaterialize: {FLReplacementClassMock}) equals: { nil }. object := FLReplacementMock new ignoreMe; yourself. self assert: (self resultOfSerializeAndMaterialize: {object}) equals: { nil }. object dontIgnoreMe. self assert: (self resultOfSerializeAndMaterialize: {object}) equals: { object }! ! !FLProcessSerializationTest methodsFor: 'running' stamp: 'MaxLeske 5/4/2013 16:17'! setUpSerializer ^ serializer := FLDelayedSerializerMock newDefault! ! !FLProcessSerializationTest methodsFor: 'tests' stamp: 'MaxLeske 5/2/2013 09:20'! testSerializingShortDelay | process | process := [ 2 timesRepeat: [ | d | d := Delay forMilliseconds: 50. d wait ] ] forkAt: Processor userBackgroundPriority. self shouldnt: [ self serialize: process ] raise: FLObjectNotFound! ! "FuelTests"! !RPackageOrganizerTest commentStamp: 'StephaneDucasse 4/24/2011 17:10' prior: 32024500! RPackageOrganizerTest tests the behavior of PackageOrganizer. Note that it does not rely on announcement to be emitted to maintain invariants. Therefore the new created PackageOrganizer is not registered to listen to event. ! !RPackageOrganizer methodsFor: 'private registration' stamp: 'SeanDeNigris 6/11/2013 10:02' prior: 32014069! checkPackageExistsOrRegister: packageName (self packages anySatisfy: [ :each | self category: packageName matches: each packageName ]) ifFalse: [ (RPackage named: packageName capitalized) register ] ! ! !Delay class methodsFor: 'snapshotting' stamp: 'CamilloBruni 6/23/2013 14:14' prior: 20640288! startUp "Restart active delay, if any, when resuming a snapshot." "Compare to false since it can be nil" (DelaySuspended = false) ifTrue:[^self error: 'Trying to activate Delay twice']. self startTimerEventLoop. DelaySuspended := false. self restoreResumptionTimes. AccessProtect signal. ! ! !RPackageOrganizerTest commentStamp: 'StephaneDucasse 4/24/2011 17:10' prior: 34013305! RPackageOrganizerTest tests the behavior of PackageOrganizer. Note that it does not rely on announcement to be emitted to maintain invariants. Therefore the new created PackageOrganizer is not registered to listen to event. ! !RPackageOrganizerTest methodsFor: 'tests' stamp: 'SeanDeNigris 6/11/2013 10:32'! testTestingPackageExistence | extensionCategory package existingPackage | existingPackage := (RPackage named: 'RPackage-Tests') register; yourself. extensionCategory := existingPackage name, '-subcategory'. package := RPackage named: extensionCategory. packageOrganizer := package organizer. self deny: (packageOrganizer includesPackageNamed: extensionCategory). packageOrganizer checkPackageExistsOrRegister: extensionCategory. self deny: (packageOrganizer includesPackageNamed: extensionCategory).! ! "Kernel"! "RPackage-Core"! "RPackage-Tests"! ConfigurationOfFuel removeSelector: #version19AlphaForTanker:! ConfigurationOfFuel removeSelector: #version19:! ConfigurationOfFuel removeSelector: #version191:! ConfigurationOfFuel removeSelector: #version18beta1:! ConfigurationOfFuel removeSelector: #version18ForMarea:! ConfigurationOfFuel removeSelector: #version18:! ConfigurationOfFuel removeSelector: #version182:! ConfigurationOfFuel removeSelector: #version181:! ConfigurationOfFuel removeSelector: #version17:! ConfigurationOfFuel removeSelector: #version16:! ConfigurationOfFuel removeSelector: #version161:! ConfigurationOfFuel removeSelector: #version15:! ConfigurationOfFuel removeSelector: #version14:! ConfigurationOfFuel removeSelector: #version13:! ConfigurationOfFuel removeSelector: #version12:! ConfigurationOfFuel removeSelector: #version11:! ConfigurationOfFuel removeSelector: #version10:! ConfigurationOfFuel removeSelector: #stable:! ConfigurationOfFuel removeSelector: #project! ConfigurationOfFuel removeSelector: #preLoadInPharo11! ConfigurationOfFuel removeSelector: #development:! ConfigurationOfFuel removeSelector: #baseline19AlphaForTanker:! ConfigurationOfFuel removeSelector: #baseline19:! ConfigurationOfFuel removeSelector: #baseline18:! ConfigurationOfFuel removeSelector: #baseline182:! ConfigurationOfFuel removeSelector: #baseline181:! ConfigurationOfFuel removeSelector: #baseline17:! ConfigurationOfFuel removeSelector: #baseline16:! ConfigurationOfFuel removeSelector: #baseline15:! ConfigurationOfFuel removeSelector: #baseline12:! ConfigurationOfFuel removeSelector: #baseline11:! ConfigurationOfFuel removeSelector: #baseline10:! ConfigurationOfFuel class removeSelector: #validate! ConfigurationOfFuel class removeSelector: #testsCategoriesForHudson! ConfigurationOfFuel class removeSelector: #project! ConfigurationOfFuel class removeSelector: #newSqueakPlatformAttributesSource! ConfigurationOfFuel class removeSelector: #loadInHudson! ConfigurationOfFuel class removeSelector: #loadDevelopment! ConfigurationOfFuel class removeSelector: #loadBleedingEdge! ConfigurationOfFuel class removeSelector: #load! ConfigurationOfFuel class removeSelector: #isMetacelloConfig! ConfigurationOfFuel class removeSelector: #fixSqueakPlatformAttributes! ConfigurationOfFuel class removeSelector: #ensureMetacelloForPharo11x! ConfigurationOfFuel class removeSelector: #ensureMetacelloBaseConfiguration! ConfigurationOfFuel class removeSelector: #ensureMetacello! ConfigurationOfFuel class removeSelector: #baseConfigurationClassIfAbsent:! ConfigurationOfFuel class removeSelector: #addSqueakHacks! ConfigurationOfFuel class removeSelector: #addEnvironment! ConfigurationOfFuel class removeSelector: #addClassDescriptionTrait! ConfigurationOfFuel class removeSelector: #DevelopmentSupport! Smalltalk globals removeClassNamed: #ConfigurationOfFuel! ----End fileIn----! ----QUIT----an Array(25 June 2013 11:31:18 am) Pharo.image priorSource: 340039! ----STARTUP----an Array(25 June 2013 11:31:21 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(25 June 2013 11:31:21 am) Pharo-20608.image priorSource: 463685! ----STARTUP----an Array(1 July 2013 2:10:23 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/1/2013 14:07' prior: 33894794! commentForCurrentUpdate ^ '10931 Backport 2.0: Filing out extension package in Nautilus produces empty file https://pharo.fogbugz.com/f/cases/10931 10946 HistoryCollection package is empty https://pharo.fogbugz.com/f/cases/10946'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/1/2013 14:08'! script582 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HistoryCollection-MarcusDenker.16.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1348.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.779.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/1/2013 14:08'! update20609 "self new update20609" self withUpdateLog: '10931 Backport 2.0: Filing out extension package in Nautilus produces empty file https://pharo.fogbugz.com/f/cases/10931 10946 HistoryCollection package is empty https://pharo.fogbugz.com/f/cases/10946'. self loadTogether: self script582 merge: false. ScriptLoader new unloadPackageNamed: 'HistoryCollection'. . self flushCaches. ! ! "ScriptLoader20"! !TClassAndTraitDescription methodsFor: 'filein/out' stamp: 'SeanDeNigris 6/13/2013 10:30' prior: 51846812! fileOutMethod: selector "Write source code of a single method on a file. Make up a name for the file." | internalStream | internalStream := (String new: 1000) writeStream. self fileOutMethod: selector on: internalStream. FileStream writeSourceCodeFrom: internalStream baseName: (self name , '-' , (selector copyReplaceAll: ':' with: '')) isSt: true.! ! !TClassAndTraitDescription methodsFor: 'filein/out' stamp: 'SeanDeNigris 6/13/2013 10:29'! fileOutMethod: selector on: aStream (selector == #Comment) ifTrue: [^ self inform: 'Sorry, cannot file out class comment in isolation.']. (self includesSelector: selector) ifFalse: [^ self error: 'Selector ', selector asString, ' not found']. aStream header; timeStamp. self printMethodChunk: selector withPreamble: true on: aStream moveSource: false toFile: 0.! ! !RPackage methodsFor: '*Nautilus' stamp: 'SeanDeNigris 6/13/2013 10:39' prior: 31775416! fileOut | internalStream | internalStream := (String new: 1000) writeStream. SystemOrganization fileOutCategory: self name on: internalStream. classExtensionSelectors keysAndValuesDo: [ :className :selectors | selectors do: [ :selector | | extendedClass | extendedClass := Smalltalk globals classNamed: className. extendedClass fileOutMethod: selector on: internalStream ] ]. ^ FileStream writeSourceCodeFrom: internalStream baseName: self name isSt: true.! ! !Trait method! fileOutMethod: selector "Write source code of a single method on a file. Make up a name for the file." | internalStream | internalStream := (String new: 1000) writeStream. self fileOutMethod: selector on: internalStream. FileStream writeSourceCodeFrom: internalStream baseName: (self name , '-' , (selector copyReplaceAll: ':' with: '')) isSt: true.! ! !Trait method! fileOutMethod: selector on: aStream (selector == #Comment) ifTrue: [^ self inform: 'Sorry, cannot file out class comment in isolation.']. (self includesSelector: selector) ifFalse: [^ self error: 'Selector ', selector asString, ' not found']. aStream header; timeStamp. self printMethodChunk: selector withPreamble: true on: aStream moveSource: false toFile: 0.! ! !Trait method! fileOutMethod: selector on: aStream (selector == #Comment) ifTrue: [^ self inform: 'Sorry, cannot file out class comment in isolation.']. (self includesSelector: selector) ifFalse: [^ self error: 'Selector ', selector asString, ' not found']. aStream header; timeStamp. self printMethodChunk: selector withPreamble: true on: aStream moveSource: false toFile: 0.! ! "Nautilus"! "Traits"! ----End fileIn----! ----QUIT----an Array(1 July 2013 2:10:28 pm) Pharo.image priorSource: 463903! ----STARTUP----an Array(1 July 2013 2:10:30 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(1 July 2013 2:10:30 pm) Pharo-20609.image priorSource: 476820! ----STARTUP----an Array(1 July 2013 5:31:27 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(1 July 2013 5:31:28 pm) Pharo.image priorSource: 477034! ----STARTUP----an Array(1 July 2013 5:31:30 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(1 July 2013 5:31:30 pm) Pharo-20609.image priorSource: 477258! ----STARTUP----an Array(1 July 2013 6:59:26 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(1 July 2013 6:59:26 pm) Pharo.image priorSource: 477472! ----STARTUP----an Array(1 July 2013 6:59:28 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(1 July 2013 6:59:28 pm) Pharo-20609.image priorSource: 477696! ----STARTUP----an Array(3 July 2013 2:31:06 pm) as /Users/denker/Desktop/20609/Pharo-20609.image! (Process allInstances reject: [ :p | {(InputEventFetcher default fetcherProcess). (Processor activeProcess). (WeakArray runningFinalizationProcess). (Processor backgroundProcess). (SmalltalkImage current lowSpaceWatcherProcess). (UIManager default uiProcess). (Delay schedulingProcess)} includes: p ]) do: [ :p | p suspend; terminate ] ! ----QUIT----an Array(3 July 2013 2:32:03 pm) Pharo-20609.image priorSource: 477910! ----STARTUP----an Array(3 July 2013 2:40:26 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/3/2013 14:38' prior: 34018651! commentForCurrentUpdate ^ '11101 fileOutMethod:on: uncategorized in 2.0 https://pharo.fogbugz.com/f/cases/11101'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/3/2013 14:38'! script583 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.122.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1348.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.779.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.46.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/3/2013 14:38'! update20610 "self new update20610" self withUpdateLog: '11101 fileOutMethod:on: uncategorized in 2.0 https://pharo.fogbugz.com/f/cases/11101'. self loadTogether: self script583 merge: false. (ClassDescription >> #fileOutMethod:on:) protocol: 'filein/out'. . self flushCaches. ! ! "ScriptLoader20"! ----End fileIn----! ----QUIT----an Array(3 July 2013 2:40:28 pm) Pharo.image priorSource: 478653! ----STARTUP----an Array(3 July 2013 2:40:30 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(3 July 2013 2:40:30 pm) Pharo-20610.image priorSource: 488621! ----STARTUP----an Array(9 July 2013 12:29:23 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/9/2013 12:26' prior: 34033395! commentForCurrentUpdate ^ '10978 Backport 20: ZipArchive utf8 handling https://pharo.fogbugz.com/f/cases/10978 11125 backport 2.0: 10859 Monticello freezing the image https://pharo.fogbugz.com/f/cases/11125 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/9/2013 12:26'! script584 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.191.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-EstebanLorenzano.1348.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.781.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/9/2013 12:27'! update20611 "self new update20611" self withUpdateLog: '10978 Backport 20: ZipArchive utf8 handling https://pharo.fogbugz.com/f/cases/10978 11125 backport 2.0: 10859 Monticello freezing the image https://pharo.fogbugz.com/f/cases/11125 '. self loadTogether: self script584 merge: false. self flushCaches. ! ! "ScriptLoader20"! !ZipArchiveMember methodsFor: 'accessing' stamp: 'ThierryGoubier 6/20/2013 15:23' prior: 55127408! contentStream "Answer my contents as a text stream. Default is no conversion, since we don't know what the bytes mean." ^self contentStreamFromEncoding: 'latin1' ! ! !ZipArchiveMember methodsFor: 'accessing' stamp: 'ThierryGoubier 6/20/2013 15:17'! contentStreamFromEncoding: encodingName "Answer my contents as a text stream. Interpret the raw bytes with given encodingName" | s | s := MultiByteBinaryOrTextStream on: (String new: self uncompressedSize). s converter: (TextConverter newForEncoding: encodingName). self extractTo: s. s reset. ^ s! ! !MCSmalltalkhubRepository methodsFor: 'interface' stamp: 'CamilloBruni 6/15/2013 10:14' prior: 24993181! loadAllFileNames | client | client := self httpClient. client ifFail: [ :exception | self error: 'Could not access ', self location, ': ', exception printString ]; url: self locationWithTrailingSlash; queryAt: 'format' put: 'raw'; get. self assertNonBinaryResponse: client response. ^ self parseFileNamesFromStream: client contents! ! !UTF8TextConverter methodsFor: 'conversion' stamp: 'ThierryGoubier 6/20/2013 15:16' prior: 54435869! errorMalformedInput ^ UTF8Error new signal: 'Invalid utf8 input detected'! ! !MCHttpRepository methodsFor: 'i/o' stamp: 'CamilloBruni 6/15/2013 10:13' prior: 24805703! loadAllFileNames | client | self displayProgress: 'Loading all file names from ', self description during: [ client := self httpClient. client ifFail: [ :exception | (exception className beginsWith: 'Zn') ifTrue: [ MCRepositoryError signal: 'Could not access ', self location, ': ', exception printString ] ifFalse: [ exception pass ] ]; url: self locationWithTrailingSlash; queryAt: 'C' put: 'M;O=D'; "legacy that some servers maybe expect" get. self assertNonBinaryResponse: client response ]. ^ self parseFileNamesFromStream: client contents readStream! ! "Compression"! "Monticello"! "Multilingual-TextConversion"! ----End fileIn----! ----QUIT----an Array(9 July 2013 12:29:29 pm) Pharo.image priorSource: 488835! ----STARTUP----an Array(9 July 2013 12:29:31 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(9 July 2013 12:29:31 pm) Pharo-20611.image priorSource: 500989! ----STARTUP----an Array(10 July 2013 10:37:29 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/10/2013 10:34' prior: 34043582! commentForCurrentUpdate ^ '10569 Backport 2.0: Better Interrruptionche https://pharo.fogbugz.com/f/cases/10569 10940 Backport 2.0: 10925 Use caching in Gofer https://pharo.fogbugz.com/f/cases/10940 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/10/2013 10:34'! script585 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1059.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/10/2013 10:35'! update20612 "self new update20612" self withUpdateLog: '10569 Backport 2.0: Better Interrruptionche https://pharo.fogbugz.com/f/cases/10569 10940 Backport 2.0: 10925 Use caching in Gofer https://pharo.fogbugz.com/f/cases/10940 '. self loadTogether: self script585 merge: false. UserInterruptHandler allInstances first setInterruptKeyValue: $. asciiValue. self flushCaches. ! ! "ScriptLoader20"! !Gofer methodsFor: 'private' stamp: 'ThierryGoubier 6/24/2013 07:01' prior: 22901123! execute: anOperationClass do: aBlock "Ensure that all repositories have a chance to cache file names during the gofer operation." | operation recursion | recursion := [ :repos | repos notEmpty ifTrue: [ repos first cacheAllFileNamesDuring: [ recursion value: repos allButFirst ] ] ifFalse: [ operation := anOperationClass on: self copy. aBlock isNil ifFalse: [ aBlock value: operation ]. operation execute ] ]. ^ recursion value: repositories! ! !UserInterruptHandler class methodsFor: 'instance creation' stamp: 'ThierryGoubier 6/28/2013 14:57' prior: 54599909! new ^ super new setInterruptKeyValue: $. asciiValue! ! !UserInterruptHandler methodsFor: 'events' stamp: 'ThierryGoubier 6/28/2013 14:49' prior: 54597490! handleEvent: evt "Interrupt event... evt is shared, so make a copy of it." | buf | buf := evt shallowCopy. (self isKbdEvent: evt) ifTrue: [ | keycode modifiers | "Check if the event is a user interrupt" keycode := buf sixth. modifiers := buf fifth. (keycode = interruptKey and: [ modifiers anyMask: 16r0E ]) ifTrue: [ Display deferUpdates: false. (Smalltalk hasClassNamed: #SoundService) ifTrue: [ (Smalltalk classNamed: #SoundService) default shutDown ]. self handleUserInterrupt ]. ^ self ]! ! !UserInterruptHandler methodsFor: 'events' stamp: 'ThierryGoubier 6/28/2013 14:41'! isKbdEvent: bufEvt ^ bufEvt first = EventTypeKeyboard and: [ bufEvt fourth = EventKeyChar ]! ! !UserInterruptHandler methodsFor: 'private' stamp: 'ThierryGoubier 6/28/2013 14:05' prior: 54598812! processToInterrupt "Look for best candidate to interrupt: - any scheduled non-finalization process of lower priority - the weak-finalization process, if scheduled - the UI process Never interrupt the idle process, since killing it is fatal" | fallback | fallback := UIManager default uiProcess. Processor scanSchedule: [ :p | "suspendedContext sender == nil usually means that process is only scheduled but had no chance to run" (p ~~ Processor backgroundProcess and: [ p suspendedContext sender notNil ]) ifTrue: [ p ~~ WeakArray runningFinalizationProcess ifTrue: [ ^ p ] ifFalse: [ fallback := p ] ] ] startingAt: Processor activePriority. ^ fallback! ! !MCRepository methodsFor: 'as yet unclassified' stamp: 'ThierryGoubier 6/24/2013 07:02'! cacheAllFileNamesDuring: aBlock ^ aBlock value! ! "Gofer-Core"! "Kernel"! "Monticello"! ----End fileIn----! ----QUIT----an Array(10 July 2013 10:37:41 am) Pharo.image priorSource: 501205! ----STARTUP----an Array(10 July 2013 10:37:45 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(10 July 2013 10:37:45 am) Pharo-20612.image priorSource: 513952! ----STARTUP----an Array(12 July 2013 4:52:47 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/12/2013 16:49' prior: 34055955! commentForCurrentUpdate ^ '11132 Backport to 2.0: Convert MetacelloConfigurationBrowser to Spec https://pharo.fogbugz.com/f/cases/11132'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/12/2013 16:49'! script586 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1062.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/12/2013 16:50'! update20613 "self new update20613" self withUpdateLog: '11132 Backport to 2.0: Convert MetacelloConfigurationBrowser to Spec https://pharo.fogbugz.com/f/cases/11132'. self loadTogether: self script586 merge: false. self flushCaches. ! ! "ScriptLoader20"! !MetacelloConfigurationBrowser commentStamp: 'StephaneDucasse 8/10/2010 21:09' prior: 25809432! A MetacelloConfigurationBrowser is simple tool to browse Metacello configurations published at http://www.squeaksource.com/MetaRepoForPharoXX where XX denotes different pharo versions. MetaRepoForPharo1.0 acts as a distribution of all the packages/projects that can be loaded in Pharo1.0. We are sorry for the name but the source limits the length of the project name: The full name is MetacelloRepositoriesForPharoXX. Metacello is a configuration language for packages. It allows one to define dependencies between packages as well as between complete projects. ! !ThemeIcons class methodsFor: '*Tools-ConfigurationBrowser' stamp: 'tbn 6/19/2013 22:30'! configIcon ^ icons at: #'configIcon' ifAbsentPut:[ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self configIconContents readStream) ].! ! !ThemeIcons class methodsFor: '*Tools-ConfigurationBrowser' stamp: 'tbn 6/19/2013 22:30'! configIconContents "Private - Method generated" ^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0 RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALnSURBVDjLfZNLaFx1HIW/e2fu zJ00w0ymkpQpiUKfMT7SblzU4kayELEptRChUEFEqKALUaRUV2YhlCLYjYq4FBeuiqZgC6FI QzBpEGpDkzHNs5PMTJtmHnfu6//7uSh2IYNnffg23zmWqtIpd395YwiRL1Q0qyIfD56cmOvU s/4LWJg40auiH6jI+7v3ncybdo2Hy9ebKvqNGrn03Nj1+x0Bi1dHHVV9W0U+ye4d2d83+Ca2 GJrlGZx0gkppkkfrsysqclFFvh8++3v7CWDh6ugIohfSPcPH+w6fwu05ABoSby9yb3Kc/meP YXc9TdCqslWapVGdn1Zjxo++O33Fujtx4gdEzj61f8xyC8/jN2rsVOcxYZOoVSZtBewZOAT+ NonuAWw3S728wFZpFm975cekGjlz8NXLVtSo0SxPImGdtFfFq5epr21wdOxrnMwuaC2jrRJW fYHdxRfIFeDWr0unkyrSUqxcyk2TLQzQrt6hqydPvidDBg/8VTAp8DegvYa3OU1z+SbuM6dQ I62kioAAVgondwAnncWvzCDNCk4CLO9vsJVw8xqN+iPiTB5SaTSKURGSaoTHHgxoAMlduL1H iFMZXP8BsvkbO1GD2O3GpLOIF0KsSBijxmCrMY+FqgGJQDzQgGT3XrJ7DuI5EKZd4iDG+CHG 84m8AIki1Ai2imRsx4FEBtQHCUB8MG1wi8QKGhjEC4mbAVHTx8kNYSuoiGurkRtLN76ivb0K 6SIkusCEoBEgaCQYPyT2QhKpAXKHTiMmQ2lmChWZTrw32v9TsLOyVlu8Nhi2G4Vs32HsTC9I A2KPRuU2Erp097+O5RRYvz3H1r3JldivfY7IR0+mfOu7l3pV5EM1cq744mi+OPwaRD71tSk0 Vsp3/uLB6s2minyrIpeOf7a00fFMf1w+MqRGzqvIW/teecdqV5a5P/8ncXv9ZxUdf/lCae5/ 3/hvpi4OjajIp4ikVOTLY+cXr3Tq/QPcssKNXib9yAAAAABJRU5ErkJggg=='! ! !ThemeIcons class methodsFor: '*Tools-ConfigurationBrowser' stamp: 'tbn 6/19/2013 22:31'! configIconLoaded ^ icons at: #'configIconLoaded' ifAbsentPut:[ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self configIconLoadedContents readStream) ].! ! !ThemeIcons class methodsFor: '*Tools-ConfigurationBrowser' stamp: 'tbn 6/19/2013 22:33'! configIconLoadedContents "Private - Method generated" ^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0 RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAM9SURBVDjLdZPrS1NhHMcPREH/ QC96nxURWS+iktC8bEt3skHoi95EbYk5KStqdtPGLKcuczSELnYhK0bzhpfK5nSZed1MPZtz zpq3pnN5tOY2p+fbsxMEUj3wgx9fvr8Pz+X7UACof9VwPb1juC6l2l6T/N5WJdr9P99fgqPx yCYyrLLXpczPMg/xrbcQzOukH0P6xJLBl/Gb/wsYaUpdT4Zlw/Vi55RVi5XgNLilCSy6qhGY rIO79Tw+P4/92v/soNz6JGbjGoCjKVXgaDhi/tpxA4Hvn4m0BHAswr4ejBiOImAvRsitx6JN B2fdSVge7e/su7+X5gFk+LGjgeZ8jkr4vQPwjbVgrIsYP6hhe3MOrreZ8Nvvwm/NQ9D5CMsT esx1q8C8kKBHt+dF5LLCXNCNkLcPvgEtvL0qTJnOwlmbhs57MVieswB+BzD7FtwXHcBcBiYr ER5VoUu7K0yRy2JXg+PAjyEsT9ZgwXoL/v48UgpM1op5DTONgPsBOJsCfmMcZhoOYoG5i87S nSxlqznMri4RwM8RAmEArxEBRg1/VyZm6sUIj2iA0RKE2kWYa9wHj0kET3Mq2P4SfNLsYCnG IGRXeIAdWCTbne8kkHcIO7VYaEtDyCwCa4zB3EchZoxJmG6Ix3StEN+7C9FRtI2lyPv+BpAj gO1CYOoNmqu10JQUoqKiAkUFl2AlRxltFKJIdZHXim/no+aBAibV1gVq8FV8iAt/Iy/nwrK3 BRW66ygrK4PH44HL5UJbWxvuqHOhU8vhGGZ4rb29nfcoTx9YoQYq45pHjZexNGVC67uXuHpF AcvgIArz5aBpMWQyGbRaLXJzc/meFouRf/4ED7l08VyYIsnaQJIlI+FwKi8cw60CFQ8IjldC JEyA0WiExWKB2WyGwWCAICEOLcot7ghAqVQG/kSZJGtTzvHopuwzUi4CuHnjApISEyEQCCCR SPiK9Anxh1bTjh1tjQAyMjLm13yM7WRJUsVjpRp16PWrp6iqqkJ5eTlycnKgUCj4PqLp9Xqf RqOZp2navgYQFRW1LjY2Njo5OfmLTHoqkC3PXM2Wn+GuZQhK09PTE7KyshZJBaRS6c+IJ+L9 BchY24ysm0a5AAAAAElFTkSuQmCC' ! ! !MetacelloConfigurationBrowser commentStamp: 'StephaneDucasse 8/10/2010 21:09' prior: 34078632! A MetacelloConfigurationBrowser is simple tool to browse Metacello configurations published at http://www.squeaksource.com/MetaRepoForPharoXX where XX denotes different pharo versions. MetaRepoForPharo1.0 acts as a distribution of all the packages/projects that can be loaded in Pharo1.0. We are sorry for the name but the source limits the length of the project name: The full name is MetacelloRepositoriesForPharoXX. Metacello is a configuration language for packages. It allows one to define dependencies between packages as well as between complete projects. ! !MetacelloConfigurationBrowser class methodsFor: 'specs' stamp: 'TorstenBergmann 7/3/2013 21:00'! defaultSpec | delta | delta := 25. ^ SpecLayout composed add: #configBrowserModel origin: 0@0 corner: 1@1 offsetOrigin: 0@0 offsetCorner: 0@(delta negated); add: #toolbarModel origin: 0@1 corner: 1@1 offsetOrigin: 0@(delta negated) offsetCorner: 0@0; "add: #textModel origin: 0@0.5 corner: 1@1 offsetOrigin: 0@delta offsetCorner: 0@0;" yourself! ! !MetacelloConfigurationBrowser class methodsFor: 'menu' stamp: 'TorstenBergmann 7/4/2013 09:48' prior: 25815506! menuCommandOn: aBuilder (aBuilder item: 'Configuration Browser') parent: #Tools; order: 0.5; action: [self new openWithSpec]; icon: ThemeIcons smallLoadProjectIcon! ! !MetacelloConfigurationBrowser class methodsFor: 'interface opening' stamp: 'TorstenBergmann 7/4/2013 09:49' prior: 25815355! open ^self new openWithSpec! ! !MetacelloConfigurationBrowser class methodsFor: 'accessing' stamp: 'tbn 6/20/2013 08:13'! title ^'Configuration browser'! ! !MetacelloConfigurationBrowser methodsFor: 'accessing' stamp: 'TorstenBergmann 7/3/2013 20:59'! configBrowserModel ^ configBrowserModel! ! !MetacelloConfigurationBrowser methodsFor: 'initialize-release' stamp: 'tbn 6/19/2013 21:47'! initialExtent ^ (400 min: (World extent x)) @ (350 min: (World extent y))! ! !MetacelloConfigurationBrowser methodsFor: 'initialize-release' stamp: 'TorstenBergmann 7/4/2013 08:44'! initializeWidgets self instantiateModels: #( configBrowserModel #MetacelloConfigurationBrowserPane toolbarModel #MetacelloConfigurationBrowserToolbar). ! ! !MetacelloConfigurationBrowser methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 21:28'! installConfiguration configBrowserModel installConfiguration! ! !MetacelloConfigurationBrowser methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 21:29'! loadConfiguration configBrowserModel loadConfiguration! ! !MetacelloConfigurationBrowser methodsFor: 'icons' stamp: 'tbn 6/19/2013 21:43'! taskbarIcon ^ ThemeIcons smallLoadProjectIcon! ! !MetacelloConfigurationBrowser methodsFor: 'accessing' stamp: 'tbn 6/20/2013 08:13'! title ^self class title! ! !MetacelloConfigurationBrowser methodsFor: 'accessing' stamp: 'tbn 6/20/2013 08:14'! toolbarModel ^ toolbarModel! ! !MetacelloConfigurationBrowserPane class methodsFor: 'spec' stamp: 'BenjaminVanRyseghem 5/14/2013 18:07'! defaultSpec ^ SpecLayout composed add: #configurationList; yourself! ! !MetacelloConfigurationBrowserPane class methodsFor: 'example' stamp: 'tbn 2/18/2013 21:33'! example " self example " ^self new openWithSpec; repository: self pharoDistribution; yourself! ! !MetacelloConfigurationBrowserPane class methodsFor: 'accessing' stamp: 'TorstenBergmann 7/4/2013 08:46'! pharoDistributionRepository "Returns the correct pharo distribution url" ^'http://ss3.gemtalksystems.com/ss/MetaRepoForPharo', SystemVersion current major asString, SystemVersion current minor asString! ! !MetacelloConfigurationBrowserPane class methodsFor: 'accessing' stamp: 'tbn 2/18/2013 20:42'! retrieveConfigurationsFrom: locationString " self retrieveConfigurationsFrom: self pharoDistribution " | repo reductionMap split configName author version last topMostItems item | repo := MCHttpRepository location: locationString. "Reduce to display only the latest" reductionMap := Dictionary new. (repo allVersionNames reverse select: [ :each | each beginsWith: 'ConfigurationOf' ]) do: [:each | split := each findTokens: '-.'. configName := split first. author := split second. version := Integer readFrom: split last. last := reductionMap at: configName ifAbsentPut: [ author -> version]. version > last value ifTrue: [ reductionMap at: configName put: (author -> version) ] ]. topMostItems := SortedCollection sortBlock: [:e1 :e2 | e1 asString <= e2 asString ]. reductionMap keysAndValuesDo: [:key :val | topMostItems add: (key, '-', val key, '.', val value asString) ]. ^topMostItems! ! !MetacelloConfigurationBrowserPane class methodsFor: 'accessing' stamp: 'tbn 2/18/2013 21:30'! title ^'Configurations'! ! !MetacelloConfigurationBrowserPane methodsFor: 'private accessing' stamp: 'TorstenBergmann 7/4/2013 08:47'! availableRepositories ^Array with: self class pharoDistributionRepository with: 'http://www.squeaksource.com/MetacelloRepository' ! ! !MetacelloConfigurationBrowserPane methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 21:37'! browseConfiguration self hasSelection ifFalse: [ ^self ]. self selectedConfigurationClass browse! ! !MetacelloConfigurationBrowserPane methodsFor: 'private accessing' stamp: 'tbn 6/19/2013 21:29'! configurationList ^configurationList ! ! !MetacelloConfigurationBrowserPane methodsFor: 'private accessing' stamp: 'tbn 2/18/2013 20:20'! configurationList: aList configurationList := aList! ! !MetacelloConfigurationBrowserPane methodsFor: 'menu' stamp: 'TorstenBergmann 7/4/2013 08:24'! configurationListMenu: aMenu aMenu target: self. aMenu title: 'Configuration'. self selectedConfiguration ifNotNil: [ aMenu add: 'Install configuration' action: #installConfiguration. self selectedConfigurationClass isNil ifTrue: [ aMenu add: 'Load configuration' action: #loadConfiguration ] ifFalse: [ aMenu add: 'Browse configuration class' action: #browseConfiguration ]. aMenu addLine ]. aMenu add: 'Switch Repository' action: #switchRepository; add: 'Refresh' action: #updateList. ^aMenu! ! !MetacelloConfigurationBrowserPane methodsFor: 'private testing' stamp: 'TorstenBergmann 7/3/2013 21:36'! hasSelection ^self selectedConfiguration notNil! ! !MetacelloConfigurationBrowserPane methodsFor: 'initialization' stamp: 'tbn 6/19/2013 22:31'! initConfigurationList "Display in format name (author.version)" configurationList displayBlock: [:item | |tokens| tokens := (item findTokens: '-.'). (tokens first allButFirst: 15), ' (',tokens second ,'.', tokens third, ')' ]. "Display loaded with a special icon (assuming the mcz is named like the class" configurationList icons: [:e | (Smalltalk includesKey: (e findTokens: '-.') first asSymbol) ifTrue: [ ThemeIcons configIconLoaded ] ifFalse: [ ThemeIcons configIcon ]]. ! ! !MetacelloConfigurationBrowserPane methodsFor: 'initialization' stamp: 'TorstenBergmann 7/4/2013 08:49'! initializeWidgets self instantiateModels: #(configurationList IconListModel). self focusOrder add: configurationList. configurationList menu: [ :aMenu | self configurationListMenu: aMenu ]. self initConfigurationList. self repository: self availableRepositories first ! ! !MetacelloConfigurationBrowserPane methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 21:28'! installConfiguration self loadConfigurationWithStable: true. self updateList! ! !MetacelloConfigurationBrowserPane methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 21:28'! loadConfiguration self loadConfigurationWithStable: false. self updateList! ! !MetacelloConfigurationBrowserPane methodsFor: 'private' stamp: 'TorstenBergmann 7/3/2013 21:37'! loadConfigurationWithStable: loadStable "Load the configuration and (depending on the flag) load the latest stable version" | configName | self hasSelection ifFalse: [ ^self ]. configName := self selectedConfigurationName. Gofer new url: self repository; package: configName; load. loadStable ifFalse: [^self]. "Now load the latest stable version" self selectedConfigurationClass project stableVersion load.! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/3/2013 20:47'! repository ^repository! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/4/2013 08:49'! repository: aRepositoryUrl repository := aRepositoryUrl. self configurationList items: (self class retrieveConfigurationsFrom: aRepositoryUrl). self window ifNotNil: [:w | w title: aRepositoryUrl ]! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/3/2013 21:31'! selectedConfiguration ^self configurationList selectedItem! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/3/2013 21:38'! selectedConfigurationClass ^Smalltalk at: self selectedConfigurationName asSymbol ifAbsent: [ nil ]! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/3/2013 21:44'! selectedConfigurationName self selectedConfiguration ifNil: [ ^String empty ]. ^self selectedConfiguration readStream upTo: $-.! ! !MetacelloConfigurationBrowserPane methodsFor: 'actions' stamp: 'TorstenBergmann 7/4/2013 08:41'! switchRepository | dialog | dialog := ListDialogWindow new getList: [ :r| self availableRepositories ]; displayBlock: [:e | e ]; title: 'Repository Search'; yourself. dialog browseBlock: [ :el | el ifNotNil: [ NBWin32Shell shellBrowse: el ]]. (dialog openModal) cancelled ifFalse: [ dialog listIndex > 0 ifTrue: [ self repository: (self availableRepositories at: dialog listIndex) ]]! ! !MetacelloConfigurationBrowserPane methodsFor: 'updating' stamp: 'TorstenBergmann 7/3/2013 21:10'! updateList |selected| selected := self configurationList selectedIndex. self configurationList updateList. self configurationList setSelectedIndex: selected.! ! !MetacelloConfigurationBrowserToolbar class methodsFor: 'specs' stamp: 'TorstenBergmann 7/3/2013 20:50'! defaultSpec ^ { #Panel. #changeTableLayout. #listDirection:. #rightToLeft. #addMorph:. {#model. #installModel.}. #addMorph:. {#model. #loadModel.}. #hResizing:. #spaceFill. #vResizing:. #shrinkWrap. }! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'initialization' stamp: 'tbn 6/20/2013 08:25'! initializeWidgets self instantiateModels: #( loadModel ButtonModel installModel ButtonModel). self setLoadModel. self setInstallModel . self focusOrder add: loadModel; add: installModel! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 20:50'! installConfiguration self owner installConfiguration ! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'initialization' stamp: 'tbn 6/20/2013 08:23'! installModel ^installModel ! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'actions' stamp: 'TorstenBergmann 7/3/2013 20:38'! loadConfiguration self owner loadConfiguration ! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'initialization' stamp: 'tbn 6/20/2013 08:23'! loadModel ^loadModel! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'initialization' stamp: 'tbn 6/20/2013 08:22'! setInstallModel installModel state: false; label: 'Install'; action: [ self installConfiguration ]. ! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'initialization' stamp: 'tbn 6/20/2013 08:22'! setLoadModel loadModel state: false; label: 'Load'; action: [ self loadConfiguration ]. ! ! MetacelloConfigurationBrowser removeSelector: #untrustedDistribution! MetacelloConfigurationBrowser removeSelector: #retrieveConfigurationMorphsFrom:! MetacelloConfigurationBrowser removeSelector: #refresh! MetacelloConfigurationBrowser removeSelector: #pharoDistribution! MetacelloConfigurationBrowser removeSelector: #open! MetacelloConfigurationBrowser removeSelector: #onUntrustedSelected:! MetacelloConfigurationBrowser removeSelector: #onTrustedSelected:! MetacelloConfigurationBrowser removeSelector: #loadStableFromSelectedConfiguration! MetacelloConfigurationBrowser removeSelector: #loadSelectedConfiguration! MetacelloConfigurationBrowser removeSelector: #loadConfigurationWithStable:! MetacelloConfigurationBrowser removeSelector: #initializeWindow! MetacelloConfigurationBrowser removeSelector: #initialize! MetacelloConfigurationBrowser removeSelector: #configurationMenu:! MetacelloConfigurationBrowser class removeSelector: #theme! "Tools"! ----End fileIn----! ----QUIT----an Array(12 July 2013 4:52:55 pm) Pharo.image priorSource: 514170! ----STARTUP----an Array(12 July 2013 4:52:57 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(12 July 2013 4:52:58 pm) Pharo-20613.image priorSource: 540767! ----STARTUP----an Array(18 July 2013 2:42:38 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/18/2013 14:39' prior: 34068920! commentForCurrentUpdate ^ '11179 Config browser buttons broken due to missing method https://pharo.fogbugz.com/f/cases/11179'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/18/2013 14:39'! script587 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1064.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/18/2013 14:39'! update20614 "self new update20614" self withUpdateLog: '11179 Config browser buttons broken due to missing method https://pharo.fogbugz.com/f/cases/11179'. self loadTogether: self script587 merge: false. self flushCaches. ! ! "ScriptLoader20"! !MetacelloConfigurationBrowser commentStamp: 'StephaneDucasse 8/10/2010 21:09' prior: 34082556! A MetacelloConfigurationBrowser is simple tool to browse Metacello configurations published at http://www.squeaksource.com/MetaRepoForPharoXX where XX denotes different pharo versions. MetaRepoForPharo1.0 acts as a distribution of all the packages/projects that can be loaded in Pharo1.0. We are sorry for the name but the source limits the length of the project name: The full name is MetacelloRepositoriesForPharoXX. Metacello is a configuration language for packages. It allows one to define dependencies between packages as well as between complete projects. ! !MetacelloConfigurationBrowserToolbar methodsFor: 'actions' stamp: 'TorstenBergmann 7/17/2013 14:17' prior: 34093329! installConfiguration owner installConfiguration ! ! !MetacelloConfigurationBrowserToolbar methodsFor: 'actions' stamp: 'TorstenBergmann 7/17/2013 14:17' prior: 34093618! loadConfiguration owner loadConfiguration ! ! !MetacelloConfigurationBrowser commentStamp: 'StephaneDucasse 8/10/2010 21:09' prior: 34105422! A MetacelloConfigurationBrowser is simple tool to browse Metacello configurations published at http://www.squeaksource.com/MetaRepoForPharoXX where XX denotes different pharo versions. MetaRepoForPharo1.0 acts as a distribution of all the packages/projects that can be loaded in Pharo1.0. We are sorry for the name but the source limits the length of the project name: The full name is MetacelloRepositoriesForPharoXX. Metacello is a configuration language for packages. It allows one to define dependencies between packages as well as between complete projects. ! !MetacelloConfigurationBrowser class methodsFor: 'private accessing' stamp: 'TorstenBergmann 7/17/2013 13:44'! configurationSearchList ^ configurationSearchList ifNil: [ configurationSearchList := OrderedCollection new ].! ! !MetacelloConfigurationBrowser class methodsFor: 'specs' stamp: 'TorstenBergmann 7/17/2013 13:37' prior: 34083225! defaultSpec | delta searchBarOffset | searchBarOffset := 5 + StandardFonts defaultFont height + 10. delta := 25. ^ SpecLayout composed add: #configBrowserModel origin: 0@0 corner: 1@1 offsetOrigin: 0@searchBarOffset offsetCorner: 0@(delta negated); add: #toolbarModel origin: 0@1 corner: 1@1 offsetOrigin: 0@(delta negated) offsetCorner: 0@0; add: #configurationSearchField origin: 0@0 corner: 1@0 offsetOrigin: 0@0 offsetCorner: 0@searchBarOffset; yourself! ! !MetacelloConfigurationBrowser methodsFor: 'accessing' stamp: 'TorstenBergmann 7/17/2013 14:18'! configurationSearchAccept: aString aString isEmptyOrNil ifTrue: [ self configBrowserModel configurationPattern: nil ] ifFalse: [ self configBrowserModel configurationPattern: ([ aString asRegexIgnoringCase ] on: RegexSyntaxError do: [ aString ])]. ! ! !MetacelloConfigurationBrowser methodsFor: 'accessing' stamp: 'TorstenBergmann 7/17/2013 13:45'! configurationSearchField ^ SearchMorph new model: self; setIndexSelector: #configurationSearchAccept:; updateSelector: #configurationSearchAccept:; searchList: self class configurationSearchList; yourself! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/17/2013 14:18'! configurationPattern: aPattern "Sets a filter pattern" configurationPattern := aPattern. self configurationList items: (aPattern isNil ifTrue: [self configurations] ifFalse: [self configurations select: [ :each| configurationPattern search: each ]]). self updateList ! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/17/2013 13:58'! configurations configurations ifNil: [ configurations := self class retrieveConfigurationsFrom: self repository ]. ^configurations! ! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'TorstenBergmann 7/17/2013 13:55' prior: 34090995! repository: aRepositoryUrl repository := aRepositoryUrl. self configurationList items: self configurations. self window ifNotNil: [:w | w title: aRepositoryUrl ]! ! "Tools"! ----End fileIn----! ----QUIT----an Array(18 July 2013 2:42:45 pm) Pharo.image priorSource: 540983! ----STARTUP----an Array(18 July 2013 2:42:47 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(18 July 2013 2:42:47 pm) Pharo-20614.image priorSource: 555034! ----STARTUP----an Array(19 July 2013 8:57:35 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/19/2013 08:55' prior: 34095732! commentForCurrentUpdate ^ '11192 Config browser does not update when switching repos https://pharo.fogbugz.com/f/cases/11192'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/19/2013 08:55'! script588 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-EstebanLorenzano.1372.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1066.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/19/2013 08:55'! update20615 "self new update20615" self withUpdateLog: '11192 Config browser does not update when switching repos https://pharo.fogbugz.com/f/cases/11192'. self loadTogether: self script588 merge: false. self flushCaches. ! ! "ScriptLoader20"! !MetacelloConfigurationBrowserPane methodsFor: 'accessing' stamp: 'tbn 7/18/2013 16:48' prior: 34109264! repository: aRepositoryUrl "clear config cache for new repositories" repository = aRepositoryUrl ifFalse: [ configurations := nil ]. repository := aRepositoryUrl. self configurationList items: self configurations. self window ifNotNil: [:w | w title: aRepositoryUrl ]! ! !MetacelloConfigurationBrowserPane methodsFor: 'actions' stamp: 'tbn 7/18/2013 16:53' prior: 34091904! switchRepository | dialog | dialog := ListDialogWindow new getList: [ :r| self availableRepositories ]; displayBlock: [:e | e ]; title: 'Repository Search'; yourself. dialog browseBlock: [ :el | el ifNotNil: [ "only available onWin until other platforms can open a URL too" OSPlatform isWin32 ifTrue: [ NBWin32Shell shellBrowse: el ] ]]. (dialog openModal) cancelled ifFalse: [ dialog listIndex > 0 ifTrue: [ self repository: (self availableRepositories at: dialog listIndex) ]]! ! "Tools"! ----End fileIn----! ----QUIT----an Array(19 July 2013 8:57:41 am) Pharo.image priorSource: 555250! ----STARTUP----an Array(19 July 2013 8:57:44 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(19 July 2013 8:57:44 am) Pharo-20615.image priorSource: 566194! ----STARTUP----an Array(23 July 2013 1:13:34 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/23/2013 13:11' prior: 34109999! commentForCurrentUpdate ^ '10860 option click on list in TestRunner and others: freeze system https://pharo.fogbugz.com/f/cases/10860'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/23/2013 13:11'! script589 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.213.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1374.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1066.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/23/2013 13:11'! update20616 "self new update20616" self withUpdateLog: '10860 option click on list in TestRunner and others: freeze system https://pharo.fogbugz.com/f/cases/10860'. self loadTogether: self script589 merge: false. self flushCaches. ! ! "ScriptLoader20"! !Morph methodsFor: 'event handling' stamp: 'MarcusDenker 7/22/2013 10:12' prior: 26677625! mouseDown: evt "Handle a mouse down event. The default response is to let my eventHandler, if any, handle it." self eventHandler ifNotNil: [self eventHandler mouseDown: evt fromMorph: self] ! ! "Morphic"! ----End fileIn----! ----QUIT----an Array(23 July 2013 1:13:45 pm) Pharo.image priorSource: 566410! ----STARTUP----an Array(23 July 2013 1:13:47 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(23 July 2013 1:13:47 pm) Pharo-20616.image priorSource: 576659! ----STARTUP----an Array(31 July 2013 10:33:30 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'MarcusDenker 7/31/2013 10:31' prior: 34121159! commentForCurrentUpdate ^ '11252 backport 2.0: have SliceMaker use fogbugz https://pharo.fogbugz.com/f/cases/11252'! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'MarcusDenker 7/31/2013 10:31'! script590 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.216.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1374.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1066.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'MarcusDenker 7/31/2013 10:31'! update20617 "self new update20617" self withUpdateLog: '11252 backport 2.0: have SliceMaker use fogbugz https://pharo.fogbugz.com/f/cases/11252'. self loadTogether: self script590 merge: false. self flushCaches. ! ! "ScriptLoader20"! !MCSliceMaker methodsFor: 'actions' stamp: 'ThierryGoubier 7/30/2013 11:17' prior: 24984958! downloadIssueSummary "If the slice number is unknown, or for whatever failure, use a default summary." | title request | title := (request := ZnClient new) url: 'http://bugs.pharo.org/issues/name/' , self issueIdString; get. request isSuccess ifFalse: [ title := '-unable-to-get-summary-' ]. self info issueSummary: title! ! MCSliceMaker removeSelector: #downloadIssueSummaryFailed! "MonticelloGUI"! ----End fileIn----! ----QUIT----an Array(31 July 2013 10:33:33 am) Pharo.image priorSource: 576875! ----STARTUP----an Array(31 July 2013 10:33:36 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(31 July 2013 10:33:36 am) Pharo-20617.image priorSource: 587290! ----STARTUP----an Array(31 July 2013 1:32:31 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 7/31/2013 13:27' prior: 34131625! commentForCurrentUpdate ^ '11280 Integrate ProfStef into 2.0 https://pharo.fogbugz.com/f/cases/11280 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 7/31/2013 13:27'! script591 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-MarcusDenker.29.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-MarcusDenker.782.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.216.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1374.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz ProfStef-Core-EstebanLorenzano.31.mcz ProfStef-Help-EstebanLorenzano.8.mcz ProfStef-Tests-EstebanLorenzano.17.mcz RPackage-Core-EstebanLorenzano.216.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1066.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 7/31/2013 13:28'! update20618 "self new update20618" self withUpdateLog: '11280 Integrate ProfStef into 2.0 https://pharo.fogbugz.com/f/cases/11280 '. self loadTogether: self script591 merge: false. Gofer it squeaksource3: 'MetaRepoForPharo20'; configurationOf: 'ProfStef'; load. (Smalltalk at: #ConfigurationOfProfStef) load. ScriptLoader new unloadPackageNamed: 'ConfigurationOfProfStef'. self flushCaches. ! ! "ScriptLoader20"! !AbstractTutorial commentStamp: 'LaurentLaffont 1/21/2010 16:53' prior: 0! Parent class of all ProfStef tutorials. To create your own tutorial: - subclass AbstractTutorial - implement a few methods which returns a Lesson instance - implement tutorial which returns a Collection of selectors to the methods you've created. For example, see MockTutorial (minimalist) and SmalltalkSyntaxTutorial (default ProfStef one). See ProfStef comment to execute your own tutorial.! !HowToMakeYourOwnTutorial commentStamp: 'LaurentLaffont 2/15/2011 22:20' prior: 0! I'm a ProfStef tutorial which teach to create a ProfStef tutorial. Open me with ProfStef goOn: HowToMakeYourOwnTutorial.! !SmalltalkSyntaxTutorial commentStamp: 'LaurentLaffont 1/21/2010 16:50' prior: 0! The default ProfStef tutorial to learn Smalltalk syntax! !Lesson commentStamp: 'LaurentLaffont 1/15/2010 10:25' prior: 0! See class side messages #welcome, #doingVSPrinting.... ! !LessonView commentStamp: 'LaurentLaffont 1/15/2010 10:24' prior: 0! A LessonView displays a Lesson instance! !ProfStef commentStamp: '' prior: 0! A ProfStef is the Smalltalk teacher. To start the tutorial, evaluate: ProfStef go. To go to the next lesson evaluate: ProfStef next. To execute your own tutorial: ProfStef goOn: MyOwnTutorial To see a table of contents with all defined tutorials: ProfStef contents! !TutorialPlayer commentStamp: 'LaurentLaffont 1/21/2010 20:34' prior: 0! I can navigate through an AbstractTutorial subclass. With #next and #previous you can go forward and backward through the tutorial. ! !ProfStefHelpTutorialBuilder commentStamp: '' prior: 0! I build HelpSystem topics to browse ProfStef tutorials! !ProfStefHelp commentStamp: 'LaurentLaffont 2/15/2011 22:17' prior: 0! HelpSystem book documenting ProfStef! !ProfStefAPIHelp commentStamp: 'LaurentLaffont 2/15/2011 22:18' prior: 0! I'm a ProfStef which build a HelpSystem book by collecting comment from classes and method.! !ProfStefTutorialsHelp commentStamp: 'LaurentLaffont 2/15/2011 22:18' prior: 0! I'm a HelpSystem book which list all ProfStef tutorials! !TTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 21:57'! testEachSelectorExists self testedTutorial tutorial do: [:aSelector| self assert: (self tutorial respondsTo: aSelector) ]! ! !TTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 21:59'! testEachSelectorReturnsALesson | answer | self testedTutorial tutorial do: [:aSelector| answer := (self testedTutorial perform: aSelector). self assert: (answer isKindOf: Lesson). ]! ! !TTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 21:59'! testLessonAtReturnsCorrespondingLesson | answer | 1 to: (self testedTutorial tutorial size) do: [:index| answer := self testedTutorial lessonAt: index. self assert: (answer isKindOf: Lesson) ] ! ! !TTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 22:00'! testNotEmpty self assert: self testedTutorial tutorial notEmpty.! ! !TTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 22:00'! testSizeReturnsNumberOfSelectors self assert: (self testedTutorial tutorial size) equals: self testedTutorial size.! ! !TTutorialTest methodsFor: 'requirements' stamp: 'LaurentLaffont 2/1/2010 22:04'! testedTutorial "Returns an instance of an AbstractTutorial subclass" ^ self explicitRequirement! ! !AbstractTutorial commentStamp: 'LaurentLaffont 1/21/2010 16:53' prior: 34152200! Parent class of all ProfStef tutorials. To create your own tutorial: - subclass AbstractTutorial - implement a few methods which returns a Lesson instance - implement tutorial which returns a Collection of selectors to the methods you've created. For example, see MockTutorial (minimalist) and SmalltalkSyntaxTutorial (default ProfStef one). See ProfStef comment to execute your own tutorial.! !AbstractTutorial class methodsFor: 'tutorial metainfo' stamp: 'LaurentLaffont 1/27/2010 21:02'! title "Return the title of the tutorial by parsing the class name like a Wiki link and interspersing whitespaces between the tokens" | className separators groups | className := self name. separators := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. groups := className findTokens: separators keep: separators. ^' ' join: (groups pairsCollect: [ :sep :rest | sep , rest ]). ! ! !AbstractTutorial class methodsFor: 'tutorial metainfo' stamp: 'LaurentLaffont 11/22/2010 21:36'! tutorials ^ (self subclasses sort: [:a :b | a name < b name]) select: [:aTutorial | (aTutorial category = 'ProfStef-Tests') not ]. ! ! !AbstractTutorial methodsFor: 'tutorial' stamp: 'DannyChan 2/1/2010 21:21'! indexOfLesson: aSelector ^self tutorial indexOf: aSelector.! ! !AbstractTutorial methodsFor: 'tutorial' stamp: 'LaurentLaffont 1/21/2010 13:51'! lessonAt: anInteger | lessonSelector | lessonSelector := self tutorial at: anInteger. ^ self perform: lessonSelector.! ! !AbstractTutorial methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 16:35'! lessons ^ self tutorial collect: [:aSelector| self perform: aSelector]! ! !AbstractTutorial methodsFor: 'printing' stamp: 'LaurentLaffont 2/15/2011 22:47'! printOn: aStream aStream nextPutAll: 'a ProfStef Tutorial ('; nextPutAll: self class title; nextPutAll: ')'. ! ! !AbstractTutorial methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 13:49'! size ^ self tutorial size! ! !AbstractTutorial methodsFor: 'tutorial' stamp: 'LaurentLaffont 1/21/2010 13:44'! tutorial "Should return an Array of selectors which returns Lesson instances. See SmalltalkSyntaxTutorial." ^ self shouldBeImplemented.! ! !HowToMakeYourOwnTutorial commentStamp: 'LaurentLaffont 2/15/2011 22:20' prior: 34152680! I'm a ProfStef tutorial which teach to create a ProfStef tutorial. Open me with ProfStef goOn: HowToMakeYourOwnTutorial.! !HowToMakeYourOwnTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 9/21/2010 20:28'! createLessonFactoryMethods ^ Lesson title: 'Lesson factory methods' lesson: '"Next, create category ''lessons'' and add a method per lesson. Each method must return a Lesson object. Your can use Lesson class>>title:lesson: to create Lesson object." HowToDebug compile: ''useSelfHalt ^ Lesson title: ''''self halt'''' lesson: ''''"Put self halt. in the method you want to debug." ProfStef next.'''''' classified: ''lessons''. HowToDebug compile: ''examineStackTrace ^ Lesson title: ''''self halt'''' lesson: ''''"Look at PharoDebug.log." ProfStef next.'''''' classified: ''lessons''. HowToDebug compile: ''changeReturnValue ^ Lesson title: ''''Change return value'''' lesson: ''''"Easy in the debugger !!"'''''' classified: ''lessons''. ProfStef next.'.! ! !HowToMakeYourOwnTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 22:26'! implementTutorial ^ Lesson title: 'Implement tutorial method' lesson: '"Finally implement the tutorial method to return an Array of your lesson factory methods:" HowToDebug compile: ''tutorial ^ #( #useSelfHalt #examineStackTrace #changeReturnValue )'' classified: ''tutorial''. ProfStef next.'.! ! !HowToMakeYourOwnTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 22:29'! runYourTutorial ^ Lesson title: 'Run your tutorial' lesson: '"You can run your fresh new tutorial like this:" ProfStef goOn: HowToDebug.'.! ! !HowToMakeYourOwnTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 21:55'! subclassAbstractTutorial ^ Lesson title: 'AbstractTutorial' lesson: '"Here are the steps to create your own ProfStef tutorial. First, create a subclass of AbstractTutorial. For example:" AbstractTutorial subclass: #HowToDebug instanceVariableNames: '''' classVariableNames: '''' poolDictionaries: '''' category: ''ProfStef''. ProfStef next.'! ! !HowToMakeYourOwnTutorial methodsFor: 'tutorial' stamp: 'LaurentLaffont 1/21/2010 21:45'! tutorial ^ #( subclassAbstractTutorial createLessonFactoryMethods implementTutorial runYourTutorial )! ! !MockTutorial methodsFor: 'lesson' stamp: 'LaurentLaffont 1/21/2010 15:15'! firstLesson ^ Lesson title: 'first' lesson: 'First lesson'.! ! !MockTutorial methodsFor: 'lesson' stamp: 'LaurentLaffont 1/21/2010 15:15'! secondLesson ^ Lesson title: 'second' lesson: 'Second lesson'.! ! !MockTutorial methodsFor: 'lesson' stamp: 'LaurentLaffont 1/21/2010 15:15'! thirdLesson ^ Lesson title: 'third' lesson: 'Third lesson'.! ! !MockTutorial methodsFor: 'tutorial' stamp: 'LaurentLaffont 1/21/2010 15:14'! tutorial ^ #( firstLesson secondLesson thirdLesson )! ! !SmalltalkSyntaxTutorial commentStamp: 'LaurentLaffont 1/21/2010 16:50' prior: 34152885! The default ProfStef tutorial to learn Smalltalk syntax! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:31'! basicTypesArray ^ Lesson title: 'Basic types: Array' lesson: '"Literal arrays are created at parse time:" #(1 2 3). #( 1 2 3 #(4 5 6)) size. #(1 2 4) isEmpty. #(1 2 3) first. #(''hello'' ''Squeak'') at: 2 put: ''Pharo''; yourself. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:31'! basicTypesCharacters ^ Lesson title: 'Basic types: Characters' lesson: '"A Character can be instantiated using $ operator:" $A. $A class. $B charCode. Character cr. Character space. "You can print all 256 characters of the ASCII extended set:" Character allByteCharacters. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:31'! basicTypesDynamicArray ^ Lesson title: 'Basic types: Dynamic Array' lesson: '"Dynamic Arrays are created at execution time:" { (2+3) . (6*6) }. { (2+3) . (6*6) . ''hello'', '' Stef''} size. { ProfStef } first next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 12/13/2010 21:06'! basicTypesNumbers ^ Lesson title: 'Basic types: Numbers' lesson: '"You now know how to execute Smalltalk code. Now let''s talk about basic objects. 1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions. Evaluate these ones:" 2. 20 factorial. 1000 factorial / 999 factorial. (1/3). (1/3) + (4/5). (1/3) asFloat. 1 class. 1 class maxVal class. (1 class maxVal + 1) class. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/27/2010 21:33'! basicTypesString ^ Lesson title: 'Basic types: Strings' lesson: '"A String is a collection of characters. Use single quotes to create a String object. Print these expressions:" ''ProfStef''. ''ProfStef'' size. ''abc'' asUppercase. ''Hello World'' reverse. "You can access each character using at: message" ''ProfStef'' at: 1. "String concatenation uses the comma operator:" ''ProfStef'', '' is cool''. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:32'! basicTypesSymbol ^ Lesson title: 'Basic types: Symbols' lesson: '"A Symbol is a String which is guaranteed to be globally unique. There is one and only one Symbol #ProfStef. There may be several ''ProfStef'' String objects. (Message == returns true if the two objects are the SAME)" ''ProfStef'' asSymbol. #ProfStef asString. (2 asString) == (2 asString). (2 asString) asSymbol == (2 asString) asSymbol. (Smalltalk at: #ProfStef) next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:33'! blocks ^ Lesson title: 'Blocks' lesson: '"Cascade is cool !! Let''s talk about blocks. Blocks are anonymous methods that can be stored into variables and executed on demand. Blocks are delimited by square brackets: []" [Browser open]. "does not open a Browser because the block is not executed. Here is a block that adds 2 to its argument (its argument is named x):" [:x | x+2]. "We can execute a block by sending it value messages." [:x | x+2] value: 5. [Browser open] value. [:x | x+2] value: 10. [:x :y| x + y] value:3 value:5. [ProfStef next] value.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:33'! blocksAssignation ^ Lesson title: 'Block assignation' lesson: '"Blocks can be assigned to a variable then executed later. Note that |b| is the declaration of a variable named ''b'' and that '':='' assigns a value to a variable. Select the three lines then Print It:" |b| b := [:x | x+2]. b value: 12. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:33'! conditionals ^ Lesson title: 'Conditionals' lesson: '"Conditionals are just messages sent to Boolean objects" 1 < 2 ifTrue: [100] ifFalse: [42]. "Here the message is ifTrue:ifFalse Try this:" Transcript open. 3 > 10 ifTrue: [Transcript show: ''maybe there''''s a bug ....''] ifFalse: [Transcript show: ''No : 3 is less than 10'']. 3 = 3 ifTrue: [ProfStef next].'.! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 12/12/2010 18:30'! debugger ^ Lesson title: 'Debugger' lesson: '"The Debugger may be the most famous tool of Smalltalk environments. It will open as soon as an unmanaged Exception occurs. The following code will open the debugger on the message stack, select SmalltalkSyntaxTutorial>>divideTwoByZero". SmalltalkSyntaxTutorial new divideTwoByZero. '! ! !SmalltalkSyntaxTutorial methodsFor: 'interactive' stamp: 'EstebanLorenzano 7/31/2013 11:09'! divideTwoByZero 2/0. "Oups!! 2/0 raises a ZeroDivide exception. So the debugger opens to let you fix the code. - Remove the line of code above. - Right-click and select 'Accept' to compile the new version of the method - click the button 'Proceed' to continue execution. ". ProfStef next. ! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 16:42'! doingVSPrinting ^ Lesson title: 'Doing VS Printing: Doing' lesson: '"Cool !! (I like to say Cooool :) ). You''ve just executed a Smalltalk expression. More precisely, you sent the message ''next'' to ProfStef class (it''s me !!). Note you can run this tutorial again by evaluating: ''ProfStef go''. ''ProfStef previous'' returns to the previous lesson. You can also Do It using the keyboard shortcut ''ALT d'' (this varies according to your operating system/computer: it can be ''CMD d'' or ''CTRL d''). Try to evaluate these expressions:" Browser open. SmalltalkImage current aboutThisSystem. "Then go to the next lesson:" ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'initialize-release' stamp: 'LaurentLaffont 12/12/2010 17:18'! initialize super initialize. self prepareDebuggerExample.! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 2/15/2011 22:22'! instanciation ^ Lesson title: 'Instanciation' lesson: '"Objects are instances of their class. Usually, we send the message #new to a class for creating an instance of this class. The message #allInstances sent to a class answers an Array with all instances of this class. For example, let''s look at how many instances of SimpleButtonMorph exist:" SimpleButtonMorph allInstances size. "Now create a new instance of it:" SimpleButtonMorph new label: ''A nice button''; openCenteredInWorld. "See the button centered on the world ? The list of all instances should contains one more instance:" SimpleButtonMorph allInstances size. "Let''s play with it:" SimpleButtonMorph allInstances last label: ''ProfStef is cooooool !!''; color: Color cyan. "Let''s delete it and ask the system to clean the memory:" SimpleButtonMorph allInstances last delete. Smalltalk garbageCollect. SimpleButtonMorph allInstances size. "Click on the button to go to next lesson:" SimpleButtonMorph new label: ''Go to next lesson''; target: [ProfStef next. SimpleButtonMorph allInstances last delete]; actionSelector: #value; openCenteredInWorld.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:34'! iterators ^ Lesson title: 'Iterators' lesson: '"The message do: is sent to a collection of objects (Array, Set, OrderedCollection), evaluating the block for each element. Here we want to print all the numbers on the Transcript (a console)" #(11 38 3 -2 10) do: [:each | Transcript show: each printString; cr]. "Some other really nice iterators" #(11 38 3 -2 10) collect: [:each | each abs]. #(11 38 3 -2 10) collect: [:each | each odd]. #(11 38 3 -2 10) select: [:each | each odd]. #(11 38 3 -2 10) select: [:each | each > 10]. #(11 38 3 -2 10) reject: [:each | each > 10]. #(11 38 3 -2 10) do: [:each | Transcript show: each printString] separatedBy: [Transcript show: ''.'']. ProfStef allInstances do: [:aProfStef | aProfStef next].'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:34'! loops ^ Lesson title: 'Loops' lesson: '"Loops are high-level collection iterators, implemented as regular methods." "Basic loops: to:do: to:by:do" 1 to: 100 do: [:i | Transcript show: i asString; cr ]. 1 to: 100 by: 3 do: [:i | Transcript show: i asString; cr]. 100 to: 0 by: -2 do: [:i | Transcript show: i asString; cr]. 1 to: 1 do: [:i | ProfStef next].'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:34'! mathematicalPrecedence ^ Lesson title: 'Mathematical precedence' lesson: '"Traditional precedence rules from mathematics do not follow in Smalltalk." 2 * 10 + 2. "Here the message * is sent to 2, which answers 20, then 20 receive the message + Remember that all messages always follow a simple left-to-right precedence rule, * without exceptions *." 2 + 2 * 10. 2 + (2 * 10). 8 - 5 / 2. (8 - 5) / 2. 8 - (5 / 2). ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/27/2010 21:27'! messageSyntaxBinary ^ Lesson title: 'Message syntax: Binary messages' lesson: '"Binary messages have the following form: anObject + anotherObject" 3 * 2. Date today + 3 weeks. false | false. true & true. true & false. 10 @ 100. 10 <= 12. ''ab'', ''cd''. Date today < Date yesterday. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:35'! messageSyntaxCascade ^ Lesson title: 'Message syntax: Cascade' lesson: '"; is the cascade operator. It''s useful to send message to the SAME receiver Open a Transcript (console):" Transcript open. "Then:" Transcript show: ''hello''. Transcript show: ''Smalltalk''. Transcript cr. "is equivalent to:" Transcript show: ''hello''; show: ''Smalltalk'' ; cr. "Try to go to the next lesson with a cascade of two ''next'' messages:" ProfStef'.! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:35'! messageSyntaxCascadeShouldNotBeHere ^ Lesson title: 'Lost ?' lesson: '"Hey, you should not be here !!!! Go back and use a cascade !!" ProfStef previous.'.! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 12/13/2010 21:09'! messageSyntaxExecutionOrder ^ Lesson title: 'Message syntax: Execution order' lesson: '"Unary messages are executed first, then binary messages and finally keyword messages: Unary > Binary > Keywords" 2 + 3 squared. 2 raisedTo: 3 + 2. (0@0) class. 0@0 corner: 100@200. (0@0 corner: 100@200) class. "Between messages of similar precedence, expressions are executed from left to right" -3 abs negated reciprocal. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:35'! messageSyntaxExecutionOrderParentheses ^ Lesson title: 'Message syntax: Parentheses' lesson: '"Use parentheses to change order of evaluation" (2 + 3) squared. (2 raisedTo: 3) + 2. (0@0 extent: 100@200) bottomRight. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:35'! messageSyntaxKeyword ^ Lesson title: 'Message syntax: Keyword messages' lesson: '"Keyword Messages are messages with arguments. They have the following form: anObject akey: anotherObject akey2: anotherObject2" 4 between: 0 and: 10. "The message is between:and: sent to the Number 4" 1 max: 3. Color r:1 g:0 b:0. "The message is r:g:b: implemented on class Color. Note you can also write" Color r:1 g:1 b:0. ProfStef perform: #next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/27/2010 21:40'! messageSyntaxUnary ^ Lesson title: 'Message syntax: Unary messages' lesson: '"Messages are sent to objects. There are three types of message: Unary, Binary and Keyword. Unary messages have the following form: anObject aMessage You''ve already sent unary messages. For example:" 1 class. false not. Time now. Date today. Float pi. "And of course: " ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/27/2010 21:41'! pharoEnvironment ^ Lesson title: 'Pharo environment' lesson: '"Every Smalltalk system is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages. Every object understands the message ''explore''. As a result, you get an Explorer window that shows details about the object." Date today explore. "This shows that the date object consists of a point in time (start) and a duration (one day long)." ProfStef explore. "You see, ProfStef class has a lot of objects. Let''s take a look at my code:" ProfStef browse. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'interactive' stamp: 'LaurentLaffont 12/12/2010 17:16'! prepareDebuggerExample self class compile: 'divideTwoByZero 2/0. "Oups!! 2/0 raises a ZeroDivide exception. So the debugger opens to let you fix the code. - Remove the line of code above. - Right-click and select ''Accept'' to compile the new version of the method - click the button ''Proceed'' to continue execution. ". ProfStef next. ' classified: 'interactive'.! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:36'! printing ^ Lesson title: 'Doing VS Printing: Printing' lesson: '"Now you''re a Do It master !! Let''s talk about printing. It''s a Do It which prints the result next to the expression you''ve selected. For example, select the text below, open the menu and click on ''print it (p)'':" 1 + 2. "You''ve seen the letter ''p'' between parentheses next to ''print it'' ? It indicates the ALT- shortcut to execute this command. Try ALT-p on the following expressions:" Date today. Time now. "The result is selected, so you can erase it using the backspace key. Try it !!" SmalltalkImage current datedVersion. ProfStef next.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 12/13/2010 21:57'! reflection ^ Lesson title: 'Reflection' lesson: '"You can inspect and change the system at runtime. Take a look at method #ifFalse:ifTrue: source code of class True:" (True>>#ifFalse:ifTrue:) definition. "Or just its comment:" (True>>#ifFalse:ifTrue:) comment. "Here''s all the methods I implement:" ProfStef selectors. "Let''s create a new method to go to the next lesson:" ProfStef class compile:''goToNextLesson self next''. "Wow !! I can''t wait to use my new method !! " ProfStef goToNextLesson.'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 12/13/2010 22:06'! reflectionContinued ^ Lesson title: 'Reflection continued' lesson: '"So cool, isn''t it ? Before going further, let''s remove this method:" ProfStef respondsTo: #goToNextLesson. ProfStef class removeSelector: #goToNextLesson. ProfStef respondsTo: #goToNextLesson. "Then move forward:" ProfStef default executeMethod: (ProfStef lookupSelector:#next).'! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/27/2010 21:09'! theEnd ^ Lesson title: 'Tutorial done !!' lesson: '"This tutorial is done. Enjoy programming Smalltalk with Pharo. Don''t forget to read ''Pharo By Example'' found here: http://pharo-project.org/PharoByExample. You can run this tutorial again by evaluating: ProfStef go. Do you want to create your own interactive tutorial with ProfStef ? That''s very easy!!!! How ? There''s a ProfStef interactive tutorial for that :D Just evaluate the following code: ProfStef goOn: HowToMakeYourOwnTutorial See you soon !!" '! ! !SmalltalkSyntaxTutorial methodsFor: 'tutorial' stamp: 'LaurentLaffont 2/6/2011 19:05'! tutorial ^ #( welcome doingVSPrinting printing basicTypesNumbers basicTypesCharacters basicTypesString basicTypesSymbol basicTypesArray basicTypesDynamicArray messageSyntaxUnary messageSyntaxBinary messageSyntaxKeyword messageSyntaxExecutionOrder messageSyntaxExecutionOrderParentheses mathematicalPrecedence messageSyntaxCascade messageSyntaxCascadeShouldNotBeHere blocks blocksAssignation conditionals loops iterators instanciation reflection reflectionContinued pharoEnvironment debugger theEnd )! ! !SmalltalkSyntaxTutorial methodsFor: 'lessons' stamp: 'LaurentLaffont 1/21/2010 13:36'! welcome ^ Lesson title: 'Welcome' lesson: '"Hello!! I''m Professor Stef. You must want me to help you learn Smalltalk. So let''s go to the first lesson. Select the text below, right-click and choose ''do it (d)''" ProfStef next.'! ! !Lesson commentStamp: 'LaurentLaffont 1/15/2010 10:25' prior: 34153007! See class side messages #welcome, #doingVSPrinting.... ! !Lesson class methodsFor: 'instance creation' stamp: 'LaurentLaffont 1/15/2010 09:27'! title: aStringForTitle lesson: aStringForLesson ^ self new title: aStringForTitle; lesson: aStringForLesson; yourself.! ! !Lesson methodsFor: 'accessing' stamp: 'LaurentLaffont 1/15/2010 09:25'! lesson ^ lesson ifNil: [lesson := '']! ! !Lesson methodsFor: 'accessing' stamp: 'LaurentLaffont 1/15/2010 09:25'! lesson: aString lesson := aString! ! !Lesson methodsFor: 'printing' stamp: 'LaurentLaffont 2/15/2011 22:46'! printOn: aStream super printOn: aStream. aStream nextPutAll: '('; nextPutAll: self title; nextPutAll: ')'. ! ! !Lesson methodsFor: 'accessing' stamp: 'LaurentLaffont 1/15/2010 09:25'! title ^ title ifNil: [title := '']! ! !Lesson methodsFor: 'accessing' stamp: 'LaurentLaffont 1/15/2010 09:25'! title: aString title := aString! ! !LessonView commentStamp: 'LaurentLaffont 1/15/2010 10:24' prior: 34153133! A LessonView displays a Lesson instance! !LessonView methodsFor: 'gui' stamp: 'LaurentLaffont 1/21/2010 21:01'! close self window delete.! ! !LessonView methodsFor: 'gui' stamp: 'LaurentLaffont 1/27/2010 21:21'! menu ^ MenuMorph fromArray: { {'do it (d)' translated. #doIt}. {'print it (p)' translated. #printIt}}.! ! !LessonView methodsFor: 'gui' stamp: 'AlainPlantec 8/28/2011 13:54'! open shoutMorph := PluggableTextMorph on: self text: nil accept: nil readSelection: nil menu: #shoutMorphFillMenu:. shoutMorph setText: ''. window := SystemWindow labelled: 'PrStef lesson'. window addMorph: shoutMorph frame: (0@0 corner: 1@1). window openInWorld.! ! !LessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 2/26/2012 14:13'! shoutAboutToStyle: aPluggableShoutMorphOrView ^ true! ! !LessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:58'! shoutMorph ^ shoutMorph ifNil: [self open. shoutMorph]! ! !LessonView methodsFor: 'gui' stamp: 'LaurentLaffont 1/21/2010 21:00'! shoutMorphFillMenu: aMenu ^ aMenu addAllFrom: self menu! ! !LessonView methodsFor: 'gui' stamp: 'EstebanLorenzano 7/31/2013 11:16'! showLesson: aLesson withTitle: aString self window setLabel: aString. self shoutMorph selectFrom: 0 to: 0; setText: aLesson lesson. (World systemWindows includes: self window) ifFalse: [self window openInWorld] ! ! !LessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 21:06'! text ^ self shoutMorph text asString! ! !LessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 21:02'! window ^ window ifNil: [self open. window]! ! !MockLessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 16:09'! lesson ^ lesson! ! !MockLessonView methodsFor: 'gui' stamp: 'LaurentLaffont 1/21/2010 16:10'! showLesson: aLesson withTitle: aString lesson := aLesson. title := aString.! ! !MockLessonView methodsFor: 'gui' stamp: 'DannyChan 2/1/2010 22:02'! showTutorialNode: aTutorialNode lesson:= aTutorialNode lessonInstance. title := aTutorialNode title.! ! !MockLessonView methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 16:10'! title ^ title! ! !ProfStef commentStamp: '' prior: 34153223! A ProfStef is the Smalltalk teacher. To start the tutorial, evaluate: ProfStef go. To go to the next lesson evaluate: ProfStef next. To execute your own tutorial: ProfStef goOn: MyOwnTutorial To see a table of contents with all defined tutorials: ProfStef contents! !ProfStef class methodsFor: 'class initialization' stamp: 'LaurentLaffont 1/21/2010 17:15'! default ^ instance ifNil: [instance := self new]! ! !ProfStef class methodsFor: 'navigating' stamp: 'DannyChan 2/9/2010 19:30'! first ^ self default first.! ! !ProfStef class methodsFor: 'navigating' stamp: 'LaurentLaffont 9/18/2011 20:01'! go ^ self default go.! ! !ProfStef class methodsFor: 'navigating' stamp: 'LaurentLaffont 9/18/2011 20:01'! goOn: aTutorialClass ^ self default goOn: aTutorialClass.! ! !ProfStef class methodsFor: 'navigating' stamp: 'DannyChan 2/9/2010 19:30'! last ^ self default last.! ! !ProfStef class methodsFor: 'navigating' stamp: 'tg 2/1/2010 16:01'! next ^ self default next.! ! !ProfStef class methodsFor: 'navigating' stamp: 'tg 2/1/2010 16:01'! previous ^ self default previous.! ! !ProfStef class methodsFor: 'class initialization' stamp: 'LaurentLaffont 9/18/2011 20:13'! reset instance := nil! ! !ProfStef class methodsFor: 'starting' stamp: 'DannyChan 2/1/2010 19:23'! tutorial: aTutorialClass lesson: aSelector self default tutorial: aTutorialClass lesson: aSelector.! ! !ProfStef class methodsFor: 'starting' stamp: 'DannyChan 2/1/2010 19:23'! tutorial: aTutorialClass lessonAt: lessonIndex self default tutorial: aTutorialClass lessonAt: lessonIndex.! ! !ProfStef methodsFor: 'gui' stamp: 'LaurentLaffont 1/21/2010 21:05'! close self lessonView close! ! !ProfStef methodsFor: 'navigating' stamp: 'DannyChan 2/9/2010 19:28'! first self player first. ^ self showCurrentLesson.! ! !ProfStef methodsFor: 'starting' stamp: 'tg 2/1/2010 16:02'! go ^ self goOn: SmalltalkSyntaxTutorial.! ! !ProfStef methodsFor: 'starting' stamp: 'tg 2/1/2010 16:02'! goOn: aTutorialClass self player tutorial: aTutorialClass new. ^ self open.! ! !ProfStef methodsFor: 'navigating' stamp: 'DannyChan 2/9/2010 19:28'! last self player last. ^ self showCurrentLesson.! ! !ProfStef methodsFor: 'accessing' stamp: 'DannyChan 2/2/2010 19:39'! lessonView ^ lessonView ifNil: [lessonView := LessonView new]! ! !ProfStef methodsFor: 'accessing' stamp: 'DannyChan 2/2/2010 19:16'! lessonView: aLessonView lessonView := aLessonView.! ! !ProfStef methodsFor: 'navigating' stamp: 'tg 2/1/2010 16:02'! next self player next. ^ self showCurrentLesson.! ! !ProfStef methodsFor: 'gui' stamp: 'tg 2/1/2010 16:02'! open self player first. ^ self showCurrentLesson.! ! !ProfStef methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:38'! player ^ player ifNil: [player := TutorialPlayer new]! ! !ProfStef methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:39'! player: aTutorialPlayer player := aTutorialPlayer.! ! !ProfStef methodsFor: 'navigating' stamp: 'tg 2/1/2010 16:02'! previous self player previous. ^ self showCurrentLesson.! ! !ProfStef methodsFor: 'gui' stamp: 'EstebanLorenzano 7/31/2013 11:10'! showCurrentLesson | progressInfo lesson position size | lesson := self player currentLesson. progressInfo := '(', self tutorialPositionString, '/', self tutorialSizeString, ')'. ^ self lessonView showLesson: lesson withTitle: lesson title, ' ', progressInfo.! ! !ProfStef methodsFor: 'navigating' stamp: 'DannyChan 2/1/2010 21:23'! tutorial: aTutorialClass lesson: aSelector | tutorial | tutorial := aTutorialClass new. self player tutorial: tutorial. self tutorial: aTutorialClass lessonAt: (tutorial indexOfLesson: aSelector).! ! !ProfStef methodsFor: 'navigating' stamp: 'DannyChan 2/1/2010 19:23'! tutorial: aTutorialClass lessonAt: lessonIndex self player tutorial: aTutorialClass new. self player tutorialPosition: lessonIndex. self showCurrentLesson.! ! !ProfStef methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:37'! tutorialPositionString ^ player tutorialPosition asString.! ! !ProfStef methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:38'! tutorialSizeString ^ self player size asString! ! !TutorialPlayer commentStamp: 'LaurentLaffont 1/21/2010 20:34' prior: 34153565! I can navigate through an AbstractTutorial subclass. With #next and #previous you can go forward and backward through the tutorial. ! !TutorialPlayer methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 15:37'! currentLesson ^ self tutorial lessonAt: self tutorialPosition.! ! !TutorialPlayer methodsFor: 'navigating' stamp: 'LaurentLaffont 1/21/2010 20:43'! first self rewind. ^ self currentLesson! ! !TutorialPlayer methodsFor: 'navigating' stamp: 'DannyChan 2/9/2010 19:29'! last tutorialPosition := self size. ^ self currentLesson! ! !TutorialPlayer methodsFor: 'navigating' stamp: 'LaurentLaffont 1/21/2010 15:40'! next self tutorialPosition < self size ifTrue: [tutorialPosition := tutorialPosition + 1]. ^ self currentLesson! ! !TutorialPlayer methodsFor: 'navigating' stamp: 'LaurentLaffont 1/18/2010 12:53'! previous tutorialPosition > 1 ifTrue: [tutorialPosition := tutorialPosition - 1]. ^ self currentLesson! ! !TutorialPlayer methodsFor: 'navigating' stamp: 'LaurentLaffont 1/21/2010 20:43'! rewind tutorialPosition := 1.! ! !TutorialPlayer methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 13:40'! size ^ self tutorial size! ! !TutorialPlayer methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 15:19'! tutorial ^ tutorial ifNil: [tutorial := SmalltalkSyntaxTutorial new]! ! !TutorialPlayer methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 15:22'! tutorial: aTutorial tutorial := aTutorial! ! !TutorialPlayer methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 20:43'! tutorialPosition ^ tutorialPosition ifNil: [ self rewind. tutorialPosition. ]. ! ! !TutorialPlayer methodsFor: 'accessing' stamp: 'DannyChan 2/1/2010 19:25'! tutorialPosition: aTutorialPosition tutorialPosition := aTutorialPosition ! ! !ProfStefHelpTutorialBuilder commentStamp: '' prior: 34153767! I build HelpSystem topics to browse ProfStef tutorials! !ProfStefHelpTutorialBuilder class methodsFor: 'instance creation' stamp: 'LaurentLaffont 4/26/2011 13:00'! new "We prohibid new" ^ (self class lookupSelector: #buildHelpTopicFrom:) == thisContext sender method ifFalse:[self error: 'Please use buildHelpTopicFrom: instead'] ifTrue: [super new]! ! !ProfStefHelpTutorialBuilder methodsFor: 'building' stamp: 'LaurentLaffont 9/19/2010 15:25'! build topicToBuild := HelpTopic named: rootToBuildFrom bookName. AbstractTutorial tutorials do: [:aTutorial| topicToBuild addSubtopic: (self buildTutorialTopicFor: aTutorial) ]. ^ topicToBuild.! ! !ProfStefHelpTutorialBuilder methodsFor: 'building' stamp: 'LaurentLaffont 9/19/2010 15:30'! buildTutorialTopicFor: aTutorial |tutorialTopic| tutorialTopic := HelpTopic named: aTutorial title. aTutorial new lessons do:[:aLesson| tutorialTopic addSubtopic: (HelpTopic title: aLesson title contents: aLesson lesson) ]. ^ tutorialTopic ! ! !ProfStefHelp commentStamp: 'LaurentLaffont 2/15/2011 22:17' prior: 34153894! HelpSystem book documenting ProfStef! !ProfStefAPIHelp commentStamp: 'LaurentLaffont 2/15/2011 22:18' prior: 34154006! I'm a ProfStef which build a HelpSystem book by collecting comment from classes and method.! !ProfStefAPIHelp class methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 15:14'! bookName ^ 'Reference'! ! !ProfStefAPIHelp class methodsFor: 'defaults' stamp: 'LaurentLaffont 9/19/2010 15:14'! builder ^ PackageAPIHelpBuilder! ! !ProfStefAPIHelp class methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 15:15'! packages ^ #('ProfStef-Core')! ! !ProfStefHelp class methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 15:07'! bookName ^ 'ProfStef'! ! !ProfStefHelp class methodsFor: 'testing' stamp: 'AlainPantec 2/23/2012 08:16'! canHaveSyntaxHighlighting ^ true ! ! !ProfStefHelp class methodsFor: 'pages' stamp: 'LaurentLaffont 9/19/2010 15:13'! createATutorial ^ HelpTopic title: 'Create a tutorial' contents: 'See AbstractTutorial comment: ', AbstractTutorial comment.! ! !ProfStefHelp class methodsFor: 'pages' stamp: 'LaurentLaffont 9/19/2010 16:38'! introduction ^ HelpTopic title: 'Introduction' contents: 'ProfStef is a framework to create interactive tutorials'.! ! !ProfStefHelp class methodsFor: 'pages' stamp: 'LaurentLaffont 9/19/2010 15:11'! listOfTutorials |contents| contents := String streamContents: [:aStream| AbstractTutorial tutorials do: [:aTutorial| aStream nextPutAll: aTutorial title; cr; tab; nextPutAll: 'ProfStef goOn:'; nextPutAll: aTutorial name; cr;cr. ] ]. ^ HelpTopic title: 'List of tutorials' contents: contents.! ! !ProfStefHelp class methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 15:13'! pages ^ #(introduction listOfTutorials createATutorial)! ! !ProfStefTutorialsHelp commentStamp: 'LaurentLaffont 2/15/2011 22:18' prior: 34154179! I'm a HelpSystem book which list all ProfStef tutorials! !ProfStefTutorialsHelp class methodsFor: 'accessing' stamp: 'LaurentLaffont 9/19/2010 15:16'! bookName ^ 'Browse tutorials'! ! !ProfStefTutorialsHelp class methodsFor: 'defaults' stamp: 'LaurentLaffont 9/19/2010 15:17'! builder ^ ProfStefHelpTutorialBuilder! ! !ProfStefTutorialsHelp class methodsFor: 'menu' stamp: 'LaurentLaffont 11/22/2010 22:00'! menuCommandOn: aBuilder (aBuilder item: #'ProfStef Tutorials') parent: #Help; action:[ HelpBrowser openOn: self ]; help: 'Browse and create ProfStef tutorials'..! ! !AbstractTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 9/21/2010 20:32'! testLessonsReturnsAllLessonInstances |lessons| lessons := MockTutorial new lessons. self assert:3 equals:lessons size. self assert: 'first' equals: lessons first title. self assert: 'second' equals: (lessons at:2 ) title. self assert: 'third' equals: lessons last title.! ! !AbstractTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 1/27/2010 21:05'! testTitleHumanizeClassName self assert: 'How To Make Your Own Tutorial' equals: HowToMakeYourOwnTutorial title. self assert: 'Smalltalk Syntax Tutorial' equals: SmalltalkSyntaxTutorial title.! ! !AbstractTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 12:46'! testTutorialRaisesShouldBeImplemented | tutorial | tutorial := AbstractTutorial new. self should: [tutorial tutorial] raise: Error withExceptionDo: [:anException | self assert: ShouldBeImplemented equals: anException class ]. ! ! !AbstractTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 1/30/2010 09:36'! testTutorialsReturnsAllButMockTutorial | tutorials | tutorials := AbstractTutorial tutorials. self assert: (tutorials includes: SmalltalkSyntaxTutorial). self assert: (tutorials includes: HowToMakeYourOwnTutorial). self deny: (tutorials includes: MockTutorial).! ! !HowToMakeYourOwnTutorialTest methodsFor: 'as yet unclassified' stamp: 'LaurentLaffont 2/1/2010 22:05'! testEachSelectorExists self testedTutorial tutorial do: [:aSelector| self assert: (self testedTutorial respondsTo: aSelector) ]! ! !HowToMakeYourOwnTutorialTest methodsFor: 'as yet unclassified' stamp: 'LaurentLaffont 2/1/2010 22:04'! testedTutorial "Returns an instance of an AbstractTutorial subclass" ^ HowToMakeYourOwnTutorial new! ! !LessonTestInstanciation methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 15:12'! testNewLessonHaveEmptyStringForTitleLesson | newLesson | newLesson := Lesson new. self assert: newLesson title equals: ''. self assert: newLesson lesson equals: ''.! ! !LessonTestInstanciation methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 15:10'! testTitleLessonCreation | firstLesson secondLesson | firstLesson := Lesson title: 'First lesson' lesson: 'Smalltalk rules!!'. secondLesson := Lesson title: 'Second lesson' lesson: 'ProfStef is cool'. self assert: firstLesson title equals: 'First lesson'. self assert: firstLesson lesson equals: 'Smalltalk rules!!'. self assert: secondLesson title equals: 'Second lesson'. self assert: secondLesson lesson equals: 'ProfStef is cool'.! ! !ProfStefHelpTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 16:50'! testBookName self assert: ProfStefHelp bookName isString! ! !ProfStefHelpTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 16:53'! testCreateATutorial | helpTopic | helpTopic := ProfStefHelp createATutorial. self assert: helpTopic notNil. self assert: helpTopic class == HelpTopic. self assert: helpTopic title = 'Create a tutorial'! ! !ProfStefHelpTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 16:54'! testIntroduction | helpTopic | helpTopic := ProfStefHelp introduction. self assert: helpTopic notNil. self assert: helpTopic class == HelpTopic. self assert: helpTopic title = 'Introduction'! ! !ProfStefHelpTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 16:49'! testListOfTutorials | helpTopic | helpTopic := ProfStefHelp listOfTutorials. self assert: (helpTopic notNil). self assert: (helpTopic title = 'List of tutorials' )! ! !ProfStefHelpTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 16:51'! testPages self assert: ProfStefHelp pages isCollection. self assert: (ProfStefHelp pages allSatisfy: #isSymbol).! ! !ProfStefHelpTutorialBuilderTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 17:13'! testBuild | helpTopic builder tutorial | tutorial := ProfStefTutorialsHelp. helpTopic := ProfStefHelpTutorialBuilder buildHelpTopicFrom: tutorial. self assert: helpTopic notNil! ! !ProfStefHelpTutorialBuilderTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2011 17:00'! testInstantiation self should: [ ProfStefHelpTutorialBuilder new ] raise: Error! ! !ProfStefTestGo methodsFor: 'running' stamp: 'LaurentLaffont 1/21/2010 20:53'! tearDown ProfStef default close! ! !ProfStefTestGo methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 21:08'! testGoOnMockTutorial | displayedText expected | ProfStef goOn: MockTutorial. displayedText := ProfStef default lessonView text. expected := MockTutorial new firstLesson lesson. self assert: displayedText equals: expected.! ! !ProfStefTestGo methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 21:06'! testGoOpenSmalltalkSyntaxTutorial | displayedText expected | ProfStef go. displayedText := ProfStef default lessonView text. expected := SmalltalkSyntaxTutorial new welcome lesson. self assert: displayedText equals: expected.! ! !ProfStefTestGo methodsFor: 'tests' stamp: 'LaurentLaffont 9/18/2011 20:10'! testGoTwiceShowLessonViewIfNotVisible | firstLessonView | ProfStef go. firstLessonView := ProfStef default lessonView. firstLessonView close. ProfStef goOn: SmalltalkSyntaxTutorial. self assert: (World systemWindows includes: firstLessonView window).! ! !ProfStefTestGo methodsFor: 'tests' stamp: 'LaurentLaffont 9/18/2011 20:00'! testGoTwiceUseSameLessonView | firstLessonView | ProfStef go. firstLessonView := ProfStef default lessonView. ProfStef goOn: SmalltalkSyntaxTutorial. self assert: (firstLessonView == ProfStef default lessonView).! ! !ProfStefTestGoOnMockTutorial methodsFor: 'running' stamp: 'LaurentLaffont 4/26/2011 13:54'! setUp ProfStef tutorial: MockTutorial lesson: #firstLesson ! ! !ProfStefTestGoOnMockTutorial methodsFor: 'running' stamp: 'LaurentLaffont 4/26/2011 13:26'! tearDown ProfStef default close! ! !ProfStefTestGoOnMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 13:26'! testFirstLessonShouldBeDisplayed. self assert: 'First lesson' equals: ProfStef default lessonView text! ! !ProfStefTestGoOnMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 13:34'! testLastShouldGoToThirdLesson ProfStef last. self assert: 'Third lesson' equals: ProfStef default lessonView text! ! !ProfStefTestGoOnMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 13:35'! testLastThenFirstShouldGoToFirstLesson ProfStef last; first. self assert: 'First lesson' equals: ProfStef default lessonView text! ! !ProfStefTestGoOnMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 13:35'! testLastThenPreviousShouldGoToSecondLesson ProfStef last; previous. self assert: 'Second lesson' equals: ProfStef default lessonView text! ! !ProfStefTestGoOnMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 4/26/2011 13:33'! testNextShouldGoToSecondLesson ProfStef next. self assert: 'Second lesson' equals: ProfStef default lessonView text! ! !ProfStefTestNavigation methodsFor: 'running' stamp: 'LaurentLaffont 1/21/2010 21:13'! setUp prof := ProfStef new. prof player: ( TutorialPlayer new tutorial: MockTutorial new; yourself). mockView := MockLessonView new. prof lessonView: mockView. prof open.! ! !ProfStefTestNavigation methodsFor: 'tests' stamp: 'LaurentLaffont 2/15/2011 22:13'! testNextOpenSecondLesson prof next. self assert: mockView title equals: 'second (2/3)'. self assert: mockView lesson lesson equals: 'Second lesson'.! ! !ProfStefTestNavigation methodsFor: 'tests' stamp: 'LaurentLaffont 2/15/2011 22:12'! testSequenceNextNextOpenThirdLesson prof next; next. self assert: mockView title equals: 'third (3/3)'. self assert: mockView lesson lesson equals: 'Third lesson'.! ! !ProfStefTestNavigation methodsFor: 'tests' stamp: 'LaurentLaffont 2/15/2011 22:11'! testSequenceNextNextPreviousOpenSecondLesson prof next; next; previous. self assert: mockView title equals: 'second (2/3)'. self assert: mockView lesson lesson equals: 'Second lesson'.! ! !ProfStefTestNavigation methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 16:27'! testShowFirstLessonOnGo | lesson | lesson := mockView lesson. self assert: lesson title equals: 'first'. self assert: lesson lesson equals: 'First lesson'.! ! !ProfStefTestNavigation methodsFor: 'as yet unclassified' stamp: 'LaurentLaffont 2/15/2011 22:12'! testShowingLessonByIndex prof tutorial: MockTutorial lessonAt: 2. self assert: mockView title equals: 'second (2/3)'. self assert: mockView lesson lesson equals: 'Second lesson'.! ! !ProfStefTestNavigation methodsFor: 'as yet unclassified' stamp: 'LaurentLaffont 2/15/2011 22:12'! testShowingLessonBySelector prof tutorial: MockTutorial lesson: #firstLesson. self assert: mockView title equals: 'first (1/3)'. self assert: mockView lesson lesson equals: 'First lesson'.! ! !SmalltalkSyntaxTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 12/12/2010 22:20'! testDivideTwoByZeroSignalsZeroDivide [self testedTutorial divideTwoByZero. self fail] on: ZeroDivide do: []! ! !SmalltalkSyntaxTutorialTest methodsFor: 'tests' stamp: 'LaurentLaffont 2/1/2010 22:07'! testEachSelectorExists self testedTutorial tutorial do: [:aSelector| self assert: (self testedTutorial respondsTo: aSelector) ]! ! !SmalltalkSyntaxTutorialTest methodsFor: 'requirements' stamp: 'LaurentLaffont 2/1/2010 22:06'! testedTutorial "Returns an instance of an AbstractTutorial subclass" ^ SmalltalkSyntaxTutorial new! ! !TutorialPlayerTestTutorialAccessor methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 21:18'! testDefaultsToSmalltalkSyntaxTutorial | player | player := TutorialPlayer new. self assert: (player tutorial isKindOf: SmalltalkSyntaxTutorial).! ! !TutorialPlayerTestTutorialAccessor methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 21:19'! testWithMockTutorial | mockTutorial player | mockTutorial := MockTutorial new. player := TutorialPlayer new tutorial: mockTutorial; yourself. self assert: player tutorial equals: mockTutorial.! ! !TutorialPlayerTestWithMockTutorial methodsFor: 'running' stamp: 'LaurentLaffont 1/21/2010 20:40'! setUp | tutorial | tutorial := MockTutorial new. player := TutorialPlayer new tutorial: (MockTutorial new)! ! !TutorialPlayerTestWithMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 20:40'! testCurrentLessonIsFirstOneAtCreation self assert: player currentLesson title equals: 'first'.! ! !TutorialPlayerTestWithMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 20:40'! testNavigation self assert: player next title equals: 'second'. self assert: player currentLesson title equals: 'second'. self assert: player next title equals: 'third'. self assert: player currentLesson title equals: 'third'. self assert: player next title equals: 'third'. self assert: player currentLesson title equals: 'third'. self assert: player previous title equals: 'second'. self assert: player currentLesson title equals: 'second'. self assert: player previous title equals: 'first'. self assert: player currentLesson title equals: 'first'. self assert: player previous title equals: 'first'. self assert: player currentLesson title equals: 'first'.! ! !TutorialPlayerTestWithMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 20:43'! testResetTutorialGoBackToFirstLesson player next; next. self assert: player currentLesson title equals: 'third'. player rewind. self assert: player currentLesson title equals: 'first'.! ! !TutorialPlayerTestWithMockTutorial methodsFor: 'tests' stamp: 'LaurentLaffont 1/21/2010 20:40'! testSizeReturnsThree self assert: player size equals: 3.! ! !Trait method! testEachSelectorExists self testedTutorial tutorial do: [:aSelector| self assert: (self tutorial respondsTo: aSelector) ]! ! !Trait method! testEachSelectorExists self testedTutorial tutorial do: [:aSelector| self assert: (self tutorial respondsTo: aSelector) ]! ! !Trait method! testEachSelectorReturnsALesson | answer | self testedTutorial tutorial do: [:aSelector| answer := (self testedTutorial perform: aSelector). self assert: (answer isKindOf: Lesson). ]! ! !Trait method! testEachSelectorReturnsALesson | answer | self testedTutorial tutorial do: [:aSelector| answer := (self testedTutorial perform: aSelector). self assert: (answer isKindOf: Lesson). ]! ! !Trait method! testLessonAtReturnsCorrespondingLesson | answer | 1 to: (self testedTutorial tutorial size) do: [:index| answer := self testedTutorial lessonAt: index. self assert: (answer isKindOf: Lesson) ] ! ! !Trait method! testLessonAtReturnsCorrespondingLesson | answer | 1 to: (self testedTutorial tutorial size) do: [:index| answer := self testedTutorial lessonAt: index. self assert: (answer isKindOf: Lesson) ] ! ! !Trait method! testNotEmpty self assert: self testedTutorial tutorial notEmpty.! ! !Trait method! testNotEmpty self assert: self testedTutorial tutorial notEmpty.! ! !Trait method! testSizeReturnsNumberOfSelectors self assert: (self testedTutorial tutorial size) equals: self testedTutorial size.! ! !Trait method! testSizeReturnsNumberOfSelectors self assert: (self testedTutorial tutorial size) equals: self testedTutorial size.! ! !Trait method! testedTutorial "Returns an instance of an AbstractTutorial subclass" ^ self explicitRequirement! ! !Trait method! testedTutorial "Returns an instance of an AbstractTutorial subclass" ^ self explicitRequirement! ! "ProfStef-Core"! "ProfStef-Help"! "ProfStef-Tests"! !ConfigurationOfProfStef commentStamp: '' prior: 0! To load last stable version: ConfigurationOfProfStef project latestVersion load. To load a specific version (ex: version 1.6): (ConfigurationOfProfStef project version: '1.6') load. to do: - should migrate shout and update the dependency.! !ConfigurationOfProfStef commentStamp: '' prior: 34204059! To load last stable version: ConfigurationOfProfStef project latestVersion load. To load a specific version (ex: version 1.6): (ConfigurationOfProfStef project version: '1.6') load. to do: - should migrate shout and update the dependency.! !ConfigurationOfProfStef class methodsFor: 'private' stamp: 'LaurentLaffont 1/21/2010 09:01'! bootstrapPackage: aString from: aPath | repository version | repository := MCHttpRepository location: aPath user: '' password: ''. repository versionReaderForFileNamed: aString , '.mcz' do: [:reader | version := reader version. version load. version workingCopy repositoryGroup addRepository: repository]! ! !ConfigurationOfProfStef class methodsFor: 'private' stamp: 'LaurentLaffont 1/21/2010 09:01'! ensureMetacello "Bootstrap Gofer (if necessary), bootstrap ConfigurationOfMetacello (using old Gofer API), then load the latest version of Metacello itself." Smalltalk at: #MetacelloProject ifAbsent: [ Smalltalk at: #Gofer ifAbsent: [ "Current version of Gofer from which to bootstrap - as of 1.0-beta.15" self bootstrapPackage: 'Gofer-lr.83' from: 'http://seaside.gemstone.com/ss/metacello' ]. Smalltalk at: #Gofer ifPresent: [:goferClass | | gofer | gofer := goferClass new url: 'http://seaside.gemstone.com/ss/metacello'; yourself. [ gofer addPackage: 'ConfigurationOfMetacello' ] on: Warning do: [:ex | ex resume ]. gofer load ]. "load latest version of Metacello, load a specific version if desired" (Smalltalk at: #ConfigurationOfMetacello) perform: #loadLatestVersion ]! ! !ConfigurationOfProfStef class methodsFor: 'metacello tool support' stamp: 'LaurentLaffont 1/21/2010 09:01'! isMetacelloConfig "Answer true and the Metacello tools will operate on you" ^true! ! !ConfigurationOfProfStef class methodsFor: 'metacello tool support' stamp: 'LaurentLaffont 1/21/2010 09:01'! lastMetacelloVersionLoad "Answer the last version loaded and the list of packages loaded for that version." LastVersionLoad == nil ifTrue: [ LastVersionLoad := nil -> 'default' ]. ^LastVersionLoad! ! !ConfigurationOfProfStef class methodsFor: 'loading' stamp: 'LaurentLaffont 2/26/2012 14:29'! load ^(self project version: #stable) load! ! !ConfigurationOfProfStef class methodsFor: 'loading' stamp: 'LaurentLaffont 2/26/2012 14:29'! loadDevelopment ^(self project version: #development) load! ! !ConfigurationOfProfStef class methodsFor: 'metacello tool support' stamp: 'LaurentLaffont 1/21/2010 09:01'! metacelloVersion: versionString loads: anArrayOrString "Stash the last version loaded and the list of packages loaded for that version. The list of packages will be used by the tools when doing 'Load Package Version'" LastVersionLoad := versionString -> anArrayOrString! ! !ConfigurationOfProfStef class methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 09:01'! project ^self new project! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'DaleHenrichs 3/4/2010 10:30'! baseline10: spec spec for: #common do: [ spec blessing: #baseline. ]. spec for: #pharo do: [ spec repository: 'http://www.squeaksource.com/ProfStef'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core'); group: 'Core' with: #('ProfStef-Core'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Core Tests' with: #('Core' 'Tests'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'LaurentLaffont 5/10/2010 22:16'! baseline11: spec spec for: #common do: [ spec blessing: #baseline. ]. spec for: #pharo do: [ spec repository: 'http://www.squeaksource.com/ProfStef'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core Browser Tests'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Core Browser Tests' with: #('Core' 'Browser' 'Tests'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'LaurentLaffont 9/19/2010 16:44'! baseline12: spec spec for: #common do: [ spec blessing: #baseline. ]. spec for: #pharo do: [ spec repository: 'http://www.squeaksource.com/ProfStef'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Help' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core' 'Browser' 'Tests' 'Help'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Help' with: #('ProfStef-Help'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'LaurentLaffont 11/22/2010 22:03'! baseline15: spec spec for: #common do: [ spec blessing: #baseline. ]. spec for: #pharo do: [ spec repository: 'http://www.squeaksource.com/ProfStef'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Help' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core' 'Tests' 'Help'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Help' with: #('ProfStef-Help'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'TudorGirba 11/24/2010 00:00'! baseline16: spec spec for: #common do: [ spec blessing: #baseline. ]. spec for: #pharo do: [ spec repository: 'http://www.squeaksource.com/ProfStef'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Help' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core' 'Tests' 'Help'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Help' with: #('ProfStef-Help'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'TudorGirba 3/11/2013 08:04'! baseline17: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Migration to SmalltalkHub'. ]. spec for: #pharo do: [ spec repository: 'http://smalltalkhub.com/mc/PharoExtras/ProfStef/main'. spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; loads: #('Core' ); file: 'ConfigurationOfShout'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec package: 'ProfStef-Core' with: [ spec requires: 'Shout' ]; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Help' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core' 'Tests' 'Help'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Help' with: #('ProfStef-Help'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'baselines' stamp: 'TudorGirba 3/11/2013 08:01'! baseline18: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'No Shout in Pharo 2.0'. ]. spec for: #pharo do: [ spec repository: 'http://smalltalkhub.com/mc/PharoExtras/ProfStef/main'. spec package: 'ProfStef-Core'; package: 'ProfStefBrowser' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Tests' with: [ spec requires: 'ProfStef-Core']; package: 'ProfStef-Help' with: [ spec requires: 'ProfStef-Core']. spec group: 'default' with: #('Core' 'Tests' 'Help'); group: 'Core' with: #('ProfStef-Core'); group: 'Browser' with: #('ProfStefBrowser'); group: 'Tests' with: #('ProfStef-Tests'); group: 'Help' with: #('ProfStef-Help'); yourself. ]! ! !ConfigurationOfProfStef methodsFor: 'accessing' stamp: 'LaurentLaffont 1/21/2010 09:01'! project ^ project ifNil: [ | constructor | "Bootstrap Metacello if it is not already loaded" self class ensureMetacello. "Construct Metacello project" constructor := (Smalltalk at: #MetacelloVersionConstructor) on: self. project := constructor project. project loadType: #linear. project ]! ! !ConfigurationOfProfStef methodsFor: 'symbolic versions' stamp: 'EstebanLorenzano 7/31/2013 11:25'! stable: spec spec for: #'pharo1.0.x' version: '1.0'. spec for: #'pharo1.1.x' version: '1.1'. spec for: #'pharo1.2.x' version: '1.6'. spec for: #'pharo1.3.x' version: '1.9'. spec for: #'pharo1.4.x' version: '1.9'. spec for: #'pharo2.x' version: '1.11'.! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 2/1/2010 22:29'! version10: spec spec for: #common do: [ spec blessing: #release. spec author: 'LaurentLaffont'. spec description: 'Release 1.0 of this project '. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.0'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.2'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.2'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'TudorGirba 3/11/2013 08:00'! version110: spec spec for: #common do: [ spec blessing: #release. spec author: 'Laurent Laffont'. spec description: 'Fix syntax highlighting'. ]. spec for: #pharo do: [ spec package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.29'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.16'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.30'; package: 'ProfStef-Help' with: 'ProfStef-Help-AlainPantec.7'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'EstebanLorenzano 7/31/2013 11:25'! version111: spec spec for: #common do: [ spec blessing: #release. spec author: 'EstebanLorenzano'. spec description: 'Fix cmd+p bug'. ]. spec for: #pharo do: [ spec package: 'ProfStef-Core' with: 'ProfStef-Core-EstebanLorenzano.30'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.16'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.30'; package: 'ProfStef-Help' with: 'ProfStef-Help-AlainPantec.7'. ]! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 9/19/2010 16:45'! version11: spec spec for: #common do: [ spec blessing: #release. spec author: 'LaurentLaffont'. spec description: 'Release 1.1 of this project '. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.0'; package: 'ProfStef-Core' with: 'ProfStef-Core-DannyChan.10'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.8'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.26'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 9/19/2010 16:47'! version12: spec spec for: #common do: [ spec blessing: #release. spec author: 'LaurentLaffont'. spec description: 'Release 1.2 -- Add SystemHelp'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.0'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.11'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.8'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.26'; package: 'ProfStef-Help' with: 'ProfStef-Help-LaurentLaffont.1'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'jannikLaval 11/20/2010 08:46'! version13: spec spec for: #common do: [ spec blessing: #release. spec author: 'AlexandreBergel'. spec description: 'Updated Shout'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.1.1'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.11'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.8'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.26'; package: 'ProfStef-Help' with: 'ProfStef-Help-LaurentLaffont.1'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'jannikLaval 11/20/2010 08:45'! version14: spec spec for: #common do: [ spec blessing: #release. spec author: 'JannikLaval'. spec description: 'Updated Shout for Pharo 1.2'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.2.1'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.11'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.8'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.26'; package: 'ProfStef-Help' with: 'ProfStef-Help-LaurentLaffont.1'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 11/22/2010 22:17'! version15: spec spec for: #common do: [ spec blessing: #release. spec author: 'LaurentLaffont'. spec description: '- Updated ProfStef packages for Pharo 1.2. - ProfStefBrowser removed from default - ProfStef-Help is now the default browser'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.2.1'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.14'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.9'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.29'; package: 'ProfStef-Help' with: 'ProfStef-Help-LaurentLaffont.2'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 2/15/2011 22:54'! version16: spec spec for: #common do: [ spec blessing: #release. spec author: 'LaurentLaffont'. spec description: '- Updated ProfStef packages for Pharo 1.2. - ProfStefBrowser removed from default - ProfStef-Help is now the default browser - Add lessons on Reflection and Debugger in SmalltalkSyntaxTutorial'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.2.2'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.22'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.11'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.29'; package: 'ProfStef-Help' with: 'ProfStef-Help-LaurentLaffont.3'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'MarianoMartinezPeck 4/29/2011 20:06'! version17: spec spec for: #common do: [ spec blessing: #development. spec author: 'Mariano Martinez Peck'. spec description: '- Updated for Pharo 1.3'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.3'; package: 'ProfStef-Core' with: 'ProfStef-Core-MarianoMartinezPeck.24'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-MarianoMartinezPeck.14'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.30'; package: 'ProfStef-Help' with: 'ProfStef-Help-MarianoMartinezPeck.6'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'LaurentLaffont 9/18/2011 20:23'! version18: spec spec for: #common do: [ spec blessing: #development. spec author: 'Laurent Laffont'. spec description: '- Updated for Pharo 1.4'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.3'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.28'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.16'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.30'; package: 'ProfStef-Help' with: 'ProfStef-Help-MarianoMartinezPeck.6'. ] ! ! !ConfigurationOfProfStef methodsFor: 'versions' stamp: 'TudorGirba 3/11/2013 07:59'! version19: spec spec for: #common do: [ spec blessing: #release. spec author: 'Laurent Laffont'. spec description: 'Fix syntax highlighting'. ]. spec for: #pharo do: [ spec project: 'Shout' with: '1.3'; package: 'ProfStef-Core' with: 'ProfStef-Core-LaurentLaffont.29'; package: 'ProfStef-Tests' with: 'ProfStef-Tests-LaurentLaffont.16'; package: 'ProfStefBrowser' with: 'ProfStefBrowser-LaurentLaffont.30'; package: 'ProfStef-Help' with: 'ProfStef-Help-AlainPantec.7'. ] ! ! "ConfigurationOfProfStef"! ConfigurationOfProfStef removeSelector: #version19:! ConfigurationOfProfStef removeSelector: #version18:! ConfigurationOfProfStef removeSelector: #version17:! ConfigurationOfProfStef removeSelector: #version16:! ConfigurationOfProfStef removeSelector: #version15:! ConfigurationOfProfStef removeSelector: #version14:! ConfigurationOfProfStef removeSelector: #version13:! ConfigurationOfProfStef removeSelector: #version12:! ConfigurationOfProfStef removeSelector: #version11:! ConfigurationOfProfStef removeSelector: #version111:! ConfigurationOfProfStef removeSelector: #version110:! ConfigurationOfProfStef removeSelector: #version10:! ConfigurationOfProfStef removeSelector: #stable:! ConfigurationOfProfStef removeSelector: #project! ConfigurationOfProfStef removeSelector: #baseline18:! ConfigurationOfProfStef removeSelector: #baseline17:! ConfigurationOfProfStef removeSelector: #baseline16:! ConfigurationOfProfStef removeSelector: #baseline15:! ConfigurationOfProfStef removeSelector: #baseline12:! ConfigurationOfProfStef removeSelector: #baseline11:! ConfigurationOfProfStef removeSelector: #baseline10:! ConfigurationOfProfStef class removeSelector: #project! ConfigurationOfProfStef class removeSelector: #metacelloVersion:loads:! ConfigurationOfProfStef class removeSelector: #loadDevelopment! ConfigurationOfProfStef class removeSelector: #load! ConfigurationOfProfStef class removeSelector: #lastMetacelloVersionLoad! ConfigurationOfProfStef class removeSelector: #isMetacelloConfig! ConfigurationOfProfStef class removeSelector: #ensureMetacello! ConfigurationOfProfStef class removeSelector: #bootstrapPackage:from:! Smalltalk globals removeClassNamed: #ConfigurationOfProfStef! ----End fileIn----! ----QUIT----an Array(31 July 2013 1:32:44 pm) Pharo.image priorSource: 587508! ----STARTUP----an Array(31 July 2013 1:32:46 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(31 July 2013 1:32:46 pm) Pharo-20618.image priorSource: 670223! ----STARTUP----an Array(13 August 2013 2:58:01 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! !ScriptLoader methodsFor: 'public' stamp: 'EstebanLorenzano 8/13/2013 14:53' prior: 34142262! commentForCurrentUpdate ^ '11209 backport 2.0: Add RPackageSet cache https://pharo.fogbugz.com/f/cases/11209 '! ! !ScriptLoader methodsFor: 'pharo - scripts' stamp: 'EstebanLorenzano 8/13/2013 14:53'! script592 ^ 'AST-Core-MarcusDenker.113.mcz AST-Semantic-StephaneDucasse.21.mcz AST-Tests-Core-MarcusDenker.21.mcz AST-Tests-Semantic-StephaneDucasse.5.mcz AndreasProfiler-EstebanLorenzano.5.mcz Announcements-Core-MarcusDenker.37.mcz Announcements-Help-MarcusDenker.5.mcz Announcements-Tests-Core-StephaneDucasse.11.mcz Announcements-View-MarcusDenker.13.mcz AsmJit-Core-CamilloBruni.2.mcz AsmJit-Extension-StephaneDucasse.6.mcz AsmJit-Instructions-CamilloBruni.3.mcz AsmJit-Operands-CamilloBruni.3.mcz AsmJit-StackManagement-CamilloBruni.2.mcz AsmJit-x86-IgorStasenko.3.mcz Balloon-MarcusDenker.91.mcz BalloonTests-MarcusDenker.1.mcz CI-Core-EstebanLorenzano.66.mcz CI-Loader-MarcusDenker.1.mcz CodeImport-MarcusDenker.12.mcz CodeImport-Tests-MarcusDenker.8.mcz Collections-Abstract-MarcusDenker.199.mcz Collections-Arithmetic-StephaneDucasse.6.mcz Collections-Arrayed-EstebanLorenzano.69.mcz Collections-Atomic-MarcusDenker.5.mcz Collections-Native-MarcusDenker.6.mcz Collections-Sequenceable-EstebanLorenzano.130.mcz Collections-Stack-MarcusDenker.7.mcz Collections-Streams-MarcusDenker.131.mcz Collections-Strings-MarcusDenker.240.mcz Collections-Support-MarcusDenker.49.mcz Collections-Text-EstebanLorenzano.82.mcz Collections-Traits-MarcusDenker.13.mcz Collections-Unordered-MarcusDenker.147.mcz Collections-Weak-MarcusDenker.68.mcz CollectionsTests-MarcusDenker.583.mcz Compatibility-MarcusDenker.10.mcz Compiler-EstebanLorenzano.379.mcz CompilerTests-MarcusDenker.131.mcz Compression-MarcusDenker.124.mcz CompressionTests-MarcusDenker.21.mcz ConfigurationCommandLineHandler-Core-MarcusDenker.8.mcz ConfigurationCommandLineHandler-Tests-MarcusDenker.2.mcz Deprecated20-MarcusDenker.32.mcz EmergencyEvaluator-MarcusDenker.28.mcz EventModel-StephaneDucasse.1.mcz FamFam-Icons-EstebanLorenzano.15.mcz FileSystem-AnsiStreams-MarcusDenker.7.mcz FileSystem-Core-MarcusDenker.69.mcz FileSystem-Disk-MarcusDenker.48.mcz FileSystem-Memory-MarcusDenker.20.mcz FileSystem-Tests-AnsiStreams-MarcusDenker.6.mcz FileSystem-Tests-Core-MarcusDenker.39.mcz FileSystem-Tests-Disk-MarcusDenker.13.mcz FileSystem-Tests-Memory-MarcusDenker.4.mcz FileSystem-Zip-EstebanLorenzano.6.mcz Files-MarcusDenker.ducasse.296.mcz FreeType-MarcusDenker.612.mcz FreeTypeTests-StephaneDucasse.3.mcz Fuel-EstebanLorenzano.767.mcz FuelCommandLineHandler-EstebanLorenzano.21.mcz FuelSystem-FileRegistry-EstebanLorenzano.3.mcz FuelTests-EstebanLorenzano.316.mcz FuelTools-Debugger-EstebanLorenzano.2.mcz Gofer-Core-MarcusDenker.194.mcz Gofer-Tests-MarcusDenker.157.mcz Graphics-Display Objects-MarcusDenker.104.mcz Graphics-Files-MarcusDenker.39.mcz Graphics-Fonts-MarcusDenker.67.mcz Graphics-Primitives-StephaneDucasse.99.mcz Graphics-Resources-StephaneDucasse.16.mcz Graphics-Tests-StephaneDucasse.30.mcz Graphics-Transformations-StephaneDucasse.7.mcz GroupManager-EstebanLorenzano.39.mcz GroupManagerUI-EstebanLorenzano.14.mcz Growl-MarcusDenker.13.mcz HelpSystem-Core-StephaneDucasse.89.mcz HelpSystem-Tests-StephaneDucasse.19.mcz HudsonBuildTools20-EstebanLorenzano.25.mcz Kernel-MarcusDenker.1350.mcz KernelTests-MarcusDenker.478.mcz KeyChain-MarcusDenker.30.mcz Keymapping-Core-EstebanLorenzano.147.mcz Keymapping-Pragmas-MarcusDenker.39.mcz Keymapping-Settings-MarcusDenker.65.mcz Keymapping-Shortcuts-EstebanLorenzano.65.mcz Keymapping-Tests-MarcusDenker.69.mcz Keymapping-Tools-Spec-MarcusDenker.16.mcz Manifest-Core-MarcusDenker.111.mcz Manifest-CriticBrowser-EstebanLorenzano.64.mcz Manifest-Resources-Tests-EstebanLorenzano.9.mcz Manifest-Tests-MarcusDenker.26.mcz MenuRegistration-EstebanLorenzano.47.mcz Metacello-Base-MarcusDenker.20.mcz Metacello-Core-MarcusDenker.496.mcz Metacello-MC-StephaneDucasse.666.mcz Metacello-Platform.pharo20-EstebanLorenzano.31.mcz Metacello-ToolBox-MarcusDenker.135.mcz Monticello-EstebanLorenzano.784.mcz MonticelloConfigurations-StephaneDucasse.61.mcz MonticelloGUI-MarcusDenker.216.mcz MonticelloMocks-EstebanLorenzano.2.mcz Morphic-MarcusDenker.1374.mcz MorphicTests-MarcusDenker.67.mcz Multilingual-Encodings-MarcusDenker.39.mcz Multilingual-Languages-MarcusDenker.30.mcz Multilingual-Tests-MarcusDenker.25.mcz Multilingual-TextConversion-MarcusDenker.48.mcz NECompletion-MarcusDenker.101.mcz NOCompletion-MarcusDenker.34.mcz NativeBoost-Core-EstebanLorenzano.116.mcz NativeBoost-Examples-EstebanLorenzano.16.mcz NativeBoost-Mac-IgorStasenko.8.mcz NativeBoost-Pools-IgorStasenko.12.mcz NativeBoost-Unix-IgorStasenko.12.mcz NativeBoost-Win32-EstebanLorenzano.35.mcz Nautilus-MarcusDenker.441.mcz NautilusCommon-MarcusDenker.120.mcz NautilusRefactoring-MarcusDenker.78.mcz Network-Kernel-MarcusDenker.86.mcz Network-MIME-MarcusDenker.52.mcz Network-Mail-StephaneDucasse.14.mcz Network-Protocols-EstebanLorenzano.91.mcz Network-RFC822-StephaneDucasse.4.mcz Network-URI-MarcusDenker.41.mcz Network-UUID-MarcusDenker.22.mcz Network-Url-MarcusDenker.84.mcz NetworkTests-MarcusDenker.79.mcz NewClassOrganizer-MarcusDenker.7.mcz NewList-MarcusDenker.25.mcz NonInteractiveTranscript-MarcusDenker.5.mcz PackageInfo-MarcusDenker.91.mcz Polymorph-EventEnhancements-MarcusDenker.13.mcz Polymorph-Geometry-LaurentLaffont.8.mcz Polymorph-TaskbarIcons-MarcusDenker.12.mcz Polymorph-Tools-Diff-StephaneDucasse.86.mcz Polymorph-Widgets-MarcusDenker.775.mcz ProfStef-Core-EstebanLorenzano.30.mcz ProfStef-Help-AlainPantec.7.mcz ProfStef-Tests-LaurentLaffont.16.mcz RPackage-Core-EstebanLorenzano.218.mcz RPackage-SystemIntegration-EstebanLorenzano.162.mcz RPackage-Tests-EstebanLorenzano.111.mcz RecentSubmissions-EstebanLorenzano.180.mcz Refactoring-Changes-MarcusDenker.35.mcz Refactoring-Core-MarcusDenker.169.mcz Refactoring-Critics-MarcusDenker.30.mcz Refactoring-Environment-StephaneDucasse.12.mcz Refactoring-Pharo-Platform-EstebanLorenzano.2.mcz Refactoring-Spelling-MarcusDenker.38.mcz Refactoring-Tests-Changes-StephaneDucasse.18.mcz Refactoring-Tests-Core-StephaneDucasse.63.mcz Refactoring-Tests-Critics-MarcusDenker.8.mcz Refactoring-Tests-Environment-StephaneDucasse.5.mcz Regex-Core-MarcusDenker.22.mcz Regex-Help-StephaneDucasse.2.mcz Regex-Tests-Core-StephaneDucasse.3.mcz Ring-Core-Containers-MarcusDenker.19.mcz Ring-Core-Kernel-MarcusDenker.90.mcz Ring-Monticello-StephaneDucasse.12.mcz Ring-Tests-Containers-MarcusDenker.9.mcz Ring-Tests-Kernel-MarcusDenker.44.mcz Ring-Tests-Monticello-MarcusDenker.10.mcz SUnit-Core-MarcusDenker.66.mcz SUnit-Help-MarcusDenker.4.mcz SUnit-Tests-MarcusDenker.21.mcz SUnit-UI-MarcusDenker.60.mcz SUnit-UITesting-MarcusDenker.4.mcz SUnit-Utilities-EstebanLorenzano.10.mcz Settings-Compiler-StephaneDucasse.3.mcz Settings-Display-MarcusDenker.7.mcz Settings-FreeType-MarcusDenker.9.mcz Settings-Graphics-MarcusDenker.14.mcz Settings-Kernel-StephaneDucasse.3.mcz Settings-Monticello-MarcusDenker.6.mcz Settings-Network-StephaneDucasse.16.mcz Settings-Polymorph-StephaneDucasse.45.mcz Settings-System-MarcusDenker.23.mcz Settings-Tools-StephaneDucasse.39.mcz Shout-StephaneDucasse.158.mcz ShoutTests-MarcusDenker.17.mcz Spec-Bindings-StephaneDucasse.22.mcz Spec-Builder-MarcusDenker.21.mcz Spec-Core-MarcusDenker.88.mcz Spec-Examples-EstebanLorenzano.18.mcz Spec-Layout-MarcusDenker.27.mcz Spec-Tests-EstebanLorenzano.21.mcz Spec-Tools-MarcusDenker.89.mcz Spec-Widgets-MarcusDenker.109.mcz StartupPreferences-MarcusDenker.79.mcz System-Announcements-MarcusDenker.41.mcz System-Applications-MarcusDenker.44.mcz System-Changes-EstebanLorenzano.198.mcz System-Clipboard-StephaneDucasse.23.mcz System-CommandLine-MarcusDenker.83.mcz System-FilePackage-MarcusDenker.72.mcz System-FileRegistry-MarcusDenker.24.mcz System-Finalization-StephaneDucasse.17.mcz System-Hashing-MarcusDenker.20.mcz System-History-MarcusDenker.5.mcz System-Installers-MarcusDenker.26.mcz System-Localization-MarcusDenker.67.mcz System-Object Events-StephaneDucasse.11.mcz System-Platforms-MarcusDenker.27.mcz System-PragmaCollector-MarcusDenker.11.mcz System-Serial Port-MarcusDenker.20.mcz System-Settings-MarcusDenker.271.mcz System-Sound-StephaneDucasse.10.mcz System-Support-MarcusDenker.803.mcz System-Text-EstebanLorenzano.216.mcz System-Tools-StephaneDucasse.93.mcz SystemProgress-MarcusDenker.5.mcz Tests-MarcusDenker.522.mcz Text-EstebanLorenzano.52.mcz TextTests-MarcusDenker.3.mcz Tools-MarcusDenker.1066.mcz ToolsTest-MarcusDenker.denker.30.mcz Traits-MarcusDenker.464.mcz Transcript-MarcusDenker.6.mcz UI-MarcusDenker.5.mcz UIManager-MarcusDenker.98.mcz Unicode-Initialization-MarcusDenker.4.mcz UpdateStreamer-Core-MarcusDenker.13.mcz UpdateStreamer-Tests-MarcusDenker.2.mcz Zinc-Character-Encoding-Core-SvenVanCaekenberghe.7.mcz Zinc-Character-Encoding-Tests-SvenVanCaekenberghe.5.mcz Zinc-FileSystem-SvenVanCaekenberghe.9.mcz Zinc-HTTP-SvenVanCaekenberghe.346.mcz Zinc-Patch-HTTPSocket-MarcusDenker.4.mcz Zinc-Resource-Meta-Core-SvenVanCaekenberghe.12.mcz Zinc-Resource-Meta-FileSystem-MarcusDenker.3.mcz Zinc-Resource-Meta-Tests-SvenVanCaekenberghe.8.mcz Zinc-System-Support-MarcusDenker.5.mcz Zinc-Tests-SvenVanCaekenberghe.177.mcz Zinc-Zodiac-EstebanLorenzano.26.mcz Zodiac-Core-SvenVanCaekenberghe.27.mcz Zodiac-Extra-NorbertHartl.6.mcz Zodiac-Tests-SvenVanCaekenberghe.10.mcz' findTokens: String lf , String cr! ! !ScriptLoader methodsFor: 'pharo - updates' stamp: 'EstebanLorenzano 8/13/2013 14:54'! update20619 "self new update20619" self withUpdateLog: '11209 backport 2.0: Add RPackageSet cache https://pharo.fogbugz.com/f/cases/11209 '. self loadTogether: self script592 merge: false. self flushCaches. ! ! "ScriptLoader20"! !RPackageSet commentStamp: '' prior: 32058383! I'm a set who can be instantiated by pattern matching RPackages ("name" and "name-*"). My purpose is to provide a bridge between monticello and system packages, to allow backward compatibility with old packaging. ! !MCVersion methodsFor: 'accessing' stamp: 'ThierryGoubier 7/19/2013 17:23' prior: 25090845! dependencies ^ dependencies ifNil: [#()]! ! !MetacelloPharoPlatform methodsFor: 'notification' stamp: 'ThierryGoubier 7/22/2013 13:36' prior: 26003629! do: aBlock displaying: aString self bypassProgressBars ifTrue: [ ^ super do: aBlock displaying: aString ]. aString displayProgressFrom: 0 to: 2 during: [ :bar | bar current: 1. RPackageSet withCacheDo: [ aBlock value ]. bar current: 2 ]! ! !MCVersionLoader methodsFor: 'loading' stamp: 'ThierryGoubier 7/22/2013 13:36' prior: 25120407! load RPackageSet withCacheDo: [ self loadWithNameLike: versions first info name ]! ! !RPackageSet commentStamp: '' prior: 34234936! I'm a set who can be instantiated by pattern matching RPackages ("name" and "name-*"). My purpose is to provide a bridge between monticello and system packages, to allow backward compatibility with old packaging. ! !RPackageSet class methodsFor: 'instance creation' stamp: 'ThierryGoubier 7/22/2013 13:29'! basicNamed: aString "We force the creation of a PackageInfo to keep backward compatibility of tools" self flag: #hack. PackageInfo named: aString. ^ self basicNew initialize: aString; yourself! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:32'! cacheActive: aBoolean cacheActive := aBoolean! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:33'! cachePackageAt: aString ifAbsentPut: aBlock ^ self cachePackages at: aString asSymbol ifAbsentPut: aBlock! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:33'! cachePackages ^ cachePackages ifNil: [ cachePackages := IdentityDictionary new ]! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:33'! isCacheActive ^ cacheActive ifNil: [ cacheActive := false ]! ! !RPackageSet class methodsFor: 'instance creation' stamp: 'ThierryGoubier 7/22/2013 13:35' prior: 32067592! named: aString ^ self isCacheActive ifTrue: [ self cachePackageAt: aString ifAbsentPut: [ self basicNamed: aString ] ] ifFalse: [ self basicNamed: aString ]! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:33'! resetCache cachePackages := nil! ! !RPackageSet class methodsFor: 'caching' stamp: 'ThierryGoubier 7/22/2013 13:33'! withCacheDo: aBlock | oldActive | oldActive := self isCacheActive. self cacheActive: true. aBlock ensure: [ self cacheActive: oldActive. self isCacheActive ifFalse: [ self resetCache ] ]! ! "Metacello-Platform"! "Monticello"! "RPackage-Core"! ----End fileIn----! ----QUIT----an Array(13 August 2013 2:58:07 pm) Pharo.image priorSource: 670439! ----STARTUP----an Array(13 August 2013 2:58:09 pm) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----SNAPSHOT----an Array(13 August 2013 2:58:09 pm) Pharo-20619.image priorSource: 683372! ----STARTUP----an Array(21 August 2013 10:53:04 am) as /Users/jenkins-pharo/Documents/ci.inria.fr/pharo/workspace/Pharo-2.0/Pharo.image! ----QUIT----an Array(21 August 2013 10:53:04 am) Pharo.image priorSource: 683592! ----STARTUP----an Array(24 September 2013 7:06:35 pm) as /Users/petr/Dev/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:06:42 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:07:04 pm) as /Users/petr/Dev/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:07:08 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:10:08 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:10:14 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:10:42 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:10:51 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:11:49 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:11:54 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:12:32 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:12:35 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(24 September 2013 7:13:28 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(24 September 2013 7:13:31 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(4 November 2013 3:58:24 pm) as /Users/petr/Dev/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(4 November 2013 3:58:34 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(4 November 2013 3:58:41 pm) as /Applications/Developement/Pharo2.0.app/Contents/Resources/Pharo2.0.image! ----QUIT/NOSAVE----an Array(4 November 2013 3:58:45 pm) Pharo2.0.image priorSource: 683823! ----STARTUP----an Array(10 November 2013 5:24:12 pm) as /Users/petr/Dev/Pharo2.0.app/Contents/Resources/Pharo2.0.image! MetacelloConfigurationBrowser open.! !ConfigurationOfPetitParser commentStamp: '' prior: 0! self loadDevelopment! !ConfigurationOfPetitParser commentStamp: '' prior: 34240586! self loadDevelopment! !ConfigurationOfPetitParser class methodsFor: 'private' stamp: 'FabrizioPerin 4/27/2010 15:04'! ensureMetacello Smalltalk at: #MetacelloProject ifAbsent: [ Gofer new url: 'http://seaside.gemstone.com/ss/metacello'; package: 'ConfigurationOfMetacello'; load. (Smalltalk at: #ConfigurationOfMetacello) loadLatestVersion ]! ! !ConfigurationOfPetitParser class methodsFor: 'metacello tool support' stamp: 'tg 4/18/2010 23:51'! isMetacelloConfig "Answer true and the Metacello tools will operate on you" ^true! ! !ConfigurationOfPetitParser class methodsFor: 'loading' stamp: 'TudorGirba 4/21/2013 23:28'! loadDefault self loadDevelopment! ! !ConfigurationOfPetitParser class methodsFor: 'loading' stamp: 'TudorGirba 4/21/2013 23:27'! loadDevelopment (self project version: #development) load! ! !ConfigurationOfPetitParser class methodsFor: 'loading' stamp: 'TudorGirba 12/12/2010 21:25'! loadMinimal (self project version: 'minimal') load! ! !ConfigurationOfPetitParser class methodsFor: 'accessing' stamp: 'tg 4/18/2010 23:51'! project ^self new project! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'AlexandreBergel 12/3/2010 09:14'! baseline10: spec spec for: #common do: [ spec blessing: #baseline. spec author: 'Alexandre Bergel'. spec description: 'work on Pharo 1.1.1'. spec repository: 'http://source.lukas-renggli.ch/petit'. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: 'PetitParser']; package: 'PetitAnalyzer' with: [ spec requires: 'PetitTests']; package: 'PetitGui' with: [ spec requires: 'Glamour for Petit']. spec group: 'Core' with: #( 'PetitParser' 'PetitAnalyzer' ). spec group: 'Tests' with: #( 'PetitTests' 'PetitAnalyzer' ). spec project: 'Glamour for Petit' with: [ spec className: 'ConfigurationOfGlamour'; file: 'ConfigurationOfGlamour'; version: '2.0-beta.8'; repository: 'http://www.squeaksource.com/Glamour' ]. ]! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'AlexandreBergel 2/18/2011 13:56'! baseline11: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: 'Preparing Moose 4.3.2'. spec repository: 'http://source.lukas-renggli.ch/petit'. spec project: 'Glamour for Petit' with: [ spec className: 'ConfigurationOfGlamour'; versionString: '2.1'; repository: 'http://www.squeaksource.com/Glamour' ]. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: #('PetitParser' ). ]; package: 'PetitAnalyzer' with: [ spec requires: #('PetitTests' ). ]; package: 'PetitGui' with: [ spec requires: #('Glamour for Petit' ). ]. spec group: 'Core' with: #('PetitParser' 'PetitAnalyzer' ); group: 'Tests' with: #('PetitTests' 'PetitAnalyzer' ). ]. ! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'DiegoLont 9/2/2013 11:15'! baseline12: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: 'Describing satellite packages'. spec repository: 'http://source.lukas-renggli.ch/petit'. spec project: 'Glamour for Petit' with: [ spec className: 'ConfigurationOfGlamour'; versionString: '2.1'; repository: 'http://www.squeaksource.com/Glamour' ]. spec project: 'AST-Core' with: [ spec repository: 'http://www.squeaksource.com/MetacelloRepository'; className: 'ConfigurationOfRefactoringBrowser'; loads: #('AST-Core') ]. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: #('PetitParser' ) ]; package: 'PetitAnalyzer' with: [ spec requires: #('PetitTests' ) ]; package: 'PetitGui' with: [ spec requires: #('Glamour for Petit' ) ]; package: 'PetitSmalltalk' with: [ spec requires: #( 'AST-Core' 'PetitParser' 'PetitTests') ]. "todo: declare all other packages & dependencies here" spec group: 'Core' with: #('PetitParser' 'PetitAnalyzer' ); group: 'Tests' with: #('PetitTests' 'PetitAnalyzer' ) ] ! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'DiegoLont 9/2/2013 11:16'! baseline13: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: 'Describing all satellite packages'. spec repository: 'http://source.lukas-renggli.ch/petit'. spec project: 'Glamour for Petit' with: [ spec className: 'ConfigurationOfGlamour'; versionString: '2.1'; loads: #(Core Morphic); repository: 'http://www.squeaksource.com/Glamour' ]. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: #('PetitParser' ). ]; package: 'PetitAnalyzer' with: [ spec requires: #('PetitTests' ). ]; package: 'PetitGui' with: [ spec requires: #('PetitParser' 'Glamour for Petit' ). ]. spec package: 'PrettyPetit'. spec package: 'PetitSmalltalk' with: [ spec requires: #( 'PetitParser' 'PetitTests') ]; package: 'PetitCSV' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitJson' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitMSE' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitManifestMf' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitRegex' with: [ spec requires: #('PetitParser') ]; package: 'PetitSQL' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitXPath' with: [ spec requires: #('PetitParser' 'PetitXml') ]; package: 'PetitXml' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'Factorial-Language' with: [ spec requires: #('PetitParser') ]. spec group: 'Core' with: #('PetitParser' 'PetitAnalyzer' ); group: 'Tests' with: #('PetitTests' 'PetitAnalyzer' ). ]. ! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'DiegoLont 9/2/2013 11:16'! baseline15: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: 'Describing all satellite packages'. spec repository: 'http://source.lukas-renggli.ch/petit'. spec project: 'Glamour for Petit' with: [ spec className: 'ConfigurationOfGlamour'; versionString: #stable; loads: #(Core Morphic); repository: 'http://www.squeaksource.com/Glamour' ]. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: #('PetitParser' ). ]; package: 'PetitAnalyzer' with: [ spec requires: #('PetitTests' ). ]; package: 'PetitGui' with: [ spec requires: #('PetitParser' 'Glamour for Petit' ). ]. spec package: 'PrettyPetit'. spec package: 'PetitSmalltalk' with: [ spec requires: #( 'PetitParser' 'PetitTests') ]; package: 'PetitCSV' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitJson' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitMSE' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitManifestMf' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'PetitRegex' with: [ spec requires: #('PetitParser') ]; package: 'PetitXPath' with: [ spec requires: #('PetitParser' 'PetitXml') ]; package: 'PetitXml' with: [ spec requires: #('PetitParser' 'PetitTests') ]; package: 'Factorial-Language' with: [ spec requires: #('PetitParser') ]. spec group: 'default' with: #('UI' 'Tests'); group: 'Core' with: #('PetitParser' 'PetitAnalyzer' ); group: 'UI' with: #('Core' 'PetitGui' ); group: 'Tests' with: #('Core' 'PetitTests'). ]. ! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'DiegoLont 09/02/2013 04:58'! baseline16: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Describing all satellite packages. Loads configuration from new repository on SmalltalkHub'. spec repository: 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main'. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: 'PetitParser']; package: 'PetitAnalyzer' with: [ spec requires: 'PetitTests']. spec group: 'Core' with: #( 'PetitParser' 'PetitAnalyzer' ). spec group: 'Tests' with: #( 'PetitTests' 'PetitAnalyzer' ) ]. spec for: #( 'squeakCommon' ) do: [ spec project: 'Glamour' with: [ spec className: 'ConfigurationOfGlamour'; file: 'ConfigurationOfGlamour'; version: #development; loads: #('Core' 'Morphic' 'Roassal'); repository: 'http://www.smalltalkhub.com/mc/Moose/Glamour/main' ]. spec package: 'PetitGui' with: [ spec requires: #('Glamour' 'PetitAnalyzer')]. spec group: 'Gui' with: #( 'PetitGui' ) ]! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'usmanbhatti 3/1/2013 17:03'! default: spec self baseline16: spec.! ! !ConfigurationOfPetitParser methodsFor: 'symbolic versions' stamp: 'DamienCassou 6/19/2013 13:43'! development: spec spec for: #'pharo1.4.x' version: '1.6-baseline'. spec for: #'pharo2.x' version: '1.6-baseline'. spec for: #'pharo3.x' version: '1.6-baseline'.! ! !ConfigurationOfPetitParser methodsFor: 'baselines' stamp: 'AlexandreBergel 12/3/2010 09:12'! minimal: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://source.lukas-renggli.ch/petit'. spec package: 'PetitParser'; package: 'PetitTests' with: [ spec requires: 'PetitParser']; package: 'PetitAnalyzer' with: [ spec requires: 'PetitTests']. spec group: 'Core' with: #( 'PetitParser' 'PetitAnalyzer' ). spec group: 'Tests' with: #( 'PetitTests' 'PetitAnalyzer' ) ]! ! !ConfigurationOfPetitParser methodsFor: 'snapshots' stamp: 'TudorGirba 9/10/2013 08:46'! populateSpec: aSpec with: list "generated by Snapshotcello creates a spec object for the package and the version stored in the list" list do: [:each | aSpec package: each third with: [ aSpec file: (each first copyUpToLast: $. ). aSpec repository: each second ] ]! ! !ConfigurationOfPetitParser methodsFor: 'accessing' stamp: 'tg 4/18/2010 23:50'! project ^ project ifNil: [ | constructor | "Bootstrap Metacello if it is not already loaded" self class ensureMetacello. "Construct Metacello project" constructor := (Smalltalk at: #MetacelloVersionConstructor) on: self. project := constructor project. project]! ! !ConfigurationOfPetitParser methodsFor: 'snapshots' stamp: 'TudorGirba 9/10/2013 08:46'! snapshot1 "generated by Snapshotcello" ^ #( #('ConfigurationOfGlamour-TudorGirba.117.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'ConfigurationOfGlamour' ) #('PetitParser-YuriyTymchuk.232.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitParser' ) #('PetitTests-AndreHora.47.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitTests' ) #('PetitAnalyzer-DiegoLont.46.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitAnalyzer' ) #('ConfigurationOfRoassal-TudorGirba.1186.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'ConfigurationOfRoassal' ) #('CollectionExtensions-TudorGirba.34.mcz' 'http://www.smalltalkhub.com/mc/Moose/CollectionExtensions/main/' 'CollectionExtensions' ) #('Glamour-Announcements-TudorGirba.7.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Announcements' ) #('Glamour-Helpers-TudorGirba.32.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Helpers' ) #('Glamour-Core-AndreiChis.256.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Core' ) #('Glamour-Presentations-AndreiChis.121.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Presentations' ) #('Glamour-Browsers-AndreiChis.101.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Browsers' ) #('Glamour-Morphic-Widgets-TudorGirba.68.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Widgets' ) #('Glamour-Morphic-Renderer-AndreiChis.208.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Renderer' ) #('Glamour-Morphic-Theme-TudorGirba.78.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Theme' ) #('Glamour-Tools-TudorGirba.66.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tools' ) #('Glamour-Examples-TudorGirba.262.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Examples' ) #('Roassal-AlexandreBergel.668.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'Roassal' ) #('RoassalMorphic-AlexandreBergel.146.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalMorphic' ) #('Glamour-Roassal-Presentations-TudorGirba.14.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Roassal-Presentations' ) #('PetitGui-DiegoLont.125.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitGui' ) )! ! !ConfigurationOfPetitParser methodsFor: 'snapshots' stamp: 'TudorGirba 10/24/2013 00:56'! snapshot2 "generated by Snapshotcello" ^ #( #('ConfigurationOfGlamour-TudorGirba.122.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'ConfigurationOfGlamour' ) #('PetitParser-YuriyTymchuk.232.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitParser' ) #('PetitTests-AndreHora.47.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitTests' ) #('PetitAnalyzer-DiegoLont.46.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitAnalyzer' ) #('ConfigurationOfRoassal-AlexandreBergel.1190.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'ConfigurationOfRoassal' ) #('Glamour-Announcements-TudorGirba.7.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Announcements' ) #('Glamour-Helpers-TudorGirba.34.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Helpers' ) #('Glamour-Core-TudorGirba.258.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Core' ) #('Glamour-Presentations-AndreiChis.121.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Presentations' ) #('Glamour-Browsers-DiegoLont.103.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Browsers' ) #('Glamour-Morphic-Widgets-TudorGirba.69.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Widgets' ) #('Glamour-Morphic-Renderer-TudorGirba.211.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Renderer' ) #('Glamour-Morphic-Theme-TudorGirba.79.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Theme' ) #('Roassal-AlexandreBergel.702.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'Roassal' ) #('RoassalMorphic-AlexandreBergel.165.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalMorphic' ) #('RoassalExtras-RobertoMinelli.26.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalExtras' ) #('Glamour-Roassal-Presentations-TudorGirba.15.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Roassal-Presentations' ) #('CollectionExtensions-TudorGirba.34.mcz' 'http://www.smalltalkhub.com/mc/Moose/CollectionExtensions/main/' 'CollectionExtensions' ) #('Glamour-Tools-TudorGirba.66.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tools' ) #('Glamour-Examples-TudorGirba.267.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Examples' ) #('PetitGui-DiegoLont.125.mcz' 'http://www.smalltalkhub.com/mc/Moose/PetitParser/main/' 'PetitGui' ) )! ! !ConfigurationOfPetitParser methodsFor: 'symbolic versions' stamp: 'TudorGirba 10/24/2013 00:56'! stable: spec spec for: #'common' version: '1.6'. spec for: #'pharo1.3.x' version: '1.5'. spec for: #'pharo2.x' version: '1.8-snapshot'. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'AlexandreBergel 12/10/2010 18:51'! version10: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: 'First release'. spec author: 'AlexandreBergel'. spec timestamp: '12/6/2010 16:11'. spec project: 'Glamour for Petit' with: '2.0-beta.8'. spec package: 'PetitParser' with: 'PetitParser-lr.208'; package: 'PetitTests' with: 'PetitTests-TudorGirba.24'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.31'; package: 'PetitGui' with: 'PetitGui-TudorGirba.58'.]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'AlexandreBergel 5/16/2011 16:23'! version11: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: 'New version'. spec author: 'AlexandreBergel'. spec timestamp: '2/18/2011 13:30'. spec project: 'Glamour for Petit' with: '2.1'. spec package: 'PetitParser' with: 'PetitParser-lr.216'; package: 'PetitTests' with: 'PetitTests-lr.32'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.37'; package: 'PetitGui' with: 'PetitGui-TudorGirba.65'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'AlexandreBergel 5/16/2011 16:23'! version12: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: 'New version'. spec author: 'AlexandreBergel'. spec timestamp: '2/18/2011 13:56'. spec project: 'Glamour for Petit' with: '2.1'. spec package: 'PetitParser' with: 'PetitParser-lr.216'; package: 'PetitTests' with: 'PetitTests-lr.32'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.37'; package: 'PetitGui' with: 'PetitGui-TudorGirba.65'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'AlexandreBergel 5/16/2011 16:23'! version13: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: ''. spec author: 'AlexandreBergel'. spec timestamp: '5/16/2011 16:23'. spec project: 'Glamour for Petit' with: '2.1'. spec package: 'PetitParser' with: 'PetitParser-lr.216'; package: 'PetitTests' with: 'PetitTests-lr.32'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.37'; package: 'PetitGui' with: 'PetitGui-TudorGirba.65'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'DamienPollet 8/11/2011 19:21'! version14: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: ''. spec author: 'DamienPollet'. spec timestamp: '8/11/2011 14:00'. spec project: 'Glamour for Petit' with: '2.1'. spec package: 'PetitParser' with: 'PetitParser-lr.218'; package: 'PetitTests' with: 'PetitTests-DamienPollet.35'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.39'; package: 'PetitGui' with: 'PetitGui-TudorGirba.65'; package: 'PetitSmalltalk' with: 'PetitSmalltalk-lr.47'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'TudorGirba 3/4/2012 20:22'! version15: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: ''. spec author: 'DamienPollet'. spec timestamp: '8/11/2011 14:00'. spec project: 'Glamour for Petit' with: '2.2'. spec package: 'PetitParser' with: 'PetitParser-lr.228'; package: 'PetitTests' with: 'PetitTests-lr.43'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-lr.39'; package: 'PetitGui' with: 'PetitGui-TudorGirba.90'; package: 'PetitSmalltalk' with: 'PetitSmalltalk-lr.57'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'versions' stamp: 'DiegoLont 9/2/2013 13:21'! version16: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: 'releasing a version of petitparser for moose 4.7 release'. spec author: 'usmanbhatti'. spec timestamp: '3/1/2013 18:01'. spec project: 'Glamour for Petit' with: '2.4'. spec package: 'PetitParser' with: 'PetitParser-YuriyTymchuk.232'; package: 'PetitTests' with: 'PetitTests-AndreHora.47'; package: 'PetitAnalyzer' with: 'PetitAnalyzer-DiegoLont.46'; package: 'PetitGui' with: 'PetitGui-DiegoLont.125'. ]. ! ! !ConfigurationOfPetitParser methodsFor: 'snapshot versions' stamp: 'DiegoLont 9/17/2013 11:12'! version17snapshot: spec "generated by Snapshotcello" spec for: #common do: [ self populateSpec: spec with: self snapshot1. spec group: 'Core' with: #( 'PetitParser' 'PetitAnalyzer' ). spec group: 'Tests' with: #( 'PetitTests' 'PetitAnalyzer' ) ]! ! !ConfigurationOfPetitParser methodsFor: 'snapshot versions' stamp: 'TudorGirba 10/24/2013 00:56'! version18snapshot: spec "generated by Snapshotcello" spec for: #common do: [ self populateSpec: spec with: self snapshot2 ]! ! "ConfigurationOfPetitParser"! !GLMTreeMorphModel commentStamp: 'alain.plantec 9/8/2009 15:22' prior: 0! ClassTree new openOn: Collection ! !GLMMultiValue commentStamp: 'tg 12/19/2009 00:16' prior: 0! GLMMultiValue is helper class that is used in #glamourValue:.! !GLMSystemWindow commentStamp: 'TudorGirba 1/27/2011 22:09' prior: 0! This is the window in which the Glamour browsers are rendered in Morphic.! !ROMorph commentStamp: '' prior: 0! A ROMorph is the unique interface between Roassal and Morphic Instance Variables animationBlock: canvas: elementBeingPointed: eventBeginingDragging: view: animationBlock - xxxxx canvas - xxxxx elementBeingPointed - xxxxx eventBeginingDragging - xxxxx view - xxxxx ! !GLMTabPanelBorder commentStamp: '' prior: 0! Specialized border for TabGroup. Does not draw border beneath the selectd tab and only draws on top.! !GLMContextChanged commentStamp: 'tg 2/20/2010 14:55' prior: 0! A GLMContextChanged is announced by a presentation when an outer port event raises.! !GLMMatchingPresentationsChanged commentStamp: 'tg 2/20/2010 14:56' prior: 0! A GLMMatchingPresentationsChanged is announced by the pane when the presentations that should be displayed change due to changes in the values of the ports of the pane.! !GLMPaneAnnouncement commentStamp: 'TudorGirba 2/4/2011 21:24' prior: 0! These announcements are used by the browser to communicate with the renderer whenever the panes configuration is modified in some way. Instance Variables: pane browser position ! !GLMPresentationUpdated commentStamp: 'tg 2/20/2010 14:54' prior: 0! A GLMPresentationUpdated is announced by the presentation when an update is wanted.! !GLMPresentationsChanged commentStamp: 'tg 2/20/2010 14:57' prior: 0! A GLMPresentationsChanged is announced by the pane when the set of presentations changes.! !GLMTransmissionTriggered commentStamp: '' prior: 0! A GLMTransmissionTriggered is announced by a browser when a transmission brokered by the browser is triggered.! !GLMUITheme commentStamp: 'TudorGirba 1/30/2011 22:51' prior: 0! The theme is developed in the context of the Glamour project, and its goal is to create a look that: - does not look like a specific operating system. In particular, the icons should be operating system agnostic, because, for example, people in Windows are confused by the red, yellow, green buttons of apple. - uses a limited amount of colors and effects. - is fast. self defaultSettings: nil. self beCurrent. ! !GLMWhitespaceTheme commentStamp: '' prior: 0! The theme is developed in the context of the Glamour project, and its goal is to create a look that: - does not look like a specific operating system. - maximizes whitespace. - is fast. PolymorphSystemSettings desktopColor: Color white. self defaultSettings: nil. self beCurrent.! !GLMTextMorphForEditView commentStamp: 'TudorGirba 7/14/2011 09:44' prior: 0! GLMTextMorphForEditView is meant to work with GLMPluggableTextMorph.! !GLMUIThemeIcons commentStamp: 'TudorGirba 1/30/2011 22:49' prior: 0! This class holds a set of icons to be used in the Glamorous UI Theme.! !RORectangleTreeMap commentStamp: '' prior: 0! A RORectangleTreeMap is an extension of Rectangle that adds some useful functionalities for ther ROTreeMapBuilder. Roberto Minelli @ REVEAL, Lugano (CH) roberto.minelli@usi.ch! !PPStream commentStamp: '' prior: 0! A positional stream implementation used for parsing. It overrides some methods for optimization reasons.! !GLMAnnouncer commentStamp: 'TudorGirba 1/23/2011 00:58' prior: 0! This is a specialization of the Announcer. The main added functionality is the ability to suspend the announcements from this announcer.! !GLMAction commentStamp: '' prior: 0! Actions are elements of behavior that are executed upon a keyboard shortcut or other event. Instances of Action are stored and maintained by Presentations. The exact representation is determined by the renderer, but actions can define a keyboard shortcut that should trigger the action or a title, category and position to be able to use the action as a context menu item.! !GLMGenericAction commentStamp: '' prior: 0! This is an action that is supposed to work in any context (e.g., Morphic or Seaside)! !GLMMorphicAction commentStamp: '' prior: 0! A GLMMorphicAction is special GLMAction that is only active when rendering Glamour browsers with Morphic.! !GLMNoBrowser commentStamp: 'TudorGirba 2/4/2011 20:22' prior: 0! A NoBrowser is a browser without behavior and that does not require a container pane. The root pane is always placed in a NoBrowser. Given that it has no behavior, a NoBrowser is a singleton to avoid multiple unnecessary instances.! !GLMPane commentStamp: 'TudorGirba 2/15/2011 11:03' prior: 0! A GLMPane represents the "physical" building block of a browser. A pane is presented using a composite presentation (held in the presentations instance var). It announces: - GLMMatchingPresentationsChanged - GLMPresentationsChanged Instance Variables browser: Browser lastActivePresentation: Presentation name: Symbol ports: Collection of Ports presentations: CompositePresentation! !GLMPort commentStamp: 'tg 12/19/2009 00:15' prior: 0! GLMPort represents the abstract port. Any port has a name. Subclasses can provide further semantics to a port.! !GLMPanePort commentStamp: '' prior: 0! A port that belongs to a pane. Bound ports have a few special characteristics in comparison to their superclass. For one, they don't just assign a value to themselves using #value: but rather generate a transmission that set the value so that the pane can handle the transmission and forward it to other ports if necessary, depending on the policy of the containing browser.! !GLMPresentationBoundPort commentStamp: 'TudorGirba 2/4/2011 20:27' prior: 0! This is a fancy port that enables us to access the value of a port from outside of a browser. It is bound to a presentation in the sense that it asks the presentation dynamically for the pane. In this way, when a presentation is placed (or copied) in another pane, the value will be dynamically looked up. Instance Variables: presentation ! !GLMSimplePort commentStamp: 'TudorGirba 2/4/2011 20:29' prior: 0! GLMSimplePort simply offers a hardcoded value. It is typically used in tests, but it can be useful in special cases when we need to simulate a Port. Instance Variables: value ! !GLMPortEvent commentStamp: 'tg 12/19/2009 00:12' prior: 0! A GLMPortEvent is passed to the parent pane every time a Port changes. Instance Variables oldValue: port: Port transmission: Transmission transmissionContext: TransmissionContext! !GLMPresentation commentStamp: 'DamienCassou 7/19/2011 21:14' prior: 0! A GLMPresentation is the abstract class for the hierarchy of presentations. A presentation specifies how the pane (held in the pane instance variable) is going to be displayed. It typically reads at least the #entity port of a pane and populates at least the #selection port. updateActions holds a collection of GLMUpdateAction that are used to update the presentation via announcements. rawSelectionTransmissions holds a collection of transmission whose origins are this presentation's #rawSelection port. Destinations of this transmissions are on the pane. This collection always contains at least one transmission to the pane's #selection port. To transform the values travelling through this transmission use #send:. To add new transmissions, use #send:as:. Because Glamour has a prototype-based design it relies on copying the presentations before installing them in panes (via transmissions). The parentPrototype instance variable keeps track of the presentation from which the current one was copied. It raises: - GLMContextChanged to let the world know that something has changed in the containing pane. This is typically used by the renderer to update the rendering. - GLMPresentationUpdated to let the world know that the presentations wants to be updated because of reasons other than the pane context changed.! !GLMBrowser commentStamp: 'TudorGirba 2/4/2011 17:50' prior: 0! The Browser is one of the core components in Glamour. It contains panes and transmissions between their ports. These transformations can either be explicitely defined by the user (such as in the Tabulator) or implicitely defined (such as in the Finder). Browsers serve as composition managers. They determine when and under which conditions transmissions should be triggered and how they connect the ports of panes. In return, panes inform the browsers when event occur on their ports so that the browser can make an informed decission on what to do. A Browser is a Presentation which means that it can be nested into other browsers.! !GLMExplicitBrowser commentStamp: 'TudorGirba 2/4/2011 17:50' prior: 0! A GLMExplicitBrowser is a browser that allows the user to explicitly define the panes and the flow of transmissions between them.! !GLMStacker commentStamp: '' prior: 0! A GLMStacker is an explicit browser that allows us to stack panes on top of each other and typically show them as tabs.! !GLMTabulator commentStamp: '' prior: 0! A GLMTabulator is an explicit browser that allows us to place panes in columns and rows.! !GLMImplicitBrowser commentStamp: 'TudorGirba 3/5/2011 21:22' prior: 0! A GLMImplicitBrowser is an abstract implementation of a browser that defines an implicit flow of transmissions. When using implicit browsers, the developer does not have access to the internal transmissions.! !GLMAccumulator commentStamp: 'TudorGirba 4/21/2011 21:20' prior: 0! An GLMAccumulator is an implicit type of browser that has the following behavior: - each input entity has associated a pane without any relationship with the other panes - based on the input entity if there already exists a pane associated, it is selected via GLMPaneSelected - if there isnt a pane, a new pane is created - based on entityToSelect, the associated pane is searched and potentially selected - when a pane is selected in the user interface, the activeEntity is populated with the entity behind the selected pane Input ports: - entity - entityToSelect Output ports: - activeEntity! !GLMExpander commentStamp: 'DamienCassou 7/26/2011 19:10' prior: 0! GLMExpander aims to implement a Hopscotch-like browser. This is similar to a tree where each tree node content is itself a presentation.! !GLMFinder commentStamp: 'TudorGirba 7/9/2011 18:16' prior: 0! A GLMFinder models a browsers that behaves like the Mac Finder: whenever the selection port is set on one pane, a new one is created to the right with the selection as entity. The Finder opens the first pane on the entity. The Finder communicates with the Renderer Input ports: - entity: this is passed to the first pane Output ports: - selection: this port is populated with the value from the last selection port from one of the panes! !GLMWrapper commentStamp: '' prior: 0! The GLMWrapper is a browser that has only one pane and that is typically used as a placeholder. The pane takes only entity as input.! !GLMCompositePresentation commentStamp: 'tg 2/20/2010 14:51' prior: 0! A composite presentation offers means to control the composition of multiple presentations by providing the arrangement of these presentations.! !GLMBrowserWithoutBlocksExample commentStamp: '' prior: 0! self openOn: 42! !GLMExamplesBrowser commentStamp: 'TudorGirba 1/4/2012 08:47' prior: 0! self new browser openOn: GLMBasicExamples! !PPBrowser commentStamp: 'TudorGirba 3/4/2011 18:55' prior: 0! self open! !PPParserBrowser commentStamp: 'TudorGirba 11/25/2012 20:38' prior: 0! self new openOn: PPArithmeticParser! !PPParserInspector commentStamp: 'TudorGirba 12/3/2011 17:25' prior: 0! This browser expects an instance of PPParser in the #entity port. self openOn: PPArithmeticParser new.! !GLMDynamicPresentation commentStamp: 'tg 9/20/2009 14:25' prior: 0! A GLMDynamicPresentation is a presentation that takes the actual presentation from the display value. Like this, we can have the block of display return a presentation depending on the input. A usage for this behavior is the Glamorous Editor, which takes the text as input and based on this it displays the browser.! !GLMFlexiblePresentation commentStamp: '' prior: 0! A presentation that flexibly changes it behavior depending on the current entity. If the entity is a collection, this class renders as a ListPresentation, otherwise as a TextPresentation.! !GLMFormatedPresentation commentStamp: 'TudorGirba 2/4/2011 17:56' prior: 0! GLMFormatedPresentation is an abstract presentation that offers a format block to be used for formatting the rendering of the presentation. The renderer will use the formatDisplayValueOf: method.! !GLMDiffPresentation commentStamp: 'TudorGirba 7/14/2011 11:49' prior: 0! GLMDiffPresentation is meant to show the difference between two input text objects. The convention is that the transformed entity should provide a collection with two elements.! !GLMListingPresentation commentStamp: 'TudorGirba 2/4/2011 20:41' prior: 0! This is the abstract class for a presentation that is supposed to show a list of elements. Thus, the displayValue should be a list. Instance Variables: tagsBlock searchBlock filterBlock amountToShowBlock allowsMultipleSelection tagsFilterBlock allowsDeselection tagsStyle helpMessage ! !GLMTextPresentation commentStamp: 'TudorGirba 3/5/2011 21:22' prior: 0! A presentation displaying text. Instance Variables: selectedTextBlock highlightSmalltalk highlightSmalltalkContext textBlock ! !GLMMorphPresentation commentStamp: 'TudorGirba 2/4/2011 21:13' prior: 0! This presentation offers a means to embed a Morph. It makes sense only for the Morph Renderer.! !GLMTransmission commentStamp: 'DamienCassou 7/19/2011 16:53' prior: 0! A GLMTransmission models the connection between multiple origin ports and one destination port. Whenever an origin port changes the value, the corresponding transmissions are triggered by the browser. The result of triggering a transmission is the setting of the value in the destination port. The transmissionStrategy can add further different semantics to this behavior. A transmission takes place in a context. The context is started every time a new value is set from outside. Afterwards, the context is preserved internally. This is important for braking possible loops of transmission propagation. There are two kind of origins for a transmission, active and passive ones. A change of value in an active origin will trigger the transmissions originating from it. A change of value in a passive origin will not trigger the transmission. However, a value in a passive origin is still part of the transmission value.! !ROAnnouncer commentStamp: '' prior: 0! A ROAnnouncer is an object that receive and emit events. Each roassal element has an roannouncer. ! !PPScriptingTest commentStamp: '' prior: 0! These are some simple demo-scripts of parser combinators for the compiler construction course. http://www.iam.unibe.ch/~scg/Teaching/CC/index.html! !ROAllConnectedNodeDraggableTest commentStamp: '' prior: 0! A ROAllConnectedNodeDraggableTest is a test class for testing the behavior of ROAllConnectedNodeDraggable! !ROAllRecursivelyConnectedNodeDraggableTest commentStamp: '' prior: 0! A ROAllRecursivelyConnectedNodeDraggableTest is a test class for testing the behavior of ROAllRecursivelyConnectedNodeDraggable! !ROAnimatedResizingTest commentStamp: '' prior: 0! A ROAnimatedResizingTest is a test class for testing the behavior of ROAnimatedResizing! !ROContainerCallbackTest commentStamp: '' prior: 0! A ROContainerCallbackTest is a test class for testing the behavior of ROContainerCallback! !ROElementTranslatedTest commentStamp: '' prior: 0! A ROElementTranslatedTest is a test class for testing the behavior of ROElementTranslated! !RORectangleTreeMapTest commentStamp: '' prior: 0! A RORectangleTreeMapTest is a test class for testing the behavior of RORectangleTreeMap! !ROResizeTest commentStamp: '' prior: 0! A ROResizeTest is a test class for testing the behavior of ROResize! !ROBSplineLineTest commentStamp: '' prior: 0! A ROBSplineLineTest is a test class for testing the behavior of ROBSplineLine! !ROBlinkTest commentStamp: '' prior: 0! A ROBlinkTest is a test class for testing the behavior of ROBlink! !ROColorAlphaFadingTest commentStamp: '' prior: 0! A ROColorAlphaFadingTest is a test class for testing the behavior of ROColorAlphaFading! !ROLinearMoveTest commentStamp: '' prior: 0! A ROLinearMoveTest is a test class for testing the behavior of ROLinearMove! !ROMondrianViewBuilderTest commentStamp: '' prior: 0! A ROMondrianViewBuilderTest is a test class for testing the behavior of ROMondrianViewBuilder! !ROTriangleTest commentStamp: '' prior: 0! A ROTriangleTest is a test class for testing the behavior of ROTriangle! !ROWiggleTest commentStamp: '' prior: 0! A ROWiggleTest is a test class for testing the behavior of ROWiggle! !GLMWatcherWindow commentStamp: '' prior: 0! This morph is used as support for the watcher (quick preview) behavior. GLMWatcherWindow uniqueInstance openInWorld. GLMWatcherWindow reset.! !ConfigurationOfGlamour commentStamp: 'TudorGirba 1/3/2012 13:23' prior: 0! ConfigurationOfGlamour loadDevelopment! !GLMParameterizableExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:50' prior: 0! This is an abstract class that provides the infrastructure for an example browser. It is meant to work with classes that hold examples in methods.! !GLMEyeSeeExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:44' prior: 0! self new openOn: ESExamples! !GLMRoassalExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:47' prior: 0! self new openOn: ROMondrianExample! !GLMScriptingEditorTemplate commentStamp: 'TudorGirba 12/28/2011 23:33' prior: 0! GLMScriptingEditorTemplate offers a simple template for building scripting editors. It offers basically three panes: - one for the script - one for the set of input variables - one for the preview once you accept the script A typical case is provided by the GLMMondrianEasel. To open any of the subclasses, you need to provide an array of associations whose values represent the names of a variables and the values are the objects referred by these variables. These variables can then be used in the code of the script.! !GLMEditor commentStamp: 'TudorGirba 12/28/2011 23:33' prior: 0! This is an Glamour-based editor for Glamour browsers. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMEyeSeeEditor commentStamp: 'TudorGirba 12/28/2011 23:34' prior: 0! This browser offers a Glamour-based editor for EyeSee charts. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMMondrianEasel commentStamp: 'TudorGirba 12/28/2011 23:34' prior: 0! This browser offers a Glamour-based MondrianEasel. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMRoassalEasel commentStamp: '' prior: 0! This browser offers a Glamour-based Roassal Easel. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMCompositeArrangement commentStamp: 'tg 1/6/2010 23:12' prior: 0! This is a strategy to capture the intended arrangement of multiple presentations of a composite presentation. The subclasses define the actual arrangement.! !GLMCondition commentStamp: 'TudorGirba 7/14/2011 10:53' prior: 0! GLMCondition is the abstract class for defininf a boolean condition applied on some input arguments. It is meant to be subclassed.! !GLMAllNotNilCondition commentStamp: '' prior: 0! Used to test if all defined arguments of a condition or not nil. We use this as a default condition for presentations. Usually, you will want to define a condition as a block such as '[ :class :category | (class isKindOf: Class) and: [ category isKindOf: Symbol ] ]' (or something like that) but sometimes you just want to make sure that all arguments are defined. Since we do not know the number of arguments in advance, we use this class to interpret #glamourValueWithArgs: and return true if all arguments are not nil.! !GLMDoItContext commentStamp: 'TudorGirba 8/24/2011 23:50' prior: 0! This offers support for a do it context. Example: context := GLMContext withAll: {#a -> 1 . #b -> 2}. Compiler new evaluate: 'a + b' in: context to: context! !GLMBasicExamples commentStamp: '' prior: 0! self open! !GLMOtherExamples commentStamp: '' prior: 0! self open! !GLMLogger commentStamp: 'tg 5/24/2010 17:00' prior: 0! This is the abstract class for the Glamour loggers. These classes are typically used for debugging hte highly dynamic Glamour model.! !GLMMemoryLogger commentStamp: 'tg 5/24/2010 16:59' prior: 0! This class stores the announcements raised by the Glamour model in an ordered collection. The collection can later be used for debugging.! !GLMNullLogger commentStamp: 'tg 5/24/2010 16:58' prior: 0! This class simply implements the Null pattern.! !GLMMorphicWidgetRenderer commentStamp: '' prior: 0! This is a helper class that is supposed to be subclassed for each rendering logic of a specific morph. For example, there will be a TreeRenderer, a TextRenderer etc! !GLMMorphicWatcherRenderer commentStamp: '' prior: 0! This is a special widget renderer in that it will get to render multiple panes on the same container morph provided by a unique instance of the GLMWatcherWindow.! !GLMMorphicWindowRenderer commentStamp: '' prior: 0! This renders the top most browser or composite presentation in a window.! !GLMPortIdentifier commentStamp: '' prior: 0! This class is a simple data structure to be used for identifying a port by name.! !GLMPortReference commentStamp: 'tg 1/5/2010 22:18' prior: 0! A PortReference is used in Transmissions to bahavior that is specific to a Transmission instance.! !GLMOriginPortReference commentStamp: '' prior: 0! Used by BundleTransmission to annotate its originating ports whether they are active or passive. When a BundleTransmission consideres a port as active, the browser will trigger it when the corresponding port changes.! !GLMPortUpdater commentStamp: '' prior: 0! This is a strategy that populates a portSymbol with the result of evaluating valueBlock.! !GLMRenderer commentStamp: 'tg 9/20/2009 12:43' prior: 0! A GLMRenderer is the abstract class for the renderer hierarchy. This should be subclassed for each rendering platform (e.g. Morphic)! !GLMMorphicRenderer commentStamp: 'tg 4/1/2010 07:11' prior: 0! This is the class responsible for the binding to Morphic. | browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [:a | a list.]. browser transmit to: #two; from: #one; andShow: [ :a | a text.]. browser openOn: #(a b c d)! !GLMSTBrowserExample commentStamp: 'TudorGirba 1/4/2012 08:21' prior: 0! self new browser openOn: (RBBrowserEnvironment new forPackageNames: #('Glamour'))! !GLMTableColumn commentStamp: 'TudorGirba 2/4/2011 21:14' prior: 0! This is a helper class for the TablePresentation. Instance Variables: title computation ! !GLMTransmissionContext commentStamp: 'DamienCassou 7/9/2011 23:44' prior: 0! This class models the context in which a set of transmissions take place. In essence, it records all ports that were reached after an outside event. That is necessary for ensuring that transmissions do not get propagated forever. When the first transmission is triggered, a context is created and this context will then store all ports that any subsequent transmission touches. This info is used to break possible cycles Instance Variables ports: Collection of Ports! !GLMTransmissionStrategy commentStamp: 'tg 2/20/2010 14:45' prior: 0! The classes from this hierarchy define strategies for what should happen after the value have been set to the destination port.! !GLMNoStrategy commentStamp: 'tg 2/20/2010 14:53' prior: 0! This is the default strategy that does nothing (an implementation of the Null pattern)! !GLMPresentStrategy commentStamp: 'DamienCassou 7/9/2011 23:02' prior: 0! The abstract strategy that deals with setting of presentations on the pane of the destination port.! !GLMPresentIfNoneStrategy commentStamp: 'tg 2/20/2010 14:52' prior: 0! This strategy sets presentations only if none exits in the pane of the destination port.! !GLMReplacePresentationsStrategy commentStamp: 'tg 2/20/2010 14:52' prior: 0! This strategy replaces the presentations from the pane of the destination port.! !GLMUIThemeExtraIcons commentStamp: 'TudorGirba 1/30/2011 22:55' prior: 0! This class offers a number of extra icons that work with the Glamorous Theme.! !GLMUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:30' prior: 0! GLMUpdateAction is used for controlling the updating of a presentation when an announcement. is sent by the announcerObjects. Instance Variables: condition presentation announcement announcerObjects <(Collection of: Objects)> transformation ! !GLMMultipleUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:31' prior: 0! This class simply specifies that the updating announcement could come from any of the objects in the announcer objects collection.! !GLMSingleUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:31' prior: 0! This class specifies that the updating announcement should come only from the single announcer object.! !PPFailure commentStamp: '' prior: 0! The failure object in PetitParser. It is the only class that responds to #isPetitFailure with true. It contains an error message and a position of the occurrence of the failure. Instance Variables: message The error message of this failure. position The position of this failure in the input stream. ! !PPMemento commentStamp: '' prior: 0! PPMemento is an internal class used by PPMemoizedParser to cache results and detect left-recursive calls. Instance Variables: result The cached result. count The number of recursive cycles followed. position The position of the cached result in the input stream.! !PPParser commentStamp: '' prior: 0! An abstract parser for all parsers in PetitParser. Subclasses implement #parseOn: to perform the actual recursive-descent parsing. All parsers support a variety of methods to perform an actual parse, see the methods in the #parsing protocol. Parsers are combined with a series of operators that can be found in the #operations protocol. Instance Variables: properties Stores additional state in the parser object.! !PPDelegateParser commentStamp: '' prior: 0! A parser that delegates to another parser. Instance Variables: parser The parser to delegate to.! !PPActionParser commentStamp: '' prior: 0! A parser that performs an action block with the successful parse result of the delegate. Instance Variables: block The action block to be executed. ! !PPWrappingParser commentStamp: '' prior: 0! A parser that performs an action block upon activation with the stream and a continuation block.! !PPAndParser commentStamp: 'TudorGirba 2/27/2011 22:22' prior: 0! The and-predicate, a parser that succeeds whenever its delegate does, but does not consume the input stream [Parr 1994, 1995].! !PPCompositeParser commentStamp: 'lr 12/4/2009 18:38' prior: 0! A PPCompositeParser is composed parser built from various primitive parsers. Every production in the receiver is specified as a method that returns its parser. Note that every production requires an instance variable of the same name, otherwise the production is not cached and cannot be used in recursive grammars. Productions should refer to each other by reading the respective inst-var. Note: these inst-vars are typically not written, as the assignment happens in the initialize method using reflection. The start production is defined in the method start. It is aliased to the inst-var parser defined in the superclass of PPCompositeParser.! !PPEndOfInputParser commentStamp: 'lr 4/18/2008 13:46' prior: 0! A parser that succeeds only at the end of the input stream.! !PPExpressionParser commentStamp: '' prior: 0! A PPExpressionParser is a parser to conveniently define an expression grammar with prefix, postfix, and left- and right-associative infix operators. The following code initializes a parser for arithmetic expressions. First we instantiate an expression parser, a simple parser for expressions in parenthesis and a simple parser for integer numbers. expression := PPExpressionParser new. parens := $( asParser token trim , expression , $) asParser token trim ==> [ :nodes | nodes second ]. integer := #digit asParser plus token trim ==> [ :token | token value asInteger ]. Then we define on what term the expression grammar is built on: expression term: parens / integer. Finally we define the operator-groups in descending precedence. Note, that the action blocks receive both, the terms and the parsed operator in the order they appear in the parsed input. expression group: [ :g | g prefix: $- asParser token trim do: [ :op :a | a negated ] ]; group: [ :g | g postfix: '++' asParser token trim do: [ :a :op | a + 1 ]. g postfix: '--' asParser token trim do: [ :a :op | a - 1 ] ]; group: [ :g | g right: $^ asParser token trim do: [ :a :op :b | a raisedTo: b ] ]; group: [ :g | g left: $* asParser token trim do: [ :a :op :b | a * b ]. g left: $/ asParser token trim do: [ :a :op :b | a / b ] ]; group: [ :g | g left: $+ asParser token trim do: [ :a :op :b | a + b ]. g left: $- asParser token trim do: [ :a :op :b | a - b ] ]. After evaluating the above code the 'expression' is an efficient parser that evaluates examples like: expression parse: '-8++'. expression parse: '1+2*3'. expression parse: '1*2+3'. expression parse: '(1+2)*3'. expression parse: '8/4/2'. expression parse: '8/(4/2)'. expression parse: '2^2^3'. expression parse: '(2^2)^3'. Instance Variables: operators The operators defined in the current group.! !PPFlattenParser commentStamp: 'lr 11/22/2009 13:09' prior: 0! A parser that answers a flat copy of the range my delegate parses.! !PPTokenParser commentStamp: 'lr 2/25/2013 23:31' prior: 0! A parser that answers a token with the value of my delegate parses. Instance Variables: tokenClass The token sub-class to be used.! !PPMemoizedParser commentStamp: '' prior: 0! A memoized parser, for refraining redundant computations. Instance Variables: stream The stream of the associated memento objects. buffer The buffer of memento objects. ! !PPNotParser commentStamp: '' prior: 0! The not-predicate, a parser that succeeds whenever its delegate does not, but consumes no input [Parr 1994, 1995].! !PPOptionalParser commentStamp: 'lr 4/3/2011 14:46' prior: 0! A parser that optionally parsers its delegate, or answers nil.! !PPRepeatingParser commentStamp: 'lr 4/3/2011 14:45' prior: 0! An abstract parser that repeatedly parses between 'min' and 'max' instances of its delegate. The default configuration parses an infinite number of elements, as 'min' is set to 0 and 'max' to infinity (SmallInteger maxVal). Instance Variables: min The minimum number of repetitions. max The maximum number of repetitions.! !PPLimitedRepeatingParser commentStamp: 'lr 4/3/2011 14:37' prior: 0! An abstract parser that repeatedly parses between 'min' and 'max' instances of my delegate and that requires the input to be completed with a specified parser 'limit'. Subclasses provide repeating behavior as typically seen in regular expression implementations (non-blind). Instance Variables: limit The parser to complete the input with.! !PPGreedyRepeatingParser commentStamp: 'lr 4/3/2011 15:08' prior: 0! A greedy repeating parser, commonly seen in regular expression implementations. It aggressively consumes as much input as possible and then backtracks to meet the 'limit' condition. This class essentially implements the iterative version of the following recursive parser composition: | parser | parser := PPChoiceParser new. parser setParsers: (Array with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ]) with: (limit and ==> [ :each | OrderedCollection new ])). ^ parser ==> [ :rest | rest asArray ]! !PPLazyRepeatingParser commentStamp: 'lr 4/3/2011 15:08' prior: 0! A lazy repeating parser, commonly seen in regular expression implementations. It limits its consumption to meet the 'limit' condition as early as possible. This class essentially implements the iterative version of the following recursive parser composition: | parser | parser := PPChoiceParser new. parser setParsers: (Array with: (limit and ==> [ :each | OrderedCollection new ]) with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ])). ^ parser ==> [ :rest | rest asArray ]! !PPPossessiveRepeatingParser commentStamp: 'lr 4/3/2011 14:35' prior: 0! The default repeating parser with standard PEG semantics (i.e. possessive, blind, eager).! !PPTrimmingParser commentStamp: 'lr 4/6/2010 19:27' prior: 0! A parser that silently consumes spaces before and after the delegate parser.! !PPEpsilonParser commentStamp: 'lr 5/15/2008 15:09' prior: 0! A parser that consumes nothing and always succeeds.! !PPFailingParser commentStamp: '' prior: 0! A parser that consumes nothing and always fails. Instance Variables: message The failure message.! !PPListParser commentStamp: '' prior: 0! Abstract parser that parses a list of things in some way (to be specified by the subclasses). Instance Variables: parsers A sequence of other parsers to delegate to.! !PPChoiceParser commentStamp: 'lr 4/18/2008 15:35' prior: 0! A parser that uses the first parser that succeeds.! !PPSequenceParser commentStamp: 'lr 4/18/2008 15:34' prior: 0! A parser that parses a sequence of parsers.! !PPLiteralParser commentStamp: '' prior: 0! Abstract literal parser that parses some kind of literal type (to be specified by subclasses). Instance Variables: literal The literal object to be parsed. message The error message to be generated. ! !PPLiteralObjectParser commentStamp: '' prior: 0! A parser that accepts a single literal object, such as a character. This is the same as the predicate parser 'PPPredicateParser expect: literal' but slightly more efficient.! !PPLiteralSequenceParser commentStamp: 'lr 12/4/2009 18:39' prior: 0! A parser accepts a sequence of literal objects, such as a String. This is an optimization to avoid having to compose longer sequences from PPSequenceParser.! !PPPattern commentStamp: '' prior: 0! PPPattern is meta-parser that is solely used to match other types of parsers. It cannot be used for actually parsing something. The constructor method determines what can be matched.! !PPListPattern commentStamp: '' prior: 0! PPListPattern that is used to match any number of parsers. As its superclass, it cannot be used for actually parsing something.! !PPPluggableParser commentStamp: '' prior: 0! A pluggable parser that passes the parser stream into a block. This enables users to perform manual parsing or to embed other parser frameworks into PetitParser. Instance Variables: block The pluggable one-argument block. ! !PPPredicateParser commentStamp: '' prior: 0! An abstract parser that accepts if a given predicate holds. Instance Variables: predicate The block testing for the predicate. predicateMessage The error message of the predicate. negated The block testing for the negation of the predicate. negatedMessage The error message of the negated predicate.! !PPPredicateObjectParser commentStamp: '' prior: 0! A parser that accepts if a given predicate on one element of the input sequence holds.! !PPPredicateSequenceParser commentStamp: '' prior: 0! A parser that accepts if a given predicate on an arbitrary number of elements of the input sequence holds. Instance Variables: size The number of elements to consume.! !PPUnresolvedParser commentStamp: 'lr 11/28/2009 18:50' prior: 0! This is a temporary placeholder or forward reference to a parser that has not been defined yet. If everything goes well it will eventually be replaced with the real parser instance.! !PPParserDebuggerResult commentStamp: 'TudorGirba 3/8/2011 10:03' prior: 0! This class is meant to be used as a model for running a parser over a given stream. You create it via parse:with: class side method. For example: self parse: '1 + 2' with: PPArithmeticParser new. Instance Variables: parser result children parent ! !PPProcessor commentStamp: '' prior: 0! PPProcessor is an abstract superclass to PPRewriter and PPSearcher. It implements common functionality to search and transform grammars. The implementation of these matching algorithms is inspired from the refactoring engine by Don Roberts and John Brant. Contrary to the original implementation that worked on syntax trees, this implementation was generalized and works on possibly cyclic search patterns and grammar graphs. Instance Variables: searches The rules to be processed. context The current search context.! !PPRewriter commentStamp: '' prior: 0! PPRewriter walks over a grammar graph and transforms its parsers. If the grammar is modified, #hasChanged returns true. Instance Variables: changed Indicates if the last operation has changed anything.! !PPSearcher commentStamp: '' prior: 0! PPSearcher walks over a grammar specification and matches its parsers against the patterns using #match:inContext:. Instance Variables: answer The answer propagated between matches.! !PPRule commentStamp: '' prior: 0! PPRule is the abstract superclass of all of the grammar search rules. A rule is the first class representation of a particular pattern to search for. The owner of the rule is the algorithms that actually executes the search. This arrangement allows multiple searches to be conducted by a single processor. Instance Variables: owner The processor that is actually performing the search. search The parse pattern to be searched. ! !PPReplaceRule commentStamp: '' prior: 0! PPReplaceRule is the abstract superclass of all of the transforming rules. The rules change the grammar by replacing the node that matches the rule. Subclasses implement different strategies for this replacement. Instance Variables: verificationBlock Is evaluated with the matching parser and allows for further verification of a match.! !PPBlockReplaceRule commentStamp: '' prior: 0! PPBlockReplaceRule replaces the matching node by the result of evaluating replaceBlock. This allows arbitrary computation to come up with a replacement. Instance Variables: replaceBlock The block that returns the parer to replace to matching parser with. ! !PPParserReplaceRule commentStamp: '' prior: 0! PPParserReplaceRule replaces a matched grammar with another grammar, which may include patterns from the matching grammar. Instance Variables: replaceParser The parser to replace the matched parser with.! !PPSearchRule commentStamp: '' prior: 0! PPSearchRule is a rule that simply searches for matches to the rule. Every time a match is found, answerBlock is evaluated with the parser that matches and the current answer. This two-argument approach allows a collection to be formed from all of the matches, like with #inject:into:. Instance Variables: answerBlock Block to evaluate with the matching node and the current answer. ! !PPTextHighlighter commentStamp: '' prior: 0! This is a utility class for creating a highlighted text. For this we need: - a parser: PPParser - an attributeMapper Here is a template to use it: PPTextHighlighter new parser: YourParser new; color: 'tokenName1' with: Color blue; color: 'tokenName2' with: Color gray; highlight: string.! !PPToken commentStamp: 'lr 2/25/2013 23:34' prior: 0! PPToken represents a parsed part of the input stream. Contrary to a simple String it remembers where it came from, the original collection, its start and stop position and its parse value. Instance Variables: collection The collection this token comes from. start The start position in the collection. stop The stop position in the collection. value The parse result.! !ROResize commentStamp: '' prior: 0! A ROResize is a general utility class to perform various operations regarding resizing! !ROExample commentStamp: '' prior: 0! A ROExample contains a list of example of Roassal. It does not contains examples on the builder. ! !ROMondrianExample commentStamp: '' prior: 0! Example for the Mondrian builder! !ROObject commentStamp: '' prior: 0! A ROObject is the root of the roassal class hierarchy. The idea to have ROObject is to have an empty initialize and a new on the class side that calls the initialize. This class is particuarly useful in VisualWorks since Object does not has an initialize! !ROAbstractAnimationMergeStrategy commentStamp: '' prior: 0! A ROAbstractAnimationMergeStrategy is a hierarchy of merging strategy for animation. Each animation has a merging strategy. ! !ROAnimationAppend commentStamp: '' prior: 0! A ROAbstractAnimationAppend means that an animation is simply added to the queue kept in the view. This is the default strategy! !ROAnimationExclusive commentStamp: '' prior: 0! A ROAnimationExclusive replaces all other animation for the element! !ROAbstractCanvas commentStamp: 'AlexandreBergel 8/19/2012 13:01' prior: 0! A ROAbstractCanvas is the abstract class of the canvases. In the core of Roassal, it has only one subclass, RONullCanvas. The platform package should subclass ROAbstractCanvas. Instance Variables camera: canvas: extent: camera - xxxxx canvas - xxxxx extent - xxxxx ! !RONullCanvas commentStamp: '' prior: 0! A RONullCanvas is a null canvas. Useful when testing.! !ROTracingCanvas commentStamp: '' prior: 0! A ROTracingCanvas records all the drawing operations. It is essentially used by the test Instance Variables trace: trace - list of drawing operations performed on the canvas! !ROAbstractResizeStrategy commentStamp: 'AlexandreBergel 3/2/2012 19:40' prior: 0! This hierarchy defines how a parent should behave when a child is resized.! !ROExtensibleParent commentStamp: 'AlexandreBergel 3/2/2012 19:41' prior: 0! The parent get expended! !ROFixedSizedParent commentStamp: '' prior: 0! The size of the parent is fixed. Inner nodes cannot escape the outter element when they are dragged away.! !ROPermissiveParent commentStamp: '' prior: 0! A ROPermissiveParent is a fixed size of the parent, but does not constraint inner nodes to escape the outter node. This strategy is useful when we temporarily need to add many inner nodes without having to go through all the constraints (e.g., with the Mondrian builder or in the tree map layout)! !ROShrinkingParent commentStamp: '' prior: 0! A ROShrinkingParent is the minimum it can have according to the children it has! !ROCamera commentStamp: 'AlexandreBergel 11/14/2012 13:41' prior: 0! ROCamera represents the notion of camera. A camera is the point of view from which a view object is actually viewed. The direction of the camera is always perpendicular to the view. A camera has an altitude. Varying the altitude simulate the zooming facility of Roassal. A view is always associated to a camera. Instance Variables: position Position of the camera angle Angle of aperture realExtent The far extent. extent What we are seeing windowSize The size of the window in which I am displayed! !ROView commentStamp: 'AlexandreBergel 3/6/2013 11:56' prior: 0! ROView is the main container of all Roassal objects. A view contains elements, typically instances of ROElement and ROEdges. It has also a camera that indicates what is currently visible. A view also contains animations that are currently operating. A view has a title, which is used when displayed in a window. ROView is an essential class. elementsToRender is the list of elements that are displayed. It contains a sorted collection of associations. Each association has a number of a key, and a collection of elements as a value. The key number corresponds to the zIndex. Elements with a low zIndex are displayed first. Instance Variables: camera eventHandler title backgroundColor animations <(Collection of: ROAnimation)> elementsToRender zOrdering Class Instance Variables: nullView ! !RODummyNode commentStamp: '' prior: 0! A RODummyNode is used by the sugiyama layout! !ROEaselMorphic commentStamp: 'AlexandreBergel 8/21/2012 11:05' prior: 0! A ROEaselMorphic describes the Pharo version of the easel. To create an icon: ThemeIcons createIconMethodsFromFile: 'ObjectProfileLogo' directory: '/Users/alexandrebergel/Documents/ObjectProfile/Logos/' ! !ROFontOrganizer commentStamp: '' prior: 0! Abstract class that tells about what a font looks like! !ROGraphTransformation commentStamp: '' prior: 0! A ROGraphTransformation performs some graph transformation. Really handing when you wish to transform an edge-based graph to a nesting-based one.! !ROIdentityMatrix commentStamp: '' prior: 0! A ROIdentityMatrix is essentially used by the sugiyama tree layout! !ROLinearMove commentStamp: 'AlexandreBergel 11/28/2011 10:50' prior: 0! ROLinearMove moves an element in a number of cycles. Example of usage: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | view el | view := ROView new. el := ROElement sprite. view add: el. view on: ROMouseLeftClick do: [ :event | ROLinearMove new nbCycles: 180; for: el until: event position. ]. view open. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=! !RONopAnimation commentStamp: 'AlexandreBergel 12/1/2012 15:49' prior: 0! RONopAnimation is a do nothing animation. Useful to simulate a pause between two animations! !ROTranslation commentStamp: 'VanessaPena 8/26/2012 09:44' prior: 0! A ROFunctionMove is just a test, is not a complete interaction yet :) ! !ROGrowable commentStamp: '' prior: 0! A ROGrowable makes the object grow when clicking on it. ! !ROLightlyHighlightable commentStamp: '' prior: 0! A ROLightlyHighlightable is a decorator that highlights the element when the mouse is over it.! !ROLayout commentStamp: '' prior: 0! A ROLayout is the superclass of all. Instance Variables affectedNodes: currentIteraction: eventHandler: maxInterations: translator: affectedNodes - xxxxx currentIteraction - xxxxx eventHandler - xxxxx maxInterations - xxxxx translator - xxxxx ! !ROCellLayout commentStamp: '' prior: 0! A ROCellLayout is like ROGridLayout. Elements of each column are centered along the same vertical line. And elements of each row are centered along the same horizontal line. Instance Variables inCellPosition: inCellPosition - Object which computes position of each element inside a cell. The cell is the space allocated for an element. Its height is maximum of heights of elements on the row. Its width is maximum of widths of elements on the column. By default elements are in the middle of their cell.! !ROGridLayout commentStamp: '' prior: 0! A ROGridLayout places elements as a grid. Instance Variables gapSize: lineItemsCountBlock: gapSize - number of pixels between each elements, horizontally and vertically lineItemsCountBlock - tells the amount of item per line should be used ! !ROHorizontalLineLayout commentStamp: '' prior: 0! A ROHorizontalLineLayout locates all the elements horizontally! !ROVerticalLineLayout commentStamp: '' prior: 0! A ROVerticalLineLayout locates all the elements vertically! !ROHorizontalDominanceTreeLayout commentStamp: 'TudorGirba 10/1/2012 14:06' prior: 0! The dominance tree layout is similar to a regular tree layout, only it poses a stronger condition in the way it places a node: a child is placed under the deepest parent. This layout is for example useful when identifying layers of dependencies. Note: the layout is slower than the tree layout because of the more complex lookup! !RODominanceTreeLayout commentStamp: 'TudorGirba 10/1/2012 14:06' prior: 0! The dominance tree layout is similar to a regular tree layout, only it poses a stronger condition in the way it places a node: a child is placed under the deepest parent. This layout is for example useful when identifying layers of dependencies. Note: the layout is slower than the tree layout because of the more complex lookup! !ROForceBasedLayout commentStamp: '' prior: 0! A ROForceBasedLayout is inspired from the Code of D3. The original d3 version may be found on: http://bl.ocks.org/mbostock/4062045 Layout algorithm inspired by Tim Dwyer and Thomas Jakobsen. Instance Variables alpha: center: charge: charges: fixedNodes: friction: gravity: layoutInitial: length: lengths: nodes: oldPositions: strength: strengths: theta: weights: alpha - xxxxx center - xxxxx charge - xxxxx charges - xxxxx fixedNodes - xxxxx friction - xxxxx gravity - xxxxx layoutInitial - xxxxx length - xxxxx lengths - xxxxx nodes - xxxxx oldPositions - xxxxx strength - xxxxx strengths - xxxxx theta - xxxxx weights - xxxxx ! !RONullLayout commentStamp: '' prior: 0! A RONullLayout does not relocate nodes! !ROScatterplotLayout commentStamp: '' prior: 0! A ROScatterplotLayout plots each element along a X-Y plan Instance Variables horizontalPadding: scaleFactorX: scaleFactorY: scaledToHeight: scaledToWidth: upSideDown: verticalPadding: xBlock: xOffset: yBlock: yOffset: horizontalPadding - xxxxx scaleFactorX - xxxxx scaleFactorY - xxxxx scaledToHeight - xxxxx scaledToWidth - xxxxx upSideDown - xxxxx verticalPadding - xxxxx xBlock - xxxxx xOffset - xxxxx yBlock - xxxxx yOffset - xxxxx ! !ROTreeMapLayout commentStamp: '' prior: 0! A ROTreeMapLayout locates the element as a tree Instance Variables baseZIndex: canvas: inset: interactionBlock: leafBlock: minAreaPerNode: minInset: nodeBlock: rootNodes: splitPercentages: view: weightBlock: weightsCache: baseZIndex - xxxxx canvas - xxxxx inset - xxxxx interactionBlock - xxxxx leafBlock - xxxxx minAreaPerNode - xxxxx minInset - xxxxx nodeBlock - xxxxx rootNodes - xxxxx splitPercentages - xxxxx view - xxxxx weightBlock - xxxxx weightsCache - xxxxx ! !ROLayoutTranslator commentStamp: 'AlexandreBergel 11/28/2011 10:48' prior: 0! ROLayoutTranslator is used by the layout to translate object. Each layout can be parametrized with a translator to produce a visual effect. I am an abstract class! !ROArrow commentStamp: '' prior: 0! A ROArrow represent an arrow. A ROLine may receive arrows. Instance Variables color: offset: size: color - Color of the arrow offset - float that represent where to put the arrow on a line size - size of the arrow ! !ROMondrianFrame commentStamp: '' prior: 0! The Mondrian specific language structures a visualization as a tree (using nodes:forEach:). A ROMondrianFrame is an element of this tree. A frame correspond to what has to be pushed and popup. It also contains funcionalities to lookup nodes. Instance Variables children: elements: interactions: layout: parent: shape: view: children - the list of children frames elements - elements (nodes and edges) that are defined in the frame interactions - xxxxx layout - xxxxx parent - xxxxx shape - xxxxx view - xxxxx ! !ROMondrianInteractionBuilder commentStamp: '' prior: 0! A ROMondrianInteractionBuilder is a builder for interaction. Instance Variables selfDefinedInteraction: shouldHavePopup: viewBuilder: selfDefinedInteraction - xxxxx shouldHavePopup - xxxxx viewBuilder - xxxxx ! !ROMondrianShapeBuilder commentStamp: '' prior: 0! A ROMondrianShapeBuilder is a convenient way to build shapes. Instance Variables color: shape: viewBuilder: color - xxxxx shape - xxxxx viewBuilder - xxxxx ! !ROMondrianViewBuilder commentStamp: '' prior: 0! A ROMondrianViewBuilder models the Mondrian Domain Specific Language. It is mostly compatible with the original Mondrian language (cf., Mondrian paper and website). Instance Variables color: container: height: isLayouted: selfDefinedInteraction: shape: title: width: color - xxxxx container - xxxxx height - xxxxx isLayouted - xxxxx selfDefinedInteraction - xxxxx shape - xxxxx title - xxxxx width - xxxxx ! !RONativeWidgetFactory commentStamp: 'AlexandreBergel 4/23/2012 17:31' prior: 0! RONativeWidgetFactory is useful to create a ROMorph or ROVWVisual, depending on where the platform is running! !ROPlatform commentStamp: '' prior: 0! A ROPlatform enable to have different canvas rending. For example having athens, morphic or cairo. ! !ROShape commentStamp: 'AlexandreBergel 10/15/2012 13:21' prior: 0! A ROShape represents the graphical representation of an element. Decorator has a color, and they are link together. All the accessors in Mondrian's builder operates on the model. However, outside the builder, shapes accepts roassal elements. For example: -=-=-=-=-=-=-=-=-=-=-=-= testIfFillColor | nodes | view shape rectangle if: #odd fillColor: [ :model | model + 1]; if: #even fillColor: [ :model | model + 10]. nodes := view nodes: #(2 3 4 5 6). self assert: (nodes collect: [ :n | (n getShape: ROBox) colorFor: n]) = #(12 4 14 6 16) -=-=-=-=-=-=-=-=-=-=-=-= This piece of code works only in the test since a number is not a color. But it illustrates the point. Then fillColor: is defined as: -=-=-=-=-=-=-=-=-=-=-=-= ROMondrianBuilder>>fillColor: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a symbol or a one-arg block" shape color: [ :element | aBlockOrSymbol roValue: element model ] -=-=-=-=-=-=-=-=-=-=-=-= Something is left ugly, that I cannot easily remove: -=-=-=-=-=-=-=-=-=-=-=-= ROMondrianBuilder>>if: conditionBlock fillColor: colorBlock "If conditionBlock is evaluated at true, then colorBlock is used to set the color of the node. Both conditionBlock and colorBlock are evaluated with the model value of the node." | oldBlockOrValue | oldBlockOrValue := self fillColor ifNil: [ self defaultFillColor ]. ^self fillColor: [ :aModel | (conditionBlock roValue: aModel) ifTrue: [ colorBlock roValue: aModel ] ifFalse: [ "Having to create a new element is rather ugly. Ideally, the oldBlockOrValue has to be 'unwrapped' for the translation" oldBlockOrValue roValue: (ROElement on: aModel) ]]. -=-=-=-=-=-=-=-=-=-=-=-= Instance Variables color: colorCache: next: color - xxxxx colorCache - xxxxx next - xxxxx ! !ROBSplineLine commentStamp: '' prior: 0! A ROBSplineLine is a bspline with control points. This work has been done by Hernan Fierro, at the University of Chile. The work has been inspired from "Hierarchical Edge Bundles" www.win.tue.nl/~dholten/papers/bundles_infovis.pdf‎ alpha - xxxxx cachePoints - xxxxx cpoints - xxxxx customCpoints - xxxxx discoveryFunction - xxxxx knots - xxxxx straightcpoints - xxxxx ! !ROBorder commentStamp: '' prior: 0! A ROBorder defines a border to be added to an element. Instance Variables width: Number width - Width of the border! !ROInnerBorder commentStamp: '' prior: 0! A ROInnerBorder is a specialization of ROBorder which is drawn inside the shape Roberto Minelli @ REVEAL, Lugano (CH) roberto.minelli@usi.ch! !ROBox commentStamp: '' prior: 0! A ROBox draws a box Instance Variables borderColor: borderColorCache: borderWidth: borderWidthCache: borderColor - could be a block, a color or a normalizer. Used to determine the color of the element being painted borderColorCache - used as a cache borderWidth - a block or a number that represent the border width. borderWidthCache - cache of the width ! !ROEllipse commentStamp: '' prior: 0! A ROCircle draws a circle! !RONullShape commentStamp: '' prior: 0! A RONullShape is the terminator of the shape chain. A new element will have an instance of null shape in it.! !ROViewDisplayer commentStamp: 'AlexandreBergel 8/2/2012 18:07' prior: 0! ROViewDisplayer is a shape that is used to display a view. It simply wraps a view into a shape. Instance Variables: view ! !ROTimeOrganizer commentStamp: '' prior: 0! Abstract class for the time passing.! !ROTreeLayerWrapper commentStamp: '' prior: 0! This class holds all figures that belong to the same layer. The class also contains auxiliary information like width and height of the layer. Instance Variables: cachedHeight The height of the layer cachedWidth The widht of the layer figures All figures that belong to this layer ! !ROSortBlock commentStamp: '' prior: 0! A ROSortBlock is used by the Sugiyama layout! !ROTextCache commentStamp: '' prior: 0! A ROTextCache is holder of cached values related to displayed text by ROAbstractLabel. Instance Variables adaptedText: lines: text: adaptedText - string returned by ROAbstractLabel>>textAdaptedFor: lines - collection of lines returned by ROAbstractLabel>>linesOf: text - string returned by ROAbstractLabel>>textFor: ! !ROTreeMapBuilder commentStamp: '' prior: 0! A ROTreeMapBuilder builds a tree map from a collection of elements and a strategy to define the nesting. This builder implements the "Squarified treemap" layout proposed by M. Bruls et al. For more information please read their publication. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.6685 Roberto Minelli @ REVEAL, Lugano (CH) roberto.minelli@usi.ch! !ROTreeMapBuilderExample commentStamp: '' prior: 0! A ROTreeMapBuilderExample contains a list of example of the ROTreeMapBuilder! !GLMPluggableTextMorph commentStamp: 'TudorGirba 7/14/2011 09:45' prior: 0! We subclass the default PluggableTextMorph just to raise the proper announcements when the text or when the selection changes.! !GLMSmalltalkEditor commentStamp: 'TudorGirba 7/14/2011 22:07' prior: 0! GLMSmalltalkEditor is a helper class for Glamour. The only goal for this class is to provide the hook needed to let the morph know when the selection has changed.! !ClassDescription methodsFor: '*roassal-core' stamp: 'AlexandreBergel 7/16/2012 07:56'! numberOfLinesOfCode "Return the amount of lines of code" ^ 5 + ((RONativeExampleUtility current getMethodsForClass: self) inject: 0 into: [:sum :el | sum + el linesOfCode ])! ! !PPParserResource methodsFor: 'accessing' stamp: 'lr 9/15/2010 12:12'! parserAt: aParserClass "Answer a cached instance of aParserClass." ^ parsers at: aParserClass name ifAbsentPut: [ aParserClass new ]! ! !PPParserResource methodsFor: 'running' stamp: 'lr 3/29/2010 15:20'! setUp super setUp. parsers := Dictionary new! ! !GLMTreeMorphModel commentStamp: 'alain.plantec 9/8/2009 15:22' prior: 34261955! ClassTree new openOn: Collection ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/3/2012 00:06'! acceptDroppingMorph: transferMorph event: evt inMorph: listMorph | targetItem | targetItem := (listMorph scrollerSubMorphFromPoint: evt position) complexContents item. ^ self glamourPresentation accept: transferMorph passenger droppedOnItem: targetItem! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 11/25/2010 13:21'! allKeystrokeActions ^ (self glamourPresentation allActions, self glamourPresentation allSelectionActions) select: [ :action | action hasShortcut ]! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'cyrilledelaunay 8/9/2011 13:14'! allMenuActions ^ (self glamourPresentation allSelectionActions select: [:action | action hasTitle ]) ! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 1/18/2010 23:59'! amountToFilterBy ^ nil "amountToFilterBy ifNil: [self glamourPresentation amountToShow]"! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/30/2009 12:05'! amountToFilterBy: aNumber amountToFilterBy := aNumber! ! !GLMTreeMorphModel methodsFor: 'announcements' stamp: 'tg 9/11/2009 00:17'! announce: anAnnouncement self announcer announce: anAnnouncement ! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'EstebanLorenzano 2/13/2012 13:16'! announcer ^glmAnnouncer ifNil: [ glmAnnouncer := GLMAnnouncer new ]! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/13/2009 03:24'! childrenBlock ^ childrenBlock ifNil: [ childrenBlock := self glamourPresentation children isNil ifFalse: [self glamourPresentation children] ifTrue: [OrderedCollection new] ]! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/13/2009 03:28'! childrenBlock: aBlock childrenBlock := aBlock ! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 1/19/2010 00:12'! defaultPageSize ^ defaultPageSize! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 1/18/2010 23:54'! defaultPageSize: anInteger defaultPageSize := anInteger! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/13/2009 03:23'! displayFormat ^ displayFormat ifNil: [displayFormat := self glamourPresentation format]! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/13/2009 03:28'! displayFormat: aBlock displayFormat := aBlock ! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'tg 9/28/2009 00:11'! doSearchOrFilter inputText isEmptyOrNil ifTrue: [ self resetInput ] ifFalse:[ self glamourPresentation allowsFilter ifTrue: [ self executeFilter ] ifFalse: [ self executeSearch ] ]. ! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/3/2012 16:31'! dragEnabled ^ self glamourPresentation allowsItemDrag! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/3/2012 16:28'! dragPassengerFor: item inMorph: listMorph ^ self glamourPresentation transformedDraggedItem: item complexContents item ! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/2/2012 03:07'! dragTransferType ^ #Glamour! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/2/2012 03:07'! dragTransferTypeForMorph: listMorph ^ self dragTransferType! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/3/2012 08:36'! dropEnabled ^ self glamourPresentation isDropTarget! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'TudorGirba 4/4/2012 19:52'! executeFilter self updateRoots! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'tg 8/18/2010 16:38'! executeSearch | newSelection check | newSelection := OrderedCollection new. roots do: [ :each | check := self glamourPresentation searchStrategy value: self inputText value: each item. check ifTrue: [newSelection add: each path]]. newSelection isEmpty ifFalse: [ self selection: (MorphTreeMorphMultipleSelection new selectedNodePathList: newSelection) ] ifTrue: [self selection: nil]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 2/28/2010 21:28'! explicitSelection: anObject "anObject is a domain object, not a Glamour related object" self glamourPresentation isMultiple ifTrue: [ self explicitlySelectMultipleItems: anObject ] ifFalse: [ self explicitlySelectItem: anObject ]! ! !GLMTreeMorphModel methodsFor: 'private selecting' stamp: 'cyrilledelaunay 7/22/2011 12:38'! explicitlySelectItem: anObject (self selectedItem notNil and: [self selectedItem = anObject]) ifTrue: [ ^ self ]. (self selectedItem isNil and: [ anObject isNil ]) ifTrue: [ ^ self ]. anObject isNil ifTrue: [ "we make sure to update the morph list by deselecting everything" self selectNodePath: nil. self selection: nil.]. self roots do: [:eachRoot | eachRoot withContentsDo: [:each | each item = anObject ifTrue: [ each expandParentPath. self selectNodePath: each path. ^ self]]]! ! !GLMTreeMorphModel methodsFor: 'private selecting' stamp: 'tg 1/11/2010 22:02'! explicitlySelectMultipleItems: aCollection | newSelection collection| aCollection isNil ifTrue: [^ self]. collection := aCollection isCollection ifTrue: [aCollection] ifFalse: [aCollection asOrderedCollection ]. (self selection notNil and: [ self selection selectedItemOrItemsOrNil = collection asOrderedCollection ]) ifTrue: [ ^ self ]. newSelection := OrderedCollection new. self roots do: [:eachRoot | eachRoot withContentsDo: [:each | (collection includes: each item) ifTrue: [ newSelection add: each path ]]]. self selectAllNodePaths: newSelection! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/30/2009 01:44'! filteredRoots | filtered | roots ifNil: [ self roots: self glamourPresentation displayValue ]. filtered := roots select: [ :each | each shouldBeDisplayed ]. ^ filtered! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/8/2009 19:46'! glamourPresentation ^ glamourPresentation! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/8/2009 19:46'! glamourPresentation: anObject glamourPresentation := anObject! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/28/2009 01:24'! inputText ^ inputText ifNil: [inputText := '']! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/27/2009 23:05'! inputText: anObject inputText := anObject. self doSearchOrFilter! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/27/2009 16:29'! inputTextEnabled ^ true! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'TudorGirba 8/21/2011 22:58'! keyStroke: aKeyboardEvent from: aTreeMorph | action | action := self allKeystrokeActions detect: [:a | a shortcut = aKeyboardEvent keyCharacter] ifNone: [nil]. action ifNotNil: [ self announce: (GLMKeyStroke action: action) ]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 11/29/2009 16:45'! menu: menu shifted: b "Set up the menu to apply to the receiver's, honoring the #shifted boolean" self selectedNode ifNotNil: [:current | current menu: menu shifted: b]. ^ menu! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/8/2009 21:20'! nodeModelFor: anObject ^ (GLMTreeMorphNodeModel with: anObject) containerTree: self; yourself! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 12/29/2009 02:01'! onDoubleClick self announcer announce: (GLMTreeMorphStrongSelectionChanged new strongSelectionValue: (self selection ifNotNil: [self selection selectedItemOrItemsOrNil]))! ! !GLMTreeMorphModel methodsFor: 'actions' stamp: 'DamienCassou 5/11/2011 08:10'! resetChildrenContents self roots do: [:each | each resetContentsRecursively]! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'TudorGirba 5/22/2013 13:34'! resetInput self updateRoots! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'AlainPlantec 5/28/2012 07:35'! resetTagsToFilterBy tagsToFilterBy := OrderedCollection new. self changed: #rootNodes.! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'EstebanLorenzano 2/13/2012 13:20'! rootNodes ^self roots! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 9/30/2009 01:24'! roots | filtered | roots ifNil: [ self roots: self glamourPresentation displayValue ]. filtered := roots select: [ :each | each shouldBeDisplayed ]. ((self shouldFilterByAmount and: [ self amountToFilterBy < filtered size]) and: [ filtered notEmpty]) ifTrue: [ filtered := filtered first: self amountToFilterBy ]. ^ filtered! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 8/25/2013 22:46'! roots: anObjectOrCollection roots := anObjectOrCollection asOrderedCollection collect: [:each | self nodeModelFor: each ]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 12/29/2009 01:57'! selection: aSelection self selection = aSelection ifTrue: [ ^ self ]. super selection: aSelection. self announcer announce: ( GLMTreeMorphSelectionChanged new selectionValue: (aSelection ifNotNil: [aSelection selectedItemOrItemsOrNil]); selectionPathValue: self selectionPathItems; yourself)! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'tg 11/29/2009 02:37'! selectionPathItems ^ self selectedNodePath isNil ifTrue: [nil] ifFalse: [self selectedNodePath collect: [:each | each item]]! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'tg 9/30/2009 14:01'! shouldFilterByAmount ^ self amountToFilterBy notNil and: [self amountToFilterBy isZero not]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 9/14/2009 23:29'! shouldFilterByTag: aTag ^ self tagsToFilterBy includes: aTag ! ! !GLMTreeMorphModel methodsFor: 'search and filtering' stamp: 'tg 11/13/2009 02:10'! shouldFilterByTextInput ^ self glamourPresentation allowsFilter and: [ self inputText notEmpty ]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'tg 9/13/2009 03:59'! tagsToFilterBy ^ tagsToFilterBy ifNil: [ tagsToFilterBy := OrderedCollection new ]! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'AlainPlantec 5/28/2012 07:35'! toggleAmountToFilterBy self amountToFilterBy notNil ifTrue: [ self amountToFilterBy isZero ifTrue: [ amountToFilterBy := self glamourPresentation amountToShow ] ifFalse: [ amountToFilterBy := 0 ]. self changed: #rootNodes ]! ! !GLMTreeMorphModel methodsFor: 'callbacks' stamp: 'AlainPlantec 5/28/2012 07:35'! toggleFilteringByTag: aTag (self shouldFilterByTag: aTag) ifTrue: [self tagsToFilterBy remove: aTag ] ifFalse: [self tagsToFilterBy add: aTag]. self resetChildrenContents. self changed: #rootNodes! ! !GLMTreeMorphModel methodsFor: 'accessing' stamp: 'AlainPlantec 5/28/2012 07:35'! updateRoots roots := nil. self changed: #rootNodes! ! !GLMTreeMorphModel methodsFor: 'drag and drop' stamp: 'TudorGirba 1/3/2012 13:46'! wantsDroppedMorph: transferMorph event: evt inMorph: listMorph | targetItem targetItemMorph | (transferMorph isKindOf: TransferMorph) ifFalse: [ ^ false ]. transferMorph dragTransferType = self dragTransferType ifFalse: [ ^ false ]. targetItemMorph := (listMorph scrollerSubMorphFromPoint: evt position). targetItemMorph isNil ifFalse: [ targetItem := targetItemMorph complexContents item. ^ self glamourPresentation allow: transferMorph passenger droppedOnItem: targetItem ]. self flag: 'we should ask the whole presentation if it wants to receive a dropped object'. ^ false! ! !GLMTreeMorphModel methodsFor: 'announcements' stamp: 'tg 9/11/2009 00:18'! when: anAnnouncement do: aBlock self announcer when: anAnnouncement do: aBlock ! ! !PPRemoveParserRefactoring class methodsFor: 'instance creation' stamp: 'lr 12/18/2011 15:20'! onClass: aClass ^ self new setClass: aClass; yourself! ! !PPRemoveParserRefactoring methodsFor: 'preconditions' stamp: 'lr 12/18/2011 15:21'! preconditions ^ (self checkCompositeParser: class) & (RBCondition hasSubclasses: class) not! ! !PPRemoveParserRefactoring methodsFor: 'initialization' stamp: 'lr 12/18/2011 15:21'! setClass: aClass class := self classObjectFor: aClass! ! !PPRemoveParserRefactoring methodsFor: 'transforming' stamp: 'lr 12/18/2011 15:22'! transform model removeClass: class! ! !GLMMultiValue commentStamp: 'tg 12/19/2009 00:16' prior: 34262051! GLMMultiValue is helper class that is used in #glamourValue:.! !GLMMultiValue methodsFor: 'testing' stamp: ' 4/5/09 22:18'! asGlamorousArray ^self asArray! ! !GLMMultiValue methodsFor: 'testing' stamp: 'tg 9/9/2009 01:02'! asGlamorousMultiValue ^ self! ! !OrderedCollection methodsFor: '*CollectionExtensions' stamp: 'simon.denier 3/26/2010 16:18'! overlappingPairsCollect: aBlock "Answer the result of evaluating aBlock with all of the overlapping pairs of my elements. Override superclass in order to use addLast:, not at:put:." | retval | retval := self species new: self size - 1. firstIndex to: lastIndex - 1 do: [:index | retval addLast: (aBlock value: (array at: index) value: (array at: index + 1))]. ^retval ! ! !OrderedCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:30'! removeAtIndex: anIndex "Remove the element of the collection at position anIndex. Answer the object removed." | obj | obj := self at: anIndex. self removeIndex: anIndex + firstIndex - 1. ^obj! ! !GLMSystemWindow commentStamp: 'TudorGirba 1/27/2011 22:09' prior: 34262184! This is the window in which the Glamour browsers are rendered in Morphic.! !GLMSystemWindow methodsFor: 'announcement' stamp: 'TudorGirba 2/3/2011 09:06'! allKeystrokeActions ^ self model notNil ifTrue: [ (self model allActions, self model allSelectionActions) select: [ :action | action hasShortcut ]] ifFalse: [#()]! ! !GLMSystemWindow methodsFor: 'open/close' stamp: 'TudorGirba 2/3/2011 09:06'! delete self model notNil ifTrue: [self model unregisterFromAllAnnouncements]. super delete! ! !GLMSystemWindow methodsFor: 'building' stamp: 'TudorGirba 1/27/2011 23:35'! extent: aPoint super extent: aPoint. self fullBounds! ! !GLMSystemWindow methodsFor: 'event handling' stamp: 'TudorGirba 1/31/2011 23:16'! handleKeyStroke: anEvent | action | action := self allKeystrokeActions detect: [:a | anEvent commandKeyPressed and: [ a shortcut = anEvent keyCharacter ]] ifNone: [nil]. action ifNotNil: [ self announcer announce: (GLMKeyStroke action: action) ]! ! !GLMSystemWindow methodsFor: 'initialization' stamp: 'TudorGirba 5/28/2012 00:27'! initialize super initialize. self on: #keyStroke send: #handleKeyStroke: to: self ! ! !GLMSystemWindow methodsFor: 'accessing' stamp: 'TudorGirba 1/27/2011 23:02'! toolbarBox: anObject toolbarBox := anObject. self replacePane: menuBox with: toolbarBox! ! !GLMSystemWindow methodsFor: 'announcement' stamp: 'TudorGirba 1/31/2011 23:08'! when: anAnnouncement do: aBlock ^ self announcer when: anAnnouncement do: aBlock! ! !String methodsFor: '*CollectionExtensions' stamp: 'on 8/24/2008 12:21'! asEnglishPlural "Answer the plural of the receiver. Assumes the receiver is an English noun. For a more comprehensive algorithm please refer to ''An Algorithmic Approach to English Pluralization'' by Damian Conway." self size < 2 ifTrue: [ ^self ]. self asString = 'child' ifTrue: [ ^'children' ]. ((self last == $y) and: [ (self at: self size - 1) isVowel not ]) ifTrue: [ ^self replaceSuffix: 'y' with: 'ies' ]. (self endsWith: 's') ifTrue: [ ^self replaceSuffix: 's' with: 'ses' ]. ^self copyWith: $s.! ! !String methodsFor: '*petitparser-core-converting' stamp: 'lr 11/29/2011 20:48'! asParser "Answer a parser that accepts the receiving string." ^ PPLiteralSequenceParser on: self! ! !String methodsFor: '*CollectionExtensions' stamp: 'simondenier 2/4/2011 23:00'! deepFlattenInto: stream stream nextPut: self! ! !String methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 7/19/2011 19:10'! intervalFromStartLine: aStartLine startColumn: aStartColumn toEndLine: anEndLine endColumn: anEndColumn " Returns an interval spanning between startLine @ startColumn to endLine @ endColumn" | lineIndex intervalStart intervalEnd | lineIndex := 0. intervalStart := 1. intervalEnd := 0. self lineIndicesDo: [ :start :endWithoutDelimiters :end | lineIndex := lineIndex + 1. lineIndex = aStartLine ifTrue: [ intervalStart := start + aStartColumn - 1 ]. lineIndex = anEndLine ifTrue: [ intervalEnd := start + anEndColumn - 1] ]. ^ intervalStart to: intervalEnd! ! !String methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 1/19/2012 13:34'! intervalOfLine: aLineNumber "Answer an interval spanning between the first and the last character of the line from aLineNumber" | lineIndex | lineIndex := 0. self lineIndicesDo: [ :start :endWithoutDelimiters :end | lineIndex := lineIndex + 1. lineIndex = aLineNumber ifTrue: [ ^ start to: end ] ]. ^ 0 to: 0! ! !String methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 1/19/2012 13:34'! intervalOfLineCorrespondingToIndex: anIndex "Answer an interval spanning between the first and the last character of the line containing the given character index" self lineIndicesDo: [:start :endWithoutDelimiters :end | anIndex <= end ifTrue: [^ start to: end]]. ^ 0 to: 0! ! !String methodsFor: '*CollectionExtensions' stamp: 'tg 4/26/2010 21:53'! piecesCutWhere: aBlock "Evaluate testBlock for successive pairs of the receiver elements, breaking the receiver into pieces between elements where the block evaluated to true, and return an OrderedCollection of those pieces." "'A sentence. Another sentence... Yet another sentence.' piecesCutWhere: [:each :next | each = $. and: [next = Character space]]" | pieces | pieces := OrderedCollection new. self piecesCutWhere: aBlock do: [:each | pieces add: each]. ^pieces! ! !String methodsFor: '*CollectionExtensions' stamp: 'tg 6/27/2010 13:08'! piecesCutWhereCamelCase "Breaks apart words written in camel case. It's not simply using piecesCutWhere: because we want to also deal with abbreviations and thus we need to decide based on three characters, not just on two: ('FOOBar') piecesCutWhereCamelCase asArray = #('FOO' 'Bar'). ('FOOBar12AndSomething') piecesCutWhereCamelCase asArray = #('FOO' 'Bar' '12' 'And' 'Something') " | start previous current next pieces | self isEmpty ifTrue: [^self]. start := 1. pieces := OrderedCollection new. 3 to: self size do: [ :index | previous := self at: index - 2. current := self at: index - 1. next := self at: index. ((previous isLowercase and: [current isUppercase]) or: [ (previous isUppercase and: [current isUppercase and: [next isLowercase ]]) or: [ (previous isDigit not and: [current isDigit]) or: [ previous isDigit and: [current isDigit not] ]]]) ifTrue: [ pieces add: (self copyFrom: start to: index - 2). start := index - 1]. ]. pieces addAll: ((self copyFrom: start to: self size) piecesCutWhere: [:a :b | (a isDigit and: [b isDigit not]) or: [a isDigit not and: [b isDigit ]]]). ^pieces! ! !String methodsFor: '*CollectionExtensions' stamp: 'simon.denier 6/9/2009 15:53'! removePrefix: prefix "Remove the given prefix, if present." ^(self beginsWith: prefix) ifTrue: [ self copyFrom: 1 + prefix size to: self size ] ifFalse: [ self ]! ! !String methodsFor: '*CollectionExtensions' stamp: 'tg 6/25/2008 13:04'! removeSuffix: suffix "Remove the given suffix, if present." ^(self endsWith: suffix) ifTrue: [ self copyFrom: 1 to: self size - suffix size ] ifFalse: [ self ]! ! !String methodsFor: '*CollectionExtensions' stamp: 'on 8/24/2008 12:22'! replaceSuffix: suffix with: replacement ^ (self removeSuffix: suffix), replacement! ! !LazyTabGroupMorph methodsFor: 'adding' stamp: 'TudorGirba 1/22/2011 21:01'! addLazyPage: aBlock label: aStringOrMorph self addLazyPage: aBlock label: aStringOrMorph toolbar: nil! ! !LazyTabGroupMorph methodsFor: 'adding' stamp: 'TudorGirba 1/22/2011 22:03'! addLazyPage: aBlock label: aStringOrMorph toolbar: aToolbar self addLazyPage: aBlock label: aStringOrMorph toolbar: aToolbar collapsable: false! ! !LazyTabGroupMorph methodsFor: 'adding' stamp: 'TudorGirba 1/22/2011 22:02'! addLazyPage: aBlock label: aStringOrMorph toolbar: aToolbar collapsable: aBoolean | newPage label innerLabel | newPage := LazyTabPage new. newPage lazyPageMorphCreation: aBlock; labelMorph: aStringOrMorph; toolbar: aToolbar. innerLabel := aStringOrMorph isMorph ifTrue: [aStringOrMorph] ifFalse: [(self theme buttonLabelForText: aStringOrMorph) font: self font; vResizing: #shrinkWrap; hResizing: #shrinkWrap]. label := aBoolean ifTrue: [UITheme builder newRow: { innerLabel . UITheme builder newCloseControlFor: nil action: [self removePage: newPage] help: nil}] ifFalse: [innerLabel]. self addPage: newPage label: label! ! !LazyTabGroupMorph methodsFor: 'accessing' stamp: 'TudorGirba 7/23/2011 20:14'! announcer ^ announcer ifNil: [announcer := GLMAnnouncer new]! ! !LazyTabGroupMorph methodsFor: 'accessing' stamp: 'TudorGirba 1/28/2011 01:25'! headerMorph ^ headerMorph! ! !LazyTabGroupMorph methodsFor: 'accessing' stamp: 'TudorGirba 1/28/2011 01:25'! headerMorph: anObject headerMorph := anObject! ! !LazyTabGroupMorph methodsFor: 'initialization' stamp: 'TudorGirba 1/28/2011 01:24'! initialize "Initialize the receiver." super initialize. self removeMorph: self contentMorph; removeMorph: self tabSelectorMorph; toolbarMorph: self newToolbarMorph; headerMorph: self newHeaderMorph; addMorph: self headerMorph; addMorph: self contentMorph. " self borderWidth: 0; changeTableLayout; cellPositioning: #topLeft; cellInset: 0 @ -1; reverseTableCells: true; pageMorphs: OrderedCollection new; tabSelectorMorph: self newTabSelectorMorph; contentMorph: self newContentMorph; addMorph: self tabSelectorMorph; addMorph: self contentMorph. self tabSelectorMorph addDependent: self"! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 1/28/2011 20:38'! newHeaderMorph ^ (self theme newRowIn: self theme for: {self tabSelectorMorph . self toolbarMorph}) cellInset: 0; cellPositioning: #bottomCenter; borderWidth: 0! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 1/28/2011 20:36'! newToolbarMorph ^ PanelMorph new fillStyle: (SolidFillStyle color: Color transparent); borderStyle: (BorderStyle width: 0); vResizing: #spaceFill; hResizing: #shrinkWrap; cellPositioning: #center; changeTableLayout; cellInset: 0; yourself ! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 1/22/2011 21:03'! pageAt: index ^ (self pages at: index ) actualPageMorph! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 7/23/2011 20:33'! removePage: aPage | removedPageIndex | removedPageIndex := self pages indexOf: aPage. self announcer suspendAllWhile: [ super removePage: aPage ]. self announcer announce: (LazyTabPageRemoved new tabs: self; page: aPage; pageIndex: removedPageIndex; newIndex: self tabSelectorMorph selectedIndex). self pages isEmpty ifTrue: [ self contentMorph removeAllMorphs ]! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 1/23/2011 00:23'! removePageIndex: anInteger self removePage: (self pages at: anInteger)! ! !LazyTabGroupMorph methodsFor: 'accessing' stamp: 'TudorGirba 1/28/2011 00:33'! toolbarMorph ^ toolbarMorph! ! !LazyTabGroupMorph methodsFor: 'accessing' stamp: 'TudorGirba 1/28/2011 00:33'! toolbarMorph: anObject toolbarMorph := anObject! ! !LazyTabGroupMorph methodsFor: 'private' stamp: 'TudorGirba 1/28/2011 20:16'! updatePageIndex: index "Change to the given page index, update the toolbar and send the announcement" | p oldPage | index = 0 ifTrue: [^ self]. oldPage := self tabSelectorMorph selectedTab. p := self pageMorph. p isNil ifTrue: [self contentMorph addMorph: (self pageAt: index)] ifFalse: [self contentMorph replaceSubmorph: p by: (self pageAt: index)]. ((self pages at: index) toolbar notNil and: [(self pages at: index) toolbar hasSubmorphs]) ifTrue: [ self toolbarMorph hasSubmorphs ifFalse: [self toolbarMorph addMorph: (self pages at: index) toolbar ] ifTrue: [self toolbarMorph replaceSubmorph: self toolbarMorph submorphs first by: (self pages at: index) toolbar ]] ifFalse: [self toolbarMorph removeAllMorphs ]. self headerMorph layoutChanged. self pageMorph layoutChanged. self adoptPaneColor: (self owner ifNil: [self]) paneColor. self announcer announce: (LazyTabPageChanged new tabs: self; page: (self pages at: index); oldPage: oldPage; pageIndex: index)! ! !GLMSingleSpotterRequest class methodsFor: 'utilities' stamp: 'ML 2/26/2011 15:02'! substring: testString matches: aString caseSensitive: aBoolean "Checks if a testString is a substring of aString. The matching parts do not necessarily need to be consecutive, for example 'egli' matches 'renggli'." | index | index := 0. testString do: [ :char | index := aString findString: (String with: char) startingAt: index + 1 caseSensitive: aBoolean. index = 0 ifTrue: [ ^ false ] ]. ^ true! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! assisted ^ assisted! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! assisted: aBoolean "A boolean indicating that the typing of the user is assisted but not constrained." assisted := aBoolean! ! !GLMSingleSpotterRequest methodsFor: 'configuration' stamp: 'ML 2/26/2011 15:02'! collection: aCollection self collection: aCollection caseSensitive: false! ! !GLMSingleSpotterRequest methodsFor: 'configuration' stamp: 'ML 2/26/2011 15:02'! collection: aCollection caseSensitive: aBoolean "Configure this completion dialog with aCollection and match the elements case sensitive if aBoolean is true. Display the complete list if the filter is empty." self searchBlock: [ :value | value isEmpty ifTrue: [ aCollection ] ifFalse: [ aCollection select: [ :each | self class substring: value matches: (self labelFor: each) caseSensitive: aBoolean ] ] ]! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! default ^ default! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! default: aString "The default string initially used for filtering." default := aString! ! !GLMSingleSpotterRequest methodsFor: 'initialize-release' stamp: 'TudorGirba 10/26/2011 16:01'! defaultAction ^(GLMMorphicSingleSpotter openOn: self) answer! ! !GLMSingleSpotterRequest methodsFor: 'dispatching' stamp: 'ML 2/26/2011 15:02'! handleWith: anObject ^ anObject handleCompletionRequest: self! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! iconBlock ^ iconBlock! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! iconBlock: aOneArgumentBlock "A one argument block answering the icon symbol for a given element." iconBlock := aOneArgumentBlock! ! !GLMSingleSpotterRequest methodsFor: 'querying' stamp: 'ML 2/26/2011 15:02'! iconFor: anObject ^ iconBlock value: anObject! ! !GLMSingleSpotterRequest methodsFor: 'initialization' stamp: 'ML 2/26/2011 15:02'! initialize super initialize. prompt := 'Completion Request'. default := String new. assisted := false. searchBlock := [ :value | #() ]. labelBlock := [ :value | value asString ]. iconBlock := [ :value | nil ]! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! labelBlock ^ labelBlock! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! labelBlock: aOneArgumentBlock "A one argument block answering the string for a given element." labelBlock := aOneArgumentBlock! ! !GLMSingleSpotterRequest methodsFor: 'querying' stamp: 'ML 2/26/2011 15:02'! labelFor: anObject ^ labelBlock value: anObject! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:56'! name ^self prompt! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! prompt ^ prompt! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! prompt: aString "A string with the title for this request." prompt := aString! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! searchBlock ^ searchBlock! ! !GLMSingleSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 15:02'! searchBlock: aOneArgumentBlock "A one argument block returning the elements for the given filter." searchBlock := aOneArgumentBlock! ! !GLMSingleSpotterRequest methodsFor: 'querying' stamp: 'ML 2/26/2011 15:02'! valuesFor: anObject ^ searchBlock value: anObject! ! !GLMSpotterRequest methodsFor: 'initialize-release' stamp: 'ML 2/26/2011 16:07'! add: aRequest requests add: aRequest ! ! !GLMSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:20'! default ^ default! ! !GLMSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:20'! default: anObject default := anObject! ! !GLMSpotterRequest methodsFor: 'initialize-release' stamp: 'TudorGirba 2/27/2011 15:25'! defaultAction ^(GLMMorphicSpotter openOn: self) answer! ! !GLMSpotterRequest methodsFor: 'initialize-release' stamp: 'ML 2/26/2011 16:10'! handleWith: anObject ^ anObject handleCompletionRequest: self! ! !GLMSpotterRequest methodsFor: 'initialize-release' stamp: 'ML 2/26/2011 16:08'! initialize super initialize. requests := OrderedCollection new.! ! !GLMSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:19'! prompt ^ prompt! ! !GLMSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:19'! prompt: anObject prompt := anObject! ! !GLMSpotterRequest methodsFor: 'accessing' stamp: 'ML 2/26/2011 16:29'! requests ^requests ! ! !Morph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 16:39'! glamourMinExtent ^ self minExtent! ! !Morph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/7/2011 10:37'! glamourOptimalExtent |tmpOldResizing tmpResult| tmpOldResizing := self setOptimalResizingStrategyAndReturnOldOne. tmpResult := self minExtent. self returnToOldResizingStrategy: tmpOldResizing. ^ tmpResult ! ! !Morph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 15:47'! returnToOldResizingStrategy: aCollection |tmpSubmorphResizing| self submorphs with: aCollection third do: [:aMorph :resizingParameter | aMorph returnToOldResizingStrategy: resizingParameter. ]. self hResizing: aCollection first. self vResizing: aCollection second.! ! !Morph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 16:03'! setOptimalResizing self hResizing: #shrinkWrap. self vResizing: #shrinkWrap! ! !Morph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 15:47'! setOptimalResizingStrategyAndReturnOldOne | tmpHResizing tmpVResizing tmpSubmorphResizing | tmpHResizing := self hResizing. tmpVResizing := self vResizing. self setOptimalResizing. tmpSubmorphResizing := self submorphs collect: [ :aMorph | aMorph setOptimalResizingStrategyAndReturnOldOne ]. ^ {tmpHResizing. tmpVResizing. tmpSubmorphResizing}! ! !ROMorph commentStamp: '' prior: 34262307! A ROMorph is the unique interface between Roassal and Morphic Instance Variables animationBlock: canvas: elementBeingPointed: eventBeginingDragging: view: animationBlock - xxxxx canvas - xxxxx elementBeingPointed - xxxxx eventBeginingDragging - xxxxx view - xxxxx ! !ROMorph class methodsFor: 'public'! on: aView ^ self new setView: aView; yourself! ! !ROMorph methodsFor: 'accessing'! bitmap "view camera realExtent: self bounds extent. " ^ view bitmap! ! !ROMorph methodsFor: 'accessing'! canvas | c | c := view canvasForRealSize: self bounds extent. c extent: self extent. ^ c ! ! !ROMorph methodsFor: 'drawing' stamp: 'AlexandreBergel 8/1/2012 16:29'! drawOn: aCanvas aCanvas clipBy: self bounds during: [ :c | c translateBy: self bounds origin during: [ :can | canvas canvas: can. view drawOn: canvas ] ]. ! ! !ROMorph methodsFor: 'accessing'! elementForEvent: evt "evt contains a real position, since this is where the user click on the screen" ^ self elementForRealPosition: (self relativePositionFor: evt)! ! !ROMorph methodsFor: 'accessing' stamp: 'AlexandreBergel 4/30/2012 16:00'! elementForRealPosition: position "evt contains a real position, since this is where the user click on the screen" ^ view elementAtRealPosition: position ! ! !ROMorph methodsFor: 'drawing' stamp: 'AlexandreBergel 11/14/2012 13:58'! extent: v super extent: v. canvas extent: v. view windowSize: v. ! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 8/26/2012 12:31'! handleKeyDown: anEvent "COMENTED FOR NOW" "System level event handling." " anEvent wasHandled ifTrue:[^self]. (self handlesKeyboard: anEvent) ifFalse:[^self]. anEvent wasHandled: true. ^self keyDown: anEvent"! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 8/26/2012 12:31'! handleKeyUp: anEvent "COMENTED FOR NOW" "System level event handling." " anEvent wasHandled ifTrue:[^self]. (self handlesKeyboard: anEvent) ifFalse:[^self]. anEvent wasHandled: true. ^self keyDown: anEvent"! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 8/26/2012 12:31'! handleKeystroke: anEvent self roKeyStroke: anEvent.! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 1/3/2013 16:17'! handleMouseMove: anEvent super handleMouseMove: anEvent. self roMouseMoving: anEvent.! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 1/3/2013 16:16'! handleMouseOver: anEvent | currentElement | anEvent wasHandled ifTrue:[ ^ self ]. "not interested" "Do nothing if we are dragging" self isDragging ifTrue: [ ^ self ]. elementBeingPointed ifNil: [ elementBeingPointed := self elementForEvent: anEvent ]. currentElement := self elementForEvent: anEvent. "Transcript show: (view camera realToVirtualPoint: (self relativePositionFor: anEvent)) printString, ' ', (elementBeingPointed == currentElement) printString; cr." (currentElement ~~ elementBeingPointed) ifTrue: [ "Transcript show: 'mouse over: ', anEvent printString, ' ', elementBeingPointed printString, ' ', currentElement printString; cr." "self roMouseLeave: anEvent." elementBeingPointed announce: ROMouseLeave. elementBeingPointed := currentElement. self roMouseEnter: anEvent ]. " self roMouseMoving: anEvent."! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 12/20/2012 17:27'! handlesKeyboard: evt ^true! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 12/20/2012 17:32'! handlesMouseDown: anEvent anEvent wasHandled ifTrue:[ ^ false ]. "not interested" ^ true! ! !ROMorph methodsFor: 'events-processing'! handlesMouseOver: evt ^ true! ! !ROMorph methodsFor: 'testing'! isDragging ^ eventBeginingDragging notNil! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 8/26/2012 12:00'! mouseDown: evt eventBeginingDragging ifNil: [ evt hand waitForClicksOrDrag: self event: evt selectors: { #roMouseClick:. nil. nil. #roMouseDragBegin: } threshold: 5. ^ self ]. evt anyButtonPressed ifTrue: [ self roMouseDragging: evt. ]. evt wasHandled: true. ^ true! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 8/26/2012 12:13'! mouseEnter: evt " Transcript show: 'mouseEnter ', evt printString; cr." evt anyButtonPressed ifFalse: [ self roMouseEnter: evt. ]. evt wasHandled: true. ^ true! ! !ROMorph methodsFor: 'events-processing'! mouseLeave: evt evt anyButtonPressed ifFalse: [ self roMouseLeave: evt. ]. evt wasHandled: true. ^ true! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 12/20/2012 18:03'! mouseMove: evt evt anyButtonPressed ifTrue: [ self roMouseDragging: evt ] ifFalse: [ self roMouseMoving: evt ]. evt wasHandled: true. ^ true! ! !ROMorph methodsFor: 'events-processing'! mouseUp: evt self isDragging ifTrue: [self roMouseDragEnd: evt ]. evt wasHandled: true.! ! !ROMorph methodsFor: 'morph'! openInWindow "Open a window that contains the morph" ^ self openInWindowLabeled: view title! ! !ROMorph methodsFor: 'util'! realToVirtualPoint: aPoint "^ (view canvasForRealSize: self extent) realToVirtualPoint: aPoint" ^ view camera realToVirtualPoint: aPoint! ! !ROMorph methodsFor: 'events-processing' stamp: 'AlexandreBergel 12/6/2012 16:26'! relativePositionFor: evt "Return the position within the window" ^ evt position - self bounds origin! ! !ROMorph methodsFor: 'events-processing' stamp: 'AlexandreBergel 10/16/2013 08:52'! roKeyStroke: evt | relativePosition ev virtualPosition | (evt commandKeyPressed and: [ evt keyCharacter = $w ]) ifTrue: [ self owner delete ]. relativePosition := self relativePositionFor: evt. ev := ROKeyDown new keyValue: evt keyValue. virtualPosition := self realToVirtualPoint: relativePosition. ev position: virtualPosition. (self elementForRealPosition: relativePosition) announce: ev. ! ! !ROMorph methodsFor: 'events-processing' stamp: 'AlexandreBergel 9/11/2013 23:29'! roMouseClick: evt | relativePosition ev positionInTheView | relativePosition := self relativePositionFor: evt. evt yellowButtonChanged ifTrue: [ ev := ROMouseRightClick new ]. evt redButtonChanged ifTrue: [ ev := ROMouseLeftClick new ]. evt blueButtonChanged ifTrue: [ ev := ROMouseClick new ]. ev commandKeyPressed: evt commandKeyPressed. ev controlKeyPressed: evt controlKeyPressed. ev shiftKeyPressed: evt shiftPressed. "virtualPosition := self realToVirtualPoint: relativePosition." positionInTheView := (self elementForRealPosition: relativePosition) view camera realToVirtualPoint: relativePosition. ev position: positionInTheView. " Transcript show: (self elementForRealPosition: relativePosition) printString, ' ', relativePosition printString; cr." (self elementForRealPosition: relativePosition) announce: ev. "Transcript show: 'click: ', virtualPosition printString; cr"! ! !ROMorph methodsFor: 'events-processing'! roMouseDragBegin: evt " Transcript show: 'drag begin: ', evt printString; cr." | relativePosition | eventBeginingDragging := evt copy. relativePosition := self relativePositionFor: evt. elementBeingPointed := self elementForRealPosition: relativePosition "elementBeingDragged := (view elementAt: (self realToVirtualPoint: relativePosition))"! ! !ROMorph methodsFor: 'events-processing'! roMouseDragEnd: evt "Transcript show: 'drag end: ', evt printString; cr." | relativePosition step event | relativePosition := self relativePositionFor: evt. step := evt position - eventBeginingDragging position. event := ROMouseDragged new step: step; yourself. event position: (self realToVirtualPoint: relativePosition). elementBeingPointed announce: event. eventBeginingDragging := nil. elementBeingPointed := nil! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 12/20/2012 18:01'! roMouseDragging: evt | step relativePosition event virtualStep | " Transcript show: 'drag dragging: ', evt printString; cr." eventBeginingDragging ifNil: [ ^ self ]. relativePosition := self relativePositionFor: evt. step := evt position - eventBeginingDragging position. "step := (self realToVirtualPoint: evt position) - (self realToVirtualPoint: eventBeginingDragging position)." elementBeingPointed ifNil: [ elementBeingPointed := self elementForRealPosition: relativePosition ]. " virtualStep := (elementBeingPointed view canvasForRealSize: self extent) realToVirtualPoint: step. Transcript show: 'drag: ', elementBeingPointed printString, ' ', step printString, ' ', virtualStep printString; cr. " event := ROMouseDragging new step: step; yourself. event commandKeyPressed: evt commandKeyPressed. event controlKeyPressed: evt controlKeyPressed. event shiftKeyPressed: evt shiftPressed. "Transcript show: 'dragging real step = ', step printString; cr." event position: relativePosition. elementBeingPointed announce: event. eventBeginingDragging := evt copy.! ! !ROMorph methodsFor: 'events-processing' stamp: 'AlexandreBergel 12/7/2012 08:39'! roMouseEnter: evt | relativePosition ev virtualPosition element | relativePosition := self relativePositionFor: evt. "Transcript show: 'enter ', (relativePosition) printString; cr." element := self elementForRealPosition: relativePosition. virtualPosition := element view camera realToVirtualPoint: relativePosition. ev := ROMouseEnter new. ev position: virtualPosition. ev realPosition: relativePosition. ev element: element. element announce: ev. ! ! !ROMorph methodsFor: 'events-processing' stamp: 'AlexandreBergel 5/28/2012 21:14'! roMouseLeave: evt | relativePosition ev virtualPosition element | relativePosition := self relativePositionFor: evt. element := self elementForRealPosition: relativePosition. "Transcript show: 'leave: ', (self elementForRealPosition: relativePosition) printString; cr." virtualPosition := element view camera realToVirtualPoint: relativePosition. ev := ROMouseLeave new. ev position: virtualPosition. element announce: ev ! ! !ROMorph methodsFor: 'events-processing'! roMouseMoving: evt | relativePosition ev | relativePosition := self relativePositionFor: evt. ev := ROMouseMove new. ev position: (view camera realToVirtualPoint: relativePosition). "Transcript show: 'moving: '; cr." (self elementForRealPosition: relativePosition) announce: ev! ! !ROMorph methodsFor: 'initialize' stamp: 'AlexandreBergel 12/1/2012 17:07'! setView: anROView view := anROView. "Maybe something smarter with #invalidRect: can be done here. Need to check." view on: RORefreshNeeded do: [ :event | self changed ]. view on: ROViewChanged do: [ :event | event newView on: RORefreshNeeded do: [ :e | self changed ]. self changed ]. canvas := view camera canvas. self extent: view defaultWindowSize. canvas extent: self extent. ! ! !ROMorph methodsFor: 'morph'! stepTime "Answer the desired time between steps in milliseconds. This default implementation requests that the 'step' method be called once every second." ^ 5 ! ! !ROMorph methodsFor: 'events-processing' stamp: 'VanessaPena 3/12/2013 23:05'! takesKeyboardFocus "Answer whether the receiver can normally take keyboard focus." ^ true! ! !ROMorph methodsFor: 'initialize' stamp: 'TudorGirba 7/24/2012 17:24'! view ^ view! ! !ROMorph methodsFor: 'morph'! wantsSteps ^ animationBlock notNil! ! !Stream methodsFor: '*petitparser-core-converting' stamp: 'lr 4/8/2010 14:46'! asPetitStream ^ self contents asPetitStream! ! !SubscriptionRegistry methodsFor: '*roassalmorphic' stamp: 'VanessaPena 12/2/2012 19:35'! unsubscribeForEvent: aEventClass ^ self protected: [ subscriptions removeAllSuchThat: [:subscription | subscription announcementClass == aEventClass ]] ! ! !Symbol methodsFor: '*Glamour-Helpers' stamp: 'tg 10/25/2010 02:09'! asGlamourOriginIdentifier ^ GLMPortIdentifier defaultOriginOf: self! ! !Symbol methodsFor: '*Glamour-Helpers' stamp: 'tg 10/25/2010 02:08'! asGlamourTargetIdentifier ^ GLMPortIdentifier defaultTargetOf: self! ! !Symbol methodsFor: '*petitparser-core-converting' stamp: 'lr 12/18/2011 15:58'! asParser "Answer a predicate parser named after the receiving symbol. Possible symbols are the method selectors on the class-side of PPPredicateObjectParser." ^ PPPredicateObjectParser perform: self! ! !Symbol methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! glamourValueWithArgs: anArray anArray size < 1 ifTrue: [^nil]. ^anArray first perform: self! ! !Symbol methodsFor: '*roassal-core'! roValue: anObject ^ anObject perform: self! ! !Symbol methodsFor: '*CollectionExtensions' stamp: 'stephane.ducasse 10/14/2008 22:07'! value "Allow this object to act as a ValueHolder on itself." ^self! ! !CompiledMethod methodsFor: '*roassalmorphic' stamp: 'Alexandre Bergel 4/26/2010 11:25'! classReferences ^ ((self allLiterals select: [:l | l isKindOf: Association ]) collect: #value) copyWithout: self methodClass ! ! !Set methodsFor: '*CollectionExtensions' stamp: 'jannik.laval 2/6/2009 16:44'! flatCollect: aBlock ^self flatCollectAsSet: aBlock! ! !PluggableListMorph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 15:56'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !GLMTabPanelBorder commentStamp: '' prior: 34262697! Specialized border for TabGroup. Does not draw border beneath the selectd tab and only draws on top.! !GLMTabPanelBorder methodsFor: 'drawing' stamp: 'tg 9/10/2010 07:42'! frameRectangle: aRectangle on: aCanvas "Draw the border taking the currently selected tab into account. Only works for top-positioned tabs for the moment." |w h r tab| w := self width. w isPoint ifTrue: [h := w y. w := w x] ifFalse:[h := w]. tab := self selectedTab. tab ifNil: [ r := aRectangle topLeft + (w@0) corner: aRectangle topRight - (w@h negated). aCanvas fillRectangle: r color: self color. ^self]. "top" r := aRectangle topLeft + (w@0) corner: tab bounds left + w@(aRectangle top + h). aCanvas fillRectangle: r color: self color. "top 1" r := tab bounds left + w@ aRectangle top corner: tab bounds right - w@(aRectangle top + h). aCanvas fillRectangle: r color: tab paneColor. "top 2" r := tab bounds right - w@ aRectangle top corner: aRectangle topRight - (w@h negated). aCanvas fillRectangle: r color: self color. "top 3"! ! !TextMorph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 16:01'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !ImageMorph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 16:02'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !PPExtractProdcutionRefactoring class methodsFor: 'instance creation' stamp: 'lr 12/10/2011 11:03'! onClass: aClass production: aSelector interval: anInterval to: aTargetSelector ^ (self extract: anInterval from: aSelector in: aClass) setTargetProduction: aTargetSelector; yourself! ! !PPExtractProdcutionRefactoring methodsFor: 'transforming' stamp: 'lr 12/10/2011 11:11'! existingSelector ^ nil! ! !PPExtractProdcutionRefactoring methodsFor: 'transforming' stamp: 'lr 12/10/2011 11:10'! getNewMethodName parameters isEmpty ifFalse: [ self refactoringError: 'Cannot extract production since it contains references.' ]. targetProduction asSymbol isUnary ifFalse: [ self refactoringError: 'Invalid production name.' ]. ^ targetProduction asSymbol! ! !PPExtractProdcutionRefactoring methodsFor: 'transforming' stamp: 'lr 12/10/2011 11:15'! nameNewMethod: aSymbol class addInstanceVariable: aSymbol asString. extractedParseTree renameSelector: aSymbol andArguments: #(). modifiedParseTree := RBParseTreeRewriter replace: self methodDelimiter with: aSymbol asString in: modifiedParseTree! ! !PPExtractProdcutionRefactoring methodsFor: 'preconditions' stamp: 'lr 12/18/2011 14:49'! preconditions ^ (self checkCompositeParser: class) & super preconditions & (RBCondition definesSelector: targetProduction asSymbol in: class) not & (RBCondition definesInstanceVariable: targetProduction asString in: class) not! ! !PPExtractProdcutionRefactoring methodsFor: 'initialization' stamp: 'lr 12/10/2011 11:02'! setTargetProduction: aSymbol targetProduction := aSymbol! ! !PPExtractProdcutionRefactoring methodsFor: 'requests' stamp: 'lr 12/10/2011 11:12'! shouldExtractAssignmentTo: aString ^ false! ! !GLMActionAnnouncement class methodsFor: 'instance creation' stamp: 'david_roethlisberger 3/3/2009 16:28'! action: anAction ^self new action: anAction; yourself! ! !GLMActionAnnouncement methodsFor: 'accessing' stamp: 'david_roethlisberger 3/3/2009 16:28'! action ^action! ! !GLMActionAnnouncement methodsFor: 'accessing' stamp: 'david_roethlisberger 3/3/2009 16:28'! action: anAction action := anAction! ! !GLMMenuInvoked class methodsFor: 'as yet unclassified' stamp: 'jre 7/31/2009 15:24'! action: anAction on: aMenuMorph ^self new initializeAction: anAction on: aMenuMorph! ! !GLMMenuInvoked methodsFor: 'initialization' stamp: 'jre 7/31/2009 15:43'! initializeAction: anAction on: aMenuMorph self action: anAction. menuMorph := aMenuMorph! ! !GLMMenuInvoked methodsFor: 'accessing' stamp: 'jre 7/31/2009 15:43'! menuMorph ^menuMorph! ! !GLMContextChanged commentStamp: 'tg 2/20/2010 14:55' prior: 34262863! A GLMContextChanged is announced by a presentation when an outer port event raises.! !GLMContextChanged methodsFor: 'testing' stamp: ' 4/5/09 22:18'! announcesNewSelection "ContextChanged announces a new selection if the updated port is #selection and the new value is different from the current selection. This method is useful when updating the selection in UI widgets, because we only want to affect the widget when there actually is a new selection" ^self property = #selection and: [self presentation selection ~~ self value]! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldValue ^oldValue! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldValue: anObject oldValue := anObject! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! presentation ^presentation! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! presentation: aPresentation presentation := aPresentation! ! !GLMContextChanged methodsFor: 'printing' stamp: 'TudorGirba 10/30/2011 10:51'! printOn: aStream super printOn: aStream. aStream nextPutAll: ' (presentation = '; nextPutAll: self presentation printString; nextPutAll: ', property = #'; nextPutAll: self property; nextPutAll: ', oldValue = '; nextPutAll: self oldValue asString; nextPutAll: ', value = '; nextPutAll: self value asString; nextPutAll: ')'! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! property ^property! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! property: aSymbol property := aSymbol! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! value ^value! ! !GLMContextChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! value: anObject value := anObject! ! !GLMDropDownListMorphSelectionChanged methodsFor: 'accessing' stamp: 'AndreiChis 8/20/2013 22:26'! selectionIndex ^ selectionIndex! ! !GLMDropDownListMorphSelectionChanged methodsFor: 'accessing' stamp: 'AndreiChis 8/20/2013 22:26'! selectionIndex: anInteger selectionIndex := anInteger! ! !GLMDropDownListMorphSelectionChanged methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 20:15'! selectionValue ^ selectionValue! ! !GLMDropDownListMorphSelectionChanged methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 20:15'! selectionValue: anObject selectionValue := anObject! ! !GLMMatchingPresentationsChanged commentStamp: 'tg 2/20/2010 14:56' prior: 34263026! A GLMMatchingPresentationsChanged is announced by the pane when the presentations that should be displayed change due to changes in the values of the ports of the pane.! !GLMMatchingPresentationsChanged methodsFor: 'accessing-convenience' stamp: 'tg 1/11/2010 20:59'! matchingPresentations "The presentations that match now." ^ self pane matchingPresentations! ! !GLMMatchingPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldMatchingPresentations "The presentations that matched before this announcement." ^oldMatchingPresentations! ! !GLMMatchingPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldMatchingPresentations: aCollection "The presentations that matched before this announcement." oldMatchingPresentations := aCollection! ! !GLMMatchingPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane "The pane on which the matching presentations changed." ^pane! ! !GLMMatchingPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane: aPane "The pane on which the matching presentations changed." pane := aPane! ! !GLMMatchingPresentationsChanged methodsFor: 'printing' stamp: 'tg 1/11/2010 08:47'! printOn: aStream super printOn: aStream. aStream nextPutAll: ' (pane = ', self pane printString , ')'! ! !GLMPaneAnnouncement commentStamp: 'TudorGirba 2/4/2011 21:24' prior: 34263269! These announcements are used by the browser to communicate with the renderer whenever the panes configuration is modified in some way. Instance Variables: pane browser position ! !GLMPaneAnnouncement class methodsFor: 'instance creation' stamp: 'tg 1/18/2010 11:08'! pane: aPane atPosition: anInteger inBrowser: aBrowser ^(self new) pane: aPane; position: anInteger; browser: aBrowser; yourself! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! browser ^browser! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! browser: anObject browser := anObject! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! pane ^pane! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! pane: anObject pane := anObject! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! position ^position! ! !GLMPaneAnnouncement methodsFor: 'accessing' stamp: 'tg 1/18/2010 11:06'! position: anObject position := anObject! ! !GLMPaneRemoved class methodsFor: 'instance creation' stamp: ' 4/5/09 22:18'! pane: aPane fromBrowser: aBrowser ^(self new) pane: aPane; browser: aBrowser; yourself! ! !GLMPaneReplaced class methodsFor: 'as yet unclassified' stamp: 'tg 8/22/2010 21:35'! oldPane: oldPane newPane: newPane fromBrowser: aBrowser ^ self new oldPane: oldPane; newPane: newPane; browser: aBrowser! ! !GLMPaneReplaced methodsFor: 'accessing' stamp: 'tg 8/22/2010 21:36'! newPane ^ newPane! ! !GLMPaneReplaced methodsFor: 'accessing' stamp: 'tg 8/22/2010 21:36'! newPane: anObject newPane := anObject! ! !GLMPaneReplaced methodsFor: 'accessing' stamp: 'tg 8/22/2010 21:36'! oldPane ^ oldPane! ! !GLMPaneReplaced methodsFor: 'accessing' stamp: 'tg 8/22/2010 21:36'! oldPane: anObject oldPane := anObject! ! !GLMPresentationUpdated commentStamp: 'tg 2/20/2010 14:54' prior: 34263553! A GLMPresentationUpdated is announced by the presentation when an update is wanted.! !GLMPresentationUpdated methodsFor: 'accessing' stamp: 'tg 8/24/2010 21:40'! presentation ^ presentation! ! !GLMPresentationUpdated methodsFor: 'accessing' stamp: 'tg 8/24/2010 21:40'! presentation: anObject presentation := anObject! ! !GLMPresentationsChanged commentStamp: 'tg 2/20/2010 14:57' prior: 34263708! A GLMPresentationsChanged is announced by the pane when the set of presentations changes.! !GLMPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldPresentations "The presentations that were present on the pane before the change." ^oldPresentations! ! !GLMPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldPresentations: aCollection "The presentations that were present on the pane before the change." oldPresentations := aCollection! ! !GLMPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane "The pane on which the presentations changed." ^pane! ! !GLMPresentationsChanged methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane: aPane "The pane on which the presentations changed." pane := aPane! ! !GLMPresentationsChanged methodsFor: 'accessing-convenience' stamp: ' 4/5/09 22:18'! presentations "The presentationt that are currently present on the pane." ^self pane presentations! ! !GLMPresentationsChanged methodsFor: 'printing' stamp: 'tg 1/11/2010 08:48'! printOn: aStream super printOn: aStream. aStream nextPutAll: ' (pane = ', self pane printString , ')'! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! end ^ end! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! end: anObject end := anObject! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'TudorGirba 7/14/2011 21:49'! interval ^ self start to: self end! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! selectedText ^ selectedText! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! selectedText: anObject selectedText := anObject! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! start ^ start! ! !GLMSelectedTextChanged methodsFor: 'accessing' stamp: 'tg 4/15/2010 17:55'! start: anObject start := anObject! ! !GLMTextChanged methodsFor: 'accessing' stamp: 'TudorGirba 7/29/2012 08:33'! text ^ text! ! !GLMTextChanged methodsFor: 'accessing' stamp: 'TudorGirba 7/29/2012 08:33'! text: anObject text := anObject! ! !GLMTransmissionTriggered commentStamp: '' prior: 34263864! A GLMTransmissionTriggered is announced by a browser when a transmission brokered by the browser is triggered.! !GLMTreeMorphSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:56'! selectionPathValue ^ selectionPathValue! ! !GLMTreeMorphSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:56'! selectionPathValue: anObject selectionPathValue := anObject! ! !GLMTreeMorphSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:54'! selectionValue ^ selectionValue! ! !GLMTreeMorphSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:54'! selectionValue: anObject selectionValue := anObject! ! !GLMTreeMorphStrongSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:58'! strongSelectionValue ^ strongSelectionValue! ! !GLMTreeMorphStrongSelectionChanged methodsFor: 'accessing' stamp: 'tg 12/29/2009 01:58'! strongSelectionValue: anObject strongSelectionValue := anObject! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! page ^ page! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! page: anObject page := anObject! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/23/2011 00:23'! pageIndex ^ pageIndex! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/23/2011 00:23'! pageIndex: anObject pageIndex := anObject! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! tabs ^ tabs! ! !LazyTabPageAnnouncement methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! tabs: anObject tabs := anObject! ! !LazyTabPageChanged methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! oldPage ^ oldPage! ! !LazyTabPageChanged methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 23:07'! oldPage: anObject oldPage := anObject! ! !LazyTabPageRemoved methodsFor: 'accessing' stamp: 'TudorGirba 7/23/2011 20:20'! newIndex ^ newIndex! ! !LazyTabPageRemoved methodsFor: 'accessing' stamp: 'TudorGirba 7/23/2011 20:33'! newIndex: anObject newIndex := anObject! ! !ROCameraResized methodsFor: 'accessing' stamp: 'VanessaPena 12/23/2012 20:21'! newBounds ^ newBounds! ! !ROCameraResized methodsFor: 'accessing' stamp: 'VanessaPena 12/23/2012 20:21'! newBounds: anObject newBounds := anObject! ! !ROCameraResized methodsFor: 'accessing' stamp: 'VanessaPena 12/23/2012 20:21'! oldBounds ^ oldBounds! ! !ROCameraResized methodsFor: 'accessing' stamp: 'VanessaPena 12/23/2012 20:21'! oldBounds: anObject oldBounds := anObject! ! !ROCameraTranslated methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/5/2013 17:33'! step ^step ! ! !ROCameraTranslated methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/5/2013 17:33'! step: aPoint step := aPoint! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 18:05'! buttons ^ buttons! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 18:05'! buttons: anObject buttons := anObject! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! commandKeyPressed ^commandKeyPressed! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! commandKeyPressed: anObject commandKeyPressed := anObject! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! controlKeyPressed ^ controlKeyPressed! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! controlKeyPressed: anObject controlKeyPressed := anObject! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! shiftKeyPressed ^ shiftKeyPressed! ! !ROAbstractMouseDragging methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 17:38'! shiftKeyPressed: anObject shiftKeyPressed := anObject! ! !ROAbstractMouseDragging methodsFor: 'accessing'! step ^ step! ! !ROAbstractMouseDragging methodsFor: 'accessing'! step: anObject step := anObject! ! !ROMouseDragging class methodsFor: 'as yet unclassified'! step: value ^ self new step: value! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:39'! element ^ element! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:39'! element: anObject element := anObject! ! !ROComponentEvent methodsFor: 'action' stamp: 'AlexandreBergel 1/18/2013 10:40'! emitToParent element ifNil: [ ^ self ]. element parent announce: self! ! !ROComponentEvent methodsFor: 'testing' stamp: 'AlexandreBergel 1/18/2013 10:41'! hasElement ^ element notNil! ! !ROComponentEvent methodsFor: 'initialize-release' stamp: 'AlexandreBergel 1/18/2013 11:15'! initialize super initialize. position := 0 @ 0. realPosition := 0 @ 0! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:40'! model ^ element isNil ifTrue: [ nil ] ifFalse: [ self element model ] ! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 14:04'! position ^ position! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:40'! position: aPoint "Set the position of the even in the view. The position does not necessary correspond to the position on the screen" position := aPoint ! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:40'! realPosition ^ realPosition! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 1/18/2013 10:40'! realPosition: aPoint "aPoint corresponds to the position on the screen. This is useful to process later on" realPosition := aPoint! ! !ROComponentEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 4/8/2013 18:08'! view self element ifNil: [ ^ nil ]. ^ self element view! ! !ROElementTranslated class methodsFor: 'public' stamp: 'AlexandreBergel 10/21/2013 13:46'! step: amountOfPixels ^ self new step: amountOfPixels; yourself! ! !ROElementTranslated methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/21/2013 13:46'! step "Return the step in pixel of the translation" ^ step! ! !ROElementTranslated methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/21/2013 13:46'! step: amountOfPixels "Set the amount of pixels for the translation" step := amountOfPixels! ! !ROKeyDown methodsFor: 'comparing' stamp: 'AlexandreBergel 10/15/2013 14:25'! = anotherKeyDown (self class == anotherKeyDown) ifFalse: [ ^ false ]. ^ self keyValue = anotherKeyDown keyValue! ! !ROKeyDown methodsFor: 'accessing' stamp: 'AlexandreBergel 4/14/2013 00:04'! character ^ Character value: self keyValue! ! !ROKeyDown methodsFor: 'initialize-release' stamp: 'AlexandreBergel 4/14/2013 12:07'! initialize super initialize. keyValue := 0! ! !ROKeyDown methodsFor: 'accessing' stamp: 'VanessaPena 8/26/2012 12:26'! keyValue ^keyValue ! ! !ROKeyDown methodsFor: 'accessing' stamp: 'VanessaPena 8/26/2012 12:26'! keyValue: aValue keyValue := aValue ! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! commandKeyPressed ^ commandKeyPressed! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! commandKeyPressed: anObject commandKeyPressed := anObject! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! controlKeyPressed ^ controlKeyPressed! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! controlKeyPressed: anObject controlKeyPressed := anObject! ! !ROMouseClick methodsFor: 'accessing' stamp: 'AlexandreBergel 12/16/2012 18:31'! initialize super initialize. commandKeyPressed := false. controlKeyPressed := false. shiftKeyPressed := false.! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! shiftKeyPressed ^ shiftKeyPressed! ! !ROMouseClick methodsFor: 'accessing' stamp: 'BenComan 12/16/2012 14:29'! shiftKeyPressed: anObject shiftKeyPressed := anObject! ! !ROEvent class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 4/17/2012 20:19'! new ^ self basicNew initialize! ! !ROEvent methodsFor: 'initialize-release' stamp: 'AlexandreBergel 6/10/2013 15:07'! initialize "Empty constructor"! ! !ROLayoutEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 13:16'! elements ^ elements! ! !ROLayoutEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 13:16'! elements: anObject elements := anObject! ! !ROLayoutEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 13:17'! layout ^ layout! ! !ROLayoutEvent methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 13:17'! layout: anObject layout := anObject! ! !ROLayoutStep methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 16:45'! currentIteration ^ currentIteration! ! !ROLayoutStep methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 17:03'! currentIteration: number currentIteration := number! ! !ROLayoutStep methodsFor: 'initialize-release' stamp: 'AlexandreBergel 11/15/2012 16:45'! initialize super initialize. currentIteration := 0. maxInterations := 0.! ! !ROLayoutStep methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 16:45'! maxInterations ^ maxInterations! ! !ROLayoutStep methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 16:45'! maxInterations: anObject maxInterations := anObject! ! !RORefreshNeeded class methodsFor: 'public creation' stamp: 'AlexandreBergel 7/9/2013 15:39'! instance Instance ifNil: [ Instance := self new ]. ^ Instance! ! !ROViewChanged methodsFor: 'accessing'! newView ^ newView! ! !ROViewChanged methodsFor: 'accessing'! newView: aView newView := aView! ! !ROWindowResized methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 15:05'! extent ^ extent! ! !ROWindowResized methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 15:05'! extent: anObject extent := anObject! ! !ROWindowResized methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 15:06'! oldExtent ^ oldExtent! ! !ROWindowResized methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 15:06'! oldExtent: anObject oldExtent := anObject! ! !GLMUITheme commentStamp: 'TudorGirba 1/30/2011 22:51' prior: 34264041! The theme is developed in the context of the Glamour project, and its goal is to create a look that: - does not look like a specific operating system. In particular, the icons should be operating system agnostic, because, for example, people in Windows are confused by the red, yellow, green buttons of apple. - uses a limited amount of colors and effects. - is fast. self defaultSettings: nil. self beCurrent. ! !GLMUITheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/31/2012 22:51'! baseColor ^ Color r: 210 g: 210 b: 210 range: 255! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'tg 9/5/2010 20:50'! basePassiveBackgroundColor ^ Color r: 245 g: 245 b: 245 range: 255! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'tg 9/5/2010 21:46'! baseSelectionColor ^ Color r: 97 g: 163 b: 225 range: 255! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/31/2012 22:33'! darkBaseColor ^ Color r: 200 g: 200 b: 200 range: 255! ! !GLMUITheme class methodsFor: 'private' stamp: 'tg 11/5/2010 20:50'! importGlamorousIcons "utility method to import the icons necessary for the theme from the file system" "self importGlamorousIcons" | icons | icons := #( 'glamorousMax' 'glamorousMin' 'glamorousClose' 'glamorousMenu' 'glamorousMaxInactive' 'glamorousMinInactive' 'glamorousCloseInactive' 'glamorousMenuInactive' 'glamorousMenuPin' 'glamorousCheckboxSelected' 'glamorousCheckboxUnselected' 'glamorousRadioSelected' 'glamorousRadioUnselected'). self importIcons: icons fromFolder: 'icons' inClass: GLMUIThemeIcons category: '*glamour-morphic-theme'! ! !GLMUITheme class methodsFor: 'private' stamp: 'tg 9/3/2010 14:28'! importIcons: icons fromFolder: aString inClass: aClass category: aCategory icons do: [:each | | method form | form := PNGReadWriter formFromFileNamed: aString, '/', each , '.png'. method := each , Character cr asString , (aClass methodStart: each), form storeString, aClass methodEnd. aClass class compile: method classified: aCategory ]. aClass initialize! ! !GLMUITheme class methodsFor: 'testing' stamp: 'TudorGirba 4/7/2011 23:45'! isAbstract "Answer whether the receiver is considered to be abstract." ^false! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/31/2012 22:35'! lightBaseColor ^ Color r: 230 g: 230 b: 230 range: 255! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'tg 9/7/2010 13:51'! lightSelectionColor ^ Color r: 175 g: 213 b: 250 range: 255! ! !GLMUITheme class methodsFor: 'settings' stamp: 'TudorGirba 4/2/2013 23:18'! newDefaultSettings self setPreferredPreferences. BalloonMorph setBalloonColorTo: self lightSelectionColor. ^super newDefaultSettings menuColor: self baseColor; menuTitleColor: self baseColor; windowColor: self baseColor; selectionColor: self lightSelectionColor; menuSelectionColor: self baseSelectionColor; progressBarColor: self baseColor; standardColorsOnly: true; autoSelectionColor: false; preferRoundCorner: false; fadedBackgroundWindows: false; secondarySelectionColor: self veryLightSelectionColor; flatMenu: true! ! !GLMUITheme class methodsFor: 'settings' stamp: 'TudorGirba 4/2/2013 23:17'! setPreferredPreferences NECPreferences expandPrefixes: true; popupShowWithShortcut: Character tab asShortcut.! ! !GLMUITheme class methodsFor: 'settings' stamp: 'TudorGirba 2/16/2011 20:56'! setPreferredShoutColors "self setPreferredShoutColors" SHTextStylerST80 styleTable: #( "(symbol color [emphasisSymbolOrArray [textStyleName [pixelHeight]]])" (default black) (invalid red) (excessCode red) (comment (gray darker)) (unfinishedComment (red muchDarker)) (#'$' (red muchDarker)) (character (red muchDarker)) (integer (red muchDarker)) (number (red muchDarker)) (#- (red muchDarker)) (symbol (magenta muchDarker)) (stringSymbol (magenta muchDarker)) (literalArray (magenta muchDarker)) (string (magenta muchDarker) normal) (unfinishedString red normal) (assignment nil) (ansiAssignment nil) (literal nil italic) (keyword (black)) (binary (black)) (unary (black)) (incompleteKeyword red) (incompleteBinary red) (incompleteUnary red ) (undefinedKeyword red) (undefinedBinary red) (undefinedUnary red) (patternKeyword nil bold) (patternBinary nil bold) (patternUnary nil bold) (#self (cyan muchDarker )) (#super (cyan muchDarker )) (#true (red muchDarker)) (#false (red muchDarker)) (#nil (red muchDarker)) (#thisContext (cyan muchDarker )) (#return (cyan muchDarker ) bold) (patternArg (blue muchDarker)) (methodArg (blue muchDarker)) (blockPatternArg (blue muchDarker)) (blockArg (blue muchDarker)) (argument (blue muchDarker)) (blockArgColon black) (leftParenthesis black) (rightParenthesis black) (leftParenthesis1 (green muchDarker)) (rightParenthesis1 (green muchDarker)) (leftParenthesis2 (magenta muchDarker)) (rightParenthesis2 (magenta muchDarker)) (leftParenthesis3 (red muchDarker)) (rightParenthesis3 (red muchDarker)) (leftParenthesis4 (green darker)) (rightParenthesis4 (green darker)) (leftParenthesis5 (orange darker)) (rightParenthesis5 (orange darker)) (leftParenthesis6 (magenta darker)) (rightParenthesis6 (magenta darker)) (leftParenthesis7 blue) (rightParenthesis7 blue) (blockStart black) (blockEnd black) (blockStart1 (green muchDarker)) (blockEnd1 (green muchDarker)) (blockStart2 (magenta muchDarker)) (blockEnd2 (magenta muchDarker)) (blockStart3 (red muchDarker)) (blockEnd3 (red muchDarker)) (blockStart4 (green darker)) (blockEnd4 (green darker)) (blockStart5 (orange darker)) (blockEnd5 (orange darker)) (blockStart6 (magenta darker)) (blockEnd6 (magenta darker)) (blockStart7 blue) (blockEnd7 blue) (arrayStart black) (arrayEnd black) (arrayStart1 black) (arrayEnd1 black) (leftBrace black) (rightBrace black) (cascadeSeparator black) (statementSeparator black) (externalCallType black) (externalCallTypePointerIndicator black) (primitiveOrExternalCallStart black bold) (primitiveOrExternalCallEnd black bold) (methodTempBar (black)) (blockTempBar (black)) (blockArgsBar (black)) (primitive (green muchDarker)) (pragmaKeyword (green muchDarker)) (pragmaUnary (green muchDarker)) (pragmaBinary (green muchDarker)) (externalFunctionCallingConvention (green muchDarker) bold) (module (green muchDarker) bold) (blockTempVar (blue muchDarker)) (blockPatternTempVar (blue muchDarker)) (instVar (blue muchDarker)) (workspaceVar (blue muchDarker)) (undefinedIdentifier red) (incompleteIdentifier red) (tempVar (blue muchDarker)) (patternTempVar (blue muchDarker)) (poolConstant (blue muchDarker)) (classVar (blue muchDarker)) (globalVar (blue muchDarker))) ! ! !GLMUITheme class methodsFor: 'settings' stamp: 'TudorGirba 4/8/2011 00:13'! setPreferredWorldBackground "self setPreferredWorldBackground" World color: Color white! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'tg 1/14/2010 03:12'! themeName ^ 'Glamorous'! ! !GLMUITheme class methodsFor: 'accessing' stamp: 'TudorGirba 11/29/2012 09:19'! veryLightSelectionColor ^ self lightSelectionColor muchLighter! ! !GLMUITheme methodsFor: 'border-styles-buttons' stamp: 'tg 9/4/2010 23:06'! buttonCornerStyleIn: aThemedMorph "If asked, we only allow square corners" ^ #square! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'tg 8/31/2010 08:32'! buttonLabelForText: aTextOrString "Answer the label to use for the given text." ^aTextOrString isString ifTrue: [(LabelMorph contents: aTextOrString) color: Color black] ifFalse: [super buttonLabelForText: aTextOrString]! ! !GLMUITheme methodsFor: 'defaults' stamp: 'tg 9/6/2010 14:04'! buttonMinHeight "Answer the minumum height of a button for this theme." ^24! ! !GLMUITheme methodsFor: 'defaults' stamp: 'tg 9/6/2010 14:04'! buttonMinWidth "Answer the minumum width of a button for this theme." ^24! ! !GLMUITheme methodsFor: 'border-styles-buttons' stamp: 'TudorGirba 4/12/2011 08:18'! buttonNormalBorderStyleFor: aButton "Return the normal button borderStyle for the given button." | outerColor innerColor | (aButton valueOfProperty: #noBorder ifAbsent: [false]) ifTrue: [ ^ SimpleBorder new width: 0; baseColor: Color transparent ]. outerColor := self glamorousDarkBaseColorFor: aButton. ^SimpleBorder new width: 1; baseColor: outerColor! ! !GLMUITheme methodsFor: 'fill-styles-buttons' stamp: 'tg 9/3/2010 12:21'! buttonNormalFillStyleFor: aButton "Return the normal button fillStyle for the given button." (aButton valueOfProperty: #noFill ifAbsent: [false]) ifTrue: [^ SolidFillStyle color: Color transparent ]. ^ self glamorousNormalFillStyleFor: aButton height: aButton height! ! !GLMUITheme methodsFor: 'border-styles-buttons' stamp: 'tg 8/31/2010 11:09'! buttonSelectedBorderStyleFor: aButton ^ self buttonNormalBorderStyleFor: aButton! ! !GLMUITheme methodsFor: 'fill-styles-buttons' stamp: 'tg 9/13/2010 10:37'! buttonSelectedFillStyleFor: aButton "Return the normal button fillStyle for the given button." | top bottom | top := self glamorousLightSelectionColorFor: aButton. bottom := self glamorousLightColorFor: aButton. ^(GradientFillStyle ramp: { 0.0->top. 0.7->bottom.}) origin: aButton bounds origin; direction: 0 @ aButton height; radial: false! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 09:08'! checkboxForm "Answer the form to use for a normal checkbox." ^self checkboxUnselectedForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 14:10'! checkboxSelectedForm "Answer the form to use for a selected checkbox." ^GLMUIThemeIcons checkboxSelectedForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:54'! checkboxUnselectedForm "Answer the form to use for a selected checkbox." ^ GLMUIThemeIcons checkboxUnselectedForm! ! !GLMUITheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/23/2012 14:26'! configureWatcherWindowLabelAreaFor: aWindow "Configure the label area for the given Watcher window." |padding| padding := 0. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0). aWindow hasCloseBox ifTrue: [aWindow addCloseBox. padding := padding + 1]. " aWindow hasCollapseBox ifTrue: [aWindow addCollapseBox. padding := padding + 1]. aWindow hasExpandBox ifTrue: [aWindow addExpandBox. padding := padding + 1]. aWindow hasMenuBox ifTrue: [padding := padding - 1]. " aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). aWindow basicLabel ifNotNil: [:label | aWindow labelArea addMorphBack: label; hResizing: #shrinkWrap]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). padding > 0 ifTrue: [ aWindow labelArea addMorphBack: (Morph new extent: (aWindow boxExtent x * padding) @ 0)]. " aWindow hasMenuBox ifTrue: [aWindow addMenuControl]." aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0)! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'TudorGirba 6/1/2012 19:40'! configureWindowBorderFor: aWindow " super configureWindowBorderFor: aWindow. aWindow roundedCorners: #()" | aStyle | aStyle := SimpleBorder new color: (Color lightGray); width: 1. aWindow borderStyle: aStyle.! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/23/2012 14:24'! configureWindowDropShadowFor: aWindow aWindow hasDropShadow: false! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 00:12'! configureWindowLabelAreaFor: aWindow "Configure the label area for the given window." |padding| padding := 0. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0). aWindow hasCloseBox ifTrue: [aWindow addCloseBox. padding := padding + 1]. aWindow hasCollapseBox ifTrue: [aWindow addCollapseBox. padding := padding + 1]. aWindow hasExpandBox ifTrue: [aWindow addExpandBox. padding := padding + 1]. aWindow hasMenuBox ifTrue: [padding := padding - 1]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). aWindow basicLabel ifNotNil: [:label | aWindow labelArea addMorphBack: label; hResizing: #shrinkWrap]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). padding > 0 ifTrue: [ aWindow labelArea addMorphBack: (Morph new extent: (aWindow boxExtent x * padding) @ 0)]. aWindow hasMenuBox ifTrue: [aWindow addMenuControl]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0)! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 01:17'! createCollapseBoxFor: aSystemWindow "Answer a button for minimising the window." |form msb| form := self windowMinimizeForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizePassiveForm. msb extent: form extent. msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizeOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow collapseBoxHit]; setBalloonText: 'Collapse this window' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 01:17'! createExpandBoxFor: aSystemWindow "Answer a button for maximising/restoring the window." |form msb| form := self windowMaximizeForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizePassiveForm. msb extent: form extent. msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizeOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow expandBoxHit]; setBalloonText: 'Expand to full screen' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'tg 9/3/2010 11:34'! createMenuBoxFor: aSystemWindow "Answer a button for the window menu." " ^aSystemWindow createBox labelGraphic: (self windowMenuIconFor: aSystemWindow); extent: aSystemWindow boxExtent; actWhen: #buttonDown; actionSelector: #offerWindowMenu; setBalloonText: 'window menu' translated" |form msb| form := self windowMenuForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuPassiveForm. msb extent: form extent. msb activeDisabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveDisabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuPassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow offerWindowMenu]; setBalloonText: 'window menu' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMUITheme methodsFor: 'defaults' stamp: 'TudorGirba 7/26/2011 12:08'! dialogWindowPreferredCornerStyleFor: aDialogWindow "Answer the preferred corner style for the given dialog." ^#square! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/3/2010 12:30'! dockingBarNormalFillStyleFor: aToolDockingBar ^ SolidFillStyle color: Color transparent! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:47'! dropListDisabledFillStyleFor: aDropList "Return the disabled fillStyle for the given drop list." ^ self textEditorDisabledFillStyleFor: aDropList! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/4/2010 22:55'! dropListNormalBorderStyleFor: aDropList "Return the normal borderStyle for the given drop list" ^ self buttonNormalBorderStyleFor: aDropList! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/4/2010 23:04'! dropListNormalFillStyleFor: aDropList "Return the normal fillStyle for the given drop list." ^ SolidFillStyle color: Color white! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 1/25/2011 15:39'! expanderTitleNormalFillStyleFor: anExpanderTitle "Return the normal expander title fillStyle for the given expander title." ^ self buttonNormalFillStyleFor: anExpanderTitle! ! !GLMUITheme methodsFor: 'private' stamp: 'tg 9/3/2010 12:32'! glamorousBaseColorFor: aButton ^ self class baseColor "unfortunately, it looks like paneColor does not always return the wanted color" "aButton paneColorOrNil ifNil: [Color r: 200 g: 200 b: 200 range: 255]"! ! !GLMUITheme methodsFor: 'private' stamp: 'tg 9/5/2010 20:40'! glamorousBasePassiveBackgroundColorFor: aButton ^ self class basePassiveBackgroundColor! ! !GLMUITheme methodsFor: 'private' stamp: 'tg 9/5/2010 20:40'! glamorousBaseSelectionColorFor: aButton ^ self class baseSelectionColor! ! !GLMUITheme methodsFor: 'private' stamp: 'tg 9/9/2010 22:50'! glamorousDarkBaseColorFor: aButton ^ self class darkBaseColor! ! !GLMUITheme methodsFor: 'private' stamp: 'tg 9/9/2010 22:02'! glamorousLightColorFor: aButton ^ self class lightBaseColor! ! !GLMUITheme methodsFor: 'private' stamp: 'TudorGirba 4/12/2011 08:24'! glamorousLightSelectionColorFor: aMorph ^ self class lightSelectionColor! ! !GLMUITheme methodsFor: 'private' stamp: 'TudorGirba 4/11/2011 21:25'! glamorousNormalFillStyleFor: aMorph height: anInteger "Return the normal button fillStyle for the given button." " | baseColor | baseColor := self glamorousBaseColorFor: aMorph. ^ self glamorousNormalFillStyleWithBaseColor: baseColor for: aMorph height: anInteger " ^ SolidFillStyle color: (self glamorousLightColorFor: aMorph)! ! !GLMUITheme methodsFor: 'private' stamp: 'TudorGirba 4/11/2011 01:37'! glamorousNormalFillStyleWithBaseColor: aColor for: aMorph height: anInteger | top bottom | top := aColor darker. bottom := aColor. ^(GradientFillStyle ramp: { 0.0->top. 0.7->bottom.}) origin: aMorph bounds origin; direction: 0 @ anInteger; radial: false! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/9/2010 23:51'! groupPanelBorderStyleFor: aGroupPanel "Answer the normal border style for a group panel." ^ SimpleBorder new width: 1; baseColor: ((self glamorousBaseColorFor: aGroupPanel))! ! !GLMUITheme methodsFor: 'growl - specific' stamp: 'TudorGirba 4/18/2012 09:32'! growlBorderColorFor: aGrowlMorph ^ Color white alpha: 0.5! ! !GLMUITheme methodsFor: 'growl - specific' stamp: 'TudorGirba 4/17/2012 15:00'! growlContentsColorFor: aGrowlMorph ^ Color white! ! !GLMUITheme methodsFor: 'growl - specific' stamp: 'TudorGirba 4/18/2012 09:16'! growlDismissHandleFor: aGrowlMorph | form image | form := self windowCloseForm. image := ImageMorph new. image image: form. image color: Color yellow. ^ image! ! !GLMUITheme methodsFor: 'growl - specific' stamp: 'TudorGirba 4/18/2012 09:30'! growlFillColorFor: aGrowlMorph ^ Color darkGray alpha: 0.5! ! !GLMUITheme methodsFor: 'growl - specific' stamp: 'TudorGirba 4/18/2012 09:12'! growlLabelColorFor: aGrowlMorph ^ Color white twiceDarker! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/23/2012 14:22'! initialize "self beCurrent" super initialize. self windowActiveDropShadowStyle: #diffuse! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'TudorGirba 4/8/2011 01:09'! initializeForms "Initialize the receiver's image forms." |inactiveForm| super initializeForms. inactiveForm := self newWindowInactiveControlForm. self forms at: #windowCloseOver put: self newWindowCloseOverForm; at: #windowMinimizeOver put: self newWindowMinimizeOverForm; at: #windowMaximizeOver put: self newWindowMaximizeOverForm; at: #windowClosePassive put: inactiveForm; at: #windowMinimizePassive put: inactiveForm; at: #windowMaximizePassive put: inactiveForm! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:48'! listDisabledFillStyleFor: aList "Return the disabled fillStyle for the given list." ^ self textEditorDisabledFillStyleFor: aList! ! !GLMUITheme methodsFor: 'fill-styles-buttons' stamp: 'tg 9/10/2010 08:12'! menuItemInDockingBarSelectedFillStyleFor: aMenuItem "Answer the selected fill style to use for the given menu item that is in a docking bar." ^ self buttonSelectedFillStyleFor: aMenuItem! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 09:09'! menuPinForm "Answer the form to use for the pin button of a menu." ^ GLMUIThemeIcons menuPinForm! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 8/21/2011 16:47'! morphTreeSplitterNormalFillStyleFor: aSplitter ^ self splitterNormalFillStyleFor: aSplitter! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 8/21/2011 16:49'! morphTreeSplitterPressedFillStyleFor: aSplitter ^ self splitterPressedFillStyleFor: aSplitter! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 09:09'! newCheckboxMarkerForm "Answer a new checkbox marker form." ^GLMUIThemeIcons checkboxMarkerForm! ! !GLMUITheme methodsFor: 'morph creation' stamp: 'TudorGirba 4/8/2011 01:15'! newCloseControlIn: aThemedMorph for: aModel action: aValuable help: helpText "Answer a button for closing things." |form msb| form := self windowCloseForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowClosePassiveForm. msb extent: form extent. msb activeDisabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveDisabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowCloseOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowClosePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: aValuable; setBalloonText: helpText. ^msb! ! !GLMUITheme methodsFor: 'morph creation' stamp: 'tg 9/5/2010 21:28'! newFocusIndicatorMorphFor: aMorph "Answer a new focus indicator for the given morph." |radius| radius := aMorph focusIndicatorCornerRadius. ^ BorderedMorph new fillStyle: Color transparent; borderStyle: (SimpleBorder new width: 1; baseColor: (self glamorousBaseSelectionColorFor: aMorph)); bounds: aMorph focusBounds! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 09:46'! newRadioButtonMarkerForm "Answer a new radio button marker form. We make it empty because we already have the selected radio button take care of the state." ^GLMUIThemeIcons radioButtonMarkerForm ! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'tg 9/6/2010 14:38'! newRadioMarkerForm "Answer a new checkbox marker form." ^Form extent: 12@12 depth: 32! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'TudorGirba 4/8/2011 01:06'! newTreeExpandedForm "Answer a new form for an expanded tree item." ^(Form extent: 9@9 depth: 32 fromArray: #( 1049135240 2290649224 2290649224 2290649224 2290649224 2290649224 2290649224 2290649224 1200130184 478709896 4169697416 4287137928 4287137928 4287137928 4287137928 4287137928 4236806280 646482056 16777215 2508753032 4287137928 4287137928 4287137928 4287137928 4287137928 2726856840 16777215 16777215 495487112 4186474632 4287137928 4287137928 4287137928 4236806280 612927624 16777215 16777215 16777215 2542307464 4287137928 4287137928 4287137928 2676525192 16777215 16777215 16777215 16777215 478709896 4169697416 4287137928 4220029064 579373192 16777215 16777215 16777215 16777215 16777215 2424866952 4287137928 2626193544 16777215 16777215 16777215 16777215 16777215 16777215 394823816 4018702472 529041544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 864585864 16777215 16777215 16777215 16777215) offset: 0@0)! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'TudorGirba 4/8/2011 01:06'! newTreeUnexpandedForm "Answer a new form for an unexpanded tree item." ^(Form extent: 9@9 depth: 32 fromArray: #( 1049135240 461932680 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2324203656 4152920200 2458421384 428378248 16777215 16777215 16777215 16777215 16777215 2357758088 4287137928 4287137928 4152920200 2408089736 394823816 16777215 16777215 16777215 2391312520 4287137928 4287137928 4287137928 4287137928 4119365768 2324203656 344492168 16777215 2408089736 4287137928 4287137928 4287137928 4287137928 4287137928 4287137928 3968370824 780699784 2391312520 4287137928 4287137928 4287137928 4287137928 4236806280 2659747976 529041544 16777215 2357758088 4287137928 4287137928 4253583496 2810742920 646482056 16777215 16777215 16777215 2324203656 4253583496 2777188488 696813704 16777215 16777215 16777215 16777215 16777215 1200130184 663259272 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: 0@0)! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:05'! newWindowCloseForm "Answer a new form for a window close box." ^ GLMUIThemeIcons windowCloseForm ! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 14:18'! newWindowCloseOverForm "Answer a new form for a window menu box." ^ self newWindowCloseForm! ! !GLMUITheme methodsFor: 'initialize-release' stamp: 'TudorGirba 4/8/2011 01:08'! newWindowInactiveControlForm "Answer a new form for an inactive window control box." ^(Form extent: 16@16 depth: 32 fromArray: #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4291677645 4288585374 4286085240 4284243036 4284243036 4286085240 4288585374 4291677645 0 0 0 0 0 0 0 4289572269 4285756275 4286479998 4288716960 4289835441 4289835441 4288716960 4286479998 4285756275 4289572269 0 0 0 0 0 4289506476 4284835173 4287335307 4290559164 4292598747 4293322470 4293322470 4292598747 4290559164 4287335307 4284703587 4289506476 0 0 0 4291546059 4285493103 4286414205 4288980132 4291217094 4292335575 4292598747 4292598747 4292335575 4291282887 4288980132 4286282619 4285493103 4291546059 0 0 4288980132 4285361517 4287466893 4288782753 4289835441 4290295992 4290295992 4290427578 4290164406 4289835441 4288782753 4287466893 4285361517 4288980132 0 0 4286282619 4286611584 4288059030 4288716960 4289177511 4289572269 4289835441 4289835441 4289703855 4289374890 4288782753 4288059030 4286611584 4286282619 0 0 4285164138 4287664272 4288782753 4289374890 4289835441 4290427578 4290624957 4290624957 4290559164 4290032820 4289374890 4288914339 4287664272 4285164138 0 0 4285361517 4288322202 4289703855 4290295992 4290822336 4291414473 4291677645 4291677645 4291414473 4291085508 4290427578 4289703855 4288453788 4285624689 0 0 4287072135 4288716960 4290427578 4291217094 4291677645 4292203989 4292598747 4292598747 4292335575 4291809231 4291217094 4290427578 4288716960 4287203721 0 0 4288980132 4288256409 4290624957 4291677645 4292335575 4292927712 4293256677 4293256677 4293059298 4292598747 4291809231 4290822336 4288256409 4289177511 0 0 4291677645 4287664272 4290295992 4292006610 4293059298 4293454056 4293585642 4293585642 4293454056 4293125091 4292203989 4290427578 4287730065 4291677645 0 0 4293256677 4290032820 4288124823 4291217094 4292796126 4293322470 4293717228 4293717228 4293454056 4292927712 4291677645 4288256409 4290032820 4293256677 0 0 0 4293454056 4290032820 4288322202 4289967027 4291546059 4292598747 4292664540 4291677645 4290295992 4288716960 4290032820 4293454056 0 0 0 0 0 4293322470 4292203989 4289835441 4288782753 4288322202 4288453788 4288980132 4289835441 4292335575 4293322470 0 0 0 0 0 0 0 4293059298 4293585642 4293717228 4293585642 4293585642 4293585642 4293585642 4293059298 0 0 0 0) offset: 0@0)! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:06'! newWindowMaximizeForm "Answer a new form for a window maximize box." ^ GLMUIThemeIcons windowMaximizeForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 14:18'! newWindowMaximizeOverForm "Answer a new form for a window menu box." ^ self newWindowMaximizeForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:08'! newWindowMenuForm "Answer a new form for a window menu box." ^ GLMUIThemeIcons windowMenuForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:15'! newWindowMenuPassiveForm "Answer a new form for a window menu box." ^ GLMUIThemeIcons windowMenuInactiveForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:10'! newWindowMinimizeForm "Answer a new form for a window minimize box." ^ GLMUIThemeIcons windowMinimizeForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 15:09'! newWindowMinimizeOverForm "Answer a new form for a window menu box." ^ self newWindowMinimizeForm! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/3/2010 14:50'! plainGroupPanelBorderStyleFor: aGroupPanel "Answer the normal border style for a plain group panel." ^SimpleBorder new width: 1; baseColor: Color transparent! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:51'! progressBarFillStyleFor: aProgressBar ^ self glamorousBasePassiveBackgroundColorFor: aProgressBar! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/7/2010 13:52'! progressBarProgressFillStyleFor: aProgressBar ^ (self glamorousLightSelectionColorFor: aProgressBar)! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 4/14/2011 10:28'! progressFillStyleFor: aProgress "Return the progress fillStyle for the given progress morph." ^ self windowActiveFillStyleFor: aProgress ! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 14:11'! radioButtonForm "Answer the form to use for a normal radio button." ^ GLMUIThemeIcons radioButtonUnselectedForm! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 14:11'! radioButtonSelectedForm "Answer the form to use for a selected radio button." ^ GLMUIThemeIcons radioButtonSelectedForm ! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 1/14/2010 03:10'! resizerGripNormalFillStyleFor: aResizer "Return the normal fillStyle for the given resizer. For the moment, answer a transparent colour for no drawing, non transparent to draw as normal." ^Color transparent! ! !GLMUITheme methodsFor: 'scrollbars' stamp: 'TudorGirba 5/19/2013 14:46'! scrollBarButtonArrowVertices: aRectangle ^ self verticesForSimpleArrow: aRectangle! ! !GLMUITheme methodsFor: 'fill-styles-scrollbars' stamp: 'tg 9/13/2010 10:52'! scrollbarNormalButtonFillStyleFor: aScrollbar "Return the normal scrollbar button fillStyle for the given scrollbar." ^ self scrollbarNormalThumbFillStyleFor: aScrollbar! ! !GLMUITheme methodsFor: 'fill-styles-scrollbars' stamp: 'tg 9/4/2010 21:03'! scrollbarNormalFillStyleFor: aScrollbar "Return the normal scrollbar fillStyle for the given scrollbar." ^ "(self glamorousBaseColorFor: aScrollbar) muchLighter" Color r: 245 g: 245 b: 245 range: 255! ! !GLMUITheme methodsFor: 'border-styles-scrollbars' stamp: 'TudorGirba 4/8/2011 00:01'! scrollbarNormalThumbBorderStyleFor: aScrollbar "Return the normal thumb borderStyle for the given scrollbar." ^ BorderStyle simple width: 0; baseColor: Color transparent! ! !GLMUITheme methodsFor: 'fill-styles-scrollbars' stamp: 'TudorGirba 4/11/2011 01:38'! scrollbarNormalThumbFillStyleFor: aScrollbar "Return the normal scrollbar fillStyle for the given scrollbar." "^ (self glamorousNormalFillStyleWithBaseColor: aScrollbar paneColor for: aScrollbar height: aScrollbar height) direction: (aScrollbar bounds isWide ifTrue: [0 @ aScrollbar height] ifFalse: [aScrollbar width @ 0])" ^ self glamorousNormalFillStyleFor: aScrollbar height: aScrollbar height! ! !GLMUITheme methodsFor: 'border-styles-scrollbars' stamp: 'tg 8/31/2010 13:27'! scrollbarPagingAreaCornerStyleIn: aThemedMorph ^#square! ! !GLMUITheme methodsFor: 'border-styles-scrollbars' stamp: 'tg 8/31/2010 13:27'! scrollbarThumbCornerStyleIn: aThemedMorph ^#square! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/4/2010 23:14'! separatorFillStyleFor: aSeparator "Return the separator fillStyle for the given separator." ^ SolidFillStyle color: (self glamorousBaseColorFor: aSeparator) darker! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:48'! sliderDisabledFillStyleFor: aSlider "Return the disabled fillStyle for the given slider." ^ self textEditorDisabledFillStyleFor: aSlider! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:41'! splitterNormalFillStyleFor: aSplitter "Return the normal splitter fillStyle for the given splitter." ^ SolidFillStyle color: Color transparent! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 8/21/2011 16:46'! splitterPressedFillStyleFor: aSplitter "Return the pressed splitter fillStyle for the given splitter." |aColor| aColor := self glamorousBaseColorFor: aSplitter. ^ (GradientFillStyle ramp: {0.0->aColor lighter. 0.9-> aColor}) origin: aSplitter topLeft; direction: (aSplitter splitsTopAndBottom ifTrue: [0 @ aSplitter height] ifFalse: [aSplitter width @ 0]); radial: false! ! !GLMUITheme methodsFor: 'basic-colors' stamp: 'tg 9/13/2010 10:36'! subgroupColorFrom: paneColor "Answer the colour for a subgroup given the pane colour." ^ self glamorousLightColorFor: paneColor" self class baseColor"! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 8/31/2010 15:28'! tabLabelNormalBorderStyleFor: aTabLabel " ^SimpleBorder new width: 0; baseColor: (self buttonBaseColorFor: aTabLabel) darker " ^ self buttonNormalBorderStyleFor: aTabLabel! ! !GLMUITheme methodsFor: 'fill-styles-buttons' stamp: 'tg 8/31/2010 11:13'! tabLabelNormalFillStyleFor: aTabLabel ^ self buttonNormalFillStyleFor: aTabLabel ! ! !GLMUITheme methodsFor: 'fill-styles-buttons' stamp: 'tg 8/31/2010 11:13'! tabLabelSelectedFillStyleFor: aTabLabel ^ self buttonSelectedFillStyleFor: aTabLabel ! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/13/2010 10:38'! tabPanelBorderStyleFor: aTabGroup ^ GLMTabPanelBorder new width: 1; baseColor: ((self glamorousDarkBaseColorFor: aTabGroup)); tabSelector: aTabGroup tabSelectorMorph! ! !GLMUITheme methodsFor: 'basic-colors' stamp: 'tg 9/6/2010 15:03'! taskbarButtonLabelColorFor: aButton "Answer the colour for the label of the given taskbar button." ^aButton model ifNil: [super taskbarButtonLabelColorFor: aButton] ifNotNil: [:win | win isActive ifTrue: [Color black] ifFalse: [Color gray darker]]! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/23/2012 15:32'! taskbarFillStyleFor: aTaskbar ^ "self buttonNormalFillStyleFor: aTaskbar" SolidFillStyle color: Color transparent ! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/4/2010 20:23'! taskbarThumbnailCornerStyleFor: aMorph "Answer the corner style for the taskbar thumbnail/tasklist." ^#square! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/4/2010 20:56'! taskbarThumbnailNormalBorderStyleFor: aWindow ^ self buttonNormalBorderStyleFor: aWindow! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/5/2010 20:46'! textEditorDisabledFillStyleFor: aTextEditor "Return the disabled fillStyle for the given text editor." ^self glamorousBasePassiveBackgroundColorFor: aTextEditor! ! !GLMUITheme methodsFor: 'border-styles' stamp: 'tg 9/4/2010 23:09'! textEditorNormalBorderStyleFor: aTextEditor "Return the normal text editor borderStyle for the given text editor." ^self buttonNormalBorderStyleFor: aTextEditor! ! !GLMUITheme methodsFor: 'basic-colors' stamp: 'TudorGirba 4/8/2011 00:02'! treeLineWidth "Answer the width of the tree lines." ^0! ! !GLMUITheme methodsFor: 'scrollbars' stamp: 'tg 9/4/2010 20:16'! verticesForSimpleArrow: aRectangle "PRIVATE - answer a collection of vertices to draw a simple arrow" | vertices | vertices := OrderedCollection new. "" vertices add: aRectangle bottomLeft. vertices add: aRectangle center x @ (aRectangle top + (aRectangle width / 8)). vertices add: aRectangle bottomRight. vertices add: aRectangle bottomRight + (0@0.01). "" ^ vertices " | vertices | vertices := OrderedCollection new. vertices add: (aRectangle center x - (aRectangle width / 4)) @ (aRectangle bottom - 8). vertices add: aRectangle center x @ (aRectangle top). vertices add: (aRectangle center x + (aRectangle width / 4)) @ (aRectangle bottom - 8). vertices add: (aRectangle center x + (aRectangle width / 4)) @ (aRectangle bottom - 8) + (0@0.01). ^ vertices" " ^ super verticesForSimpleArrow: aRectangle "! ! !GLMUITheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/23/2012 14:09'! watcherWindowActiveFillStyleFor: aWindow ^ SolidFillStyle color: (Color veryVeryLightGray alpha: 0.6)! ! !GLMUITheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/23/2012 14:10'! watcherWindowInactiveFillStyleFor: aWindow ^ SolidFillStyle color: (Color veryVeryLightGray alpha: 0.6)! ! !GLMUITheme methodsFor: 'accessing' stamp: 'TudorGirba 4/7/2011 23:46'! windowActiveDropShadowStyle: anObject "Set the value of windowActiveDropShadowStyle" windowActiveDropShadowStyle := anObject! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/31/2012 22:28'! windowActiveFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^SolidFillStyle color: self class baseColor! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/31/2012 22:51'! windowActiveTitleFillStyleFor: aWindow ^ "self glamorousNormalFillStyleFor: aWindow height: aWindow labelHeight" SolidFillStyle color: Color transparent! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 01:13'! windowCloseOverForm "Answer the form to use for mouse over window close buttons" ^self forms at: #windowCloseOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:17'! windowClosePassiveForm "Answer the form to use for passive (background) window close buttons" ^GLMUIThemeIcons windowCloseInactiveForm! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'tg 9/2/2010 13:52'! windowInactiveFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^self windowActiveFillStyleFor: aWindow! ! !GLMUITheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/31/2012 22:51'! windowInactiveTitleFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^ SolidFillStyle color: Color transparent! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 01:14'! windowMaximizeOverForm "Answer the form to use for mouse over window maximize buttons" ^self forms at: #windowMaximizeOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:18'! windowMaximizePassiveForm "Answer the form to use for passive (background) window maximize/restore buttons" ^GLMUIThemeIcons windowMaximizeInactiveForm! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'tg 9/3/2010 10:52'! windowMenuPassiveForm "Answer the form to use for passive (background) window menu buttons" ^self newWindowMenuPassiveForm! ! !GLMUITheme methodsFor: 'label-styles' stamp: 'TudorGirba 4/8/2011 01:14'! windowMinimizeOverForm "Answer the form to use for mouse over window minimize buttons" ^self forms at: #windowMinimizeOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMUITheme methodsFor: 'forms' stamp: 'FernandoOlivero 10/28/2010 13:18'! windowMinimizePassiveForm "Answer the form to use for passive (background) window minimize buttons" ^GLMUIThemeIcons windowMinimizeInactiveForm! ! !GLMUITheme methodsFor: 'defaults' stamp: 'TudorGirba 5/19/2013 21:26'! windowShadowColor "Answer the window shadow color to use." ^ Color gray! ! !GLMWhitespaceTheme commentStamp: '' prior: 34264514! The theme is developed in the context of the Glamour project, and its goal is to create a look that: - does not look like a specific operating system. - maximizes whitespace. - is fast. PolymorphSystemSettings desktopColor: Color white. self defaultSettings: nil. self beCurrent.! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! baseColor ^ Color white"Color r: 210 g: 210 b: 210 range: 255"! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! basePassiveBackgroundColor ^ Color r: 245 g: 245 b: 245 range: 255! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! baseSelectionColor ^ Color r: 97 g: 163 b: 225 range: 255! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2013 06:30'! darkBaseColor ^ Color r: 210 g: 210 b: 210 range: 255! ! !GLMWhitespaceTheme class methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! importGlamorousIcons "utility method to import the icons necessary for the theme from the file system" "self importGlamorousIcons" | icons | icons := #( 'glamorousMax' 'glamorousMin' 'glamorousClose' 'glamorousMenu' 'glamorousMaxInactive' 'glamorousMinInactive' 'glamorousCloseInactive' 'glamorousMenuInactive' 'glamorousMenuPin' 'glamorousCheckboxSelected' 'glamorousCheckboxUnselected' 'glamorousRadioSelected' 'glamorousRadioUnselected'). self importIcons: icons fromFolder: 'icons' inClass: GLMUIThemeIcons category: '*glamour-morphic-theme'! ! !GLMWhitespaceTheme class methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! importIcons: icons fromFolder: aString inClass: aClass category: aCategory icons do: [:each | | method form | form := PNGReadWriter formFromFileNamed: aString, '/', each , '.png'. method := each , Character cr asString , (aClass methodStart: each), form storeString, aClass methodEnd. aClass class compile: method classified: aCategory ]. aClass initialize! ! !GLMWhitespaceTheme class methodsFor: 'testing' stamp: 'TudorGirba 5/16/2013 22:10'! isAbstract "Answer whether the receiver is considered to be abstract." ^false! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! lightBaseColor ^ Color r: 240 g: 240 b: 240 range: 255! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! lightSelectionColor ^ Color r: 175 g: 213 b: 250 range: 255! ! !GLMWhitespaceTheme class methodsFor: 'settings' stamp: 'TudorGirba 5/20/2013 06:34'! newDefaultSettings self setPreferredPreferences. BalloonMorph setBalloonColorTo: self veryLightSelectionColor. ^super newDefaultSettings menuColor: self baseColor; menuTitleColor: self baseColor; windowColor: self baseColor; selectionColor: self lightSelectionColor; menuSelectionColor: self baseSelectionColor; progressBarColor: self baseColor; standardColorsOnly: true; autoSelectionColor: false; preferRoundCorner: false; fadedBackgroundWindows: false; secondarySelectionColor: self veryLightSelectionColor; flatMenu: true! ! !GLMWhitespaceTheme class methodsFor: 'settings' stamp: 'TudorGirba 5/16/2013 22:10'! setPreferredPreferences NECPreferences expandPrefixes: true; popupShowWithShortcut: Character tab asShortcut.! ! !GLMWhitespaceTheme class methodsFor: 'settings' stamp: 'TudorGirba 5/16/2013 22:10'! setPreferredShoutColors "self setPreferredShoutColors" SHTextStylerST80 styleTable: #( "(symbol color [emphasisSymbolOrArray [textStyleName [pixelHeight]]])" (default black) (invalid red) (excessCode red) (comment (gray darker)) (unfinishedComment (red muchDarker)) (#'$' (red muchDarker)) (character (red muchDarker)) (integer (red muchDarker)) (number (red muchDarker)) (#- (red muchDarker)) (symbol (magenta muchDarker)) (stringSymbol (magenta muchDarker)) (literalArray (magenta muchDarker)) (string (magenta muchDarker) normal) (unfinishedString red normal) (assignment nil) (ansiAssignment nil) (literal nil italic) (keyword (black)) (binary (black)) (unary (black)) (incompleteKeyword red) (incompleteBinary red) (incompleteUnary red ) (undefinedKeyword red) (undefinedBinary red) (undefinedUnary red) (patternKeyword nil bold) (patternBinary nil bold) (patternUnary nil bold) (#self (cyan muchDarker )) (#super (cyan muchDarker )) (#true (red muchDarker)) (#false (red muchDarker)) (#nil (red muchDarker)) (#thisContext (cyan muchDarker )) (#return (cyan muchDarker ) bold) (patternArg (blue muchDarker)) (methodArg (blue muchDarker)) (blockPatternArg (blue muchDarker)) (blockArg (blue muchDarker)) (argument (blue muchDarker)) (blockArgColon black) (leftParenthesis black) (rightParenthesis black) (leftParenthesis1 (green muchDarker)) (rightParenthesis1 (green muchDarker)) (leftParenthesis2 (magenta muchDarker)) (rightParenthesis2 (magenta muchDarker)) (leftParenthesis3 (red muchDarker)) (rightParenthesis3 (red muchDarker)) (leftParenthesis4 (green darker)) (rightParenthesis4 (green darker)) (leftParenthesis5 (orange darker)) (rightParenthesis5 (orange darker)) (leftParenthesis6 (magenta darker)) (rightParenthesis6 (magenta darker)) (leftParenthesis7 blue) (rightParenthesis7 blue) (blockStart black) (blockEnd black) (blockStart1 (green muchDarker)) (blockEnd1 (green muchDarker)) (blockStart2 (magenta muchDarker)) (blockEnd2 (magenta muchDarker)) (blockStart3 (red muchDarker)) (blockEnd3 (red muchDarker)) (blockStart4 (green darker)) (blockEnd4 (green darker)) (blockStart5 (orange darker)) (blockEnd5 (orange darker)) (blockStart6 (magenta darker)) (blockEnd6 (magenta darker)) (blockStart7 blue) (blockEnd7 blue) (arrayStart black) (arrayEnd black) (arrayStart1 black) (arrayEnd1 black) (leftBrace black) (rightBrace black) (cascadeSeparator black) (statementSeparator black) (externalCallType black) (externalCallTypePointerIndicator black) (primitiveOrExternalCallStart black bold) (primitiveOrExternalCallEnd black bold) (methodTempBar (black)) (blockTempBar (black)) (blockArgsBar (black)) (primitive (green muchDarker)) (pragmaKeyword (green muchDarker)) (pragmaUnary (green muchDarker)) (pragmaBinary (green muchDarker)) (externalFunctionCallingConvention (green muchDarker) bold) (module (green muchDarker) bold) (blockTempVar (blue muchDarker)) (blockPatternTempVar (blue muchDarker)) (instVar (blue muchDarker)) (workspaceVar (blue muchDarker)) (undefinedIdentifier red) (incompleteIdentifier red) (tempVar (blue muchDarker)) (patternTempVar (blue muchDarker)) (poolConstant (blue muchDarker)) (classVar (blue muchDarker)) (globalVar (blue muchDarker))) ! ! !GLMWhitespaceTheme class methodsFor: 'settings' stamp: 'TudorGirba 5/16/2013 22:10'! setPreferredWorldBackground "self setPreferredWorldBackground" World color: Color white! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! themeName ^ 'Glamorous'! ! !GLMWhitespaceTheme class methodsFor: 'accessing' stamp: 'TudorGirba 5/19/2013 21:49'! veryLightSelectionColor ^ Color white darker! ! !GLMWhitespaceTheme methodsFor: 'border-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! buttonCornerStyleIn: aThemedMorph "If asked, we only allow square corners" ^ #square! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! buttonLabelForText: aTextOrString "Answer the label to use for the given text." ^aTextOrString isString ifTrue: [(LabelMorph contents: aTextOrString) color: Color black] ifFalse: [super buttonLabelForText: aTextOrString]! ! !GLMWhitespaceTheme methodsFor: 'defaults' stamp: 'TudorGirba 5/16/2013 22:10'! buttonMinHeight "Answer the minumum height of a button for this theme." ^24! ! !GLMWhitespaceTheme methodsFor: 'defaults' stamp: 'TudorGirba 5/16/2013 22:10'! buttonMinWidth "Answer the minumum width of a button for this theme." ^24! ! !GLMWhitespaceTheme methodsFor: 'border-styles-buttons' stamp: 'TudorGirba 5/19/2013 22:44'! buttonNormalBorderStyleFor: aButton "Return the normal button borderStyle for the given button." (aButton valueOfProperty: #noBorder ifAbsent: [false]) ifTrue: [ ^ SimpleBorder new width: 0; baseColor: Color transparent ]. ^ self glamorousLightBorderFor: aButton! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! buttonNormalFillStyleFor: aButton "Return the normal button fillStyle for the given button." (aButton valueOfProperty: #noFill ifAbsent: [false]) ifTrue: [^ SolidFillStyle color: Color transparent ]. ^ self glamorousNormalFillStyleFor: aButton height: aButton height! ! !GLMWhitespaceTheme methodsFor: 'border-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! buttonSelectedBorderStyleFor: aButton ^ self buttonNormalBorderStyleFor: aButton! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-buttons' stamp: 'TudorGirba 5/19/2013 14:06'! buttonSelectedFillStyleFor: aButton "Return the normal button fillStyle for the given button." | top bottom | top := self glamorousLightSelectionColorFor: aButton. bottom := self glamorousBaseColorFor: aButton. ^(GradientFillStyle ramp: { 0.0->top. 0.7->bottom.}) origin: aButton bounds origin; direction: 0 @ aButton height; radial: false! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! checkboxForm "Answer the form to use for a normal checkbox." ^self checkboxUnselectedForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! checkboxSelectedForm "Answer the form to use for a selected checkbox." ^GLMUIThemeIcons checkboxSelectedForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! checkboxUnselectedForm "Answer the form to use for a selected checkbox." ^ GLMUIThemeIcons checkboxUnselectedForm! ! !GLMWhitespaceTheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/19/2013 21:18'! configureWatcherWindowLabelAreaFor: aWindow "Configure the label area for the given Watcher window." |padding| padding := 0. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0). aWindow hasCloseBox ifTrue: [aWindow addCloseBox. padding := padding + 1]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). aWindow basicLabel ifNotNil: [:label | aWindow labelArea addMorphBack: label; hResizing: #shrinkWrap]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). padding > 0 ifTrue: [ aWindow labelArea addMorphBack: (Morph new extent: (aWindow boxExtent x * padding) @ 0)]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0)! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/21/2013 20:57'! configureWindowBorderFor: aWindow ^ self glamorousThickBorderFor: aWindow! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/19/2013 14:14'! configureWindowDropShadowFor: aWindow aWindow hasDropShadow: false! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! configureWindowLabelAreaFor: aWindow "Configure the label area for the given window." |padding| padding := 0. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0). aWindow hasCloseBox ifTrue: [aWindow addCloseBox. padding := padding + 1]. aWindow hasCollapseBox ifTrue: [aWindow addCollapseBox. padding := padding + 1]. aWindow hasExpandBox ifTrue: [aWindow addExpandBox. padding := padding + 1]. aWindow hasMenuBox ifTrue: [padding := padding - 1]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). aWindow basicLabel ifNotNil: [:label | aWindow labelArea addMorphBack: label; hResizing: #shrinkWrap]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0; hResizing: #spaceFill). padding > 0 ifTrue: [ aWindow labelArea addMorphBack: (Morph new extent: (aWindow boxExtent x * padding) @ 0)]. aWindow hasMenuBox ifTrue: [aWindow addMenuControl]. aWindow labelArea addMorphBack: (Morph new extent: aWindow class borderWidth @ 0)! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! createCollapseBoxFor: aSystemWindow "Answer a button for minimising the window." |form msb| form := self windowMinimizeForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizePassiveForm. msb extent: form extent. msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizeOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMinimizePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow collapseBoxHit]; setBalloonText: 'Collapse this window' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! createExpandBoxFor: aSystemWindow "Answer a button for maximising/restoring the window." |form msb| form := self windowMaximizeForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizePassiveForm. msb extent: form extent. msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizeOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMaximizePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow expandBoxHit]; setBalloonText: 'Expand to full screen' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! createMenuBoxFor: aSystemWindow "Answer a button for the window menu." " ^aSystemWindow createBox labelGraphic: (self windowMenuIconFor: aSystemWindow); extent: aSystemWindow boxExtent; actWhen: #buttonDown; actionSelector: #offerWindowMenu; setBalloonText: 'window menu' translated" |form msb| form := self windowMenuForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuPassiveForm. msb extent: form extent. msb activeDisabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveDisabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowMenuPassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: [aSystemWindow offerWindowMenu]; setBalloonText: 'window menu' translated; extent: aSystemWindow boxExtent. ^msb! ! !GLMWhitespaceTheme methodsFor: 'defaults' stamp: 'TudorGirba 5/16/2013 22:10'! dialogWindowPreferredCornerStyleFor: aDialogWindow "Answer the preferred corner style for the given dialog." ^#square! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! dockingBarNormalFillStyleFor: aToolDockingBar ^ SolidFillStyle color: Color transparent! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! dropListDisabledFillStyleFor: aDropList "Return the disabled fillStyle for the given drop list." ^ self textEditorDisabledFillStyleFor: aDropList! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/16/2013 22:10'! dropListNormalBorderStyleFor: aDropList "Return the normal borderStyle for the given drop list" ^ self buttonNormalBorderStyleFor: aDropList! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! dropListNormalFillStyleFor: aDropList "Return the normal fillStyle for the given drop list." ^ SolidFillStyle color: Color white! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! expanderTitleNormalFillStyleFor: anExpanderTitle "Return the normal expander title fillStyle for the given expander title." ^ self buttonNormalFillStyleFor: anExpanderTitle! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousBaseColorFor: aButton ^ self class baseColor "unfortunately, it looks like paneColor does not always return the wanted color" "aButton paneColorOrNil ifNil: [Color r: 200 g: 200 b: 200 range: 255]"! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousBasePassiveBackgroundColorFor: aButton ^ self class basePassiveBackgroundColor! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousBaseSelectionColorFor: aButton ^ self class baseSelectionColor! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousDarkBaseColorFor: aButton ^ self class darkBaseColor! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/23/2013 06:24'! glamorousLightBorderFor: aMorph | aStyle | " aMorph roundedCorners: #(1 2 3 4). " aStyle := SimpleBorder new baseColor: (self glamorousLightColorFor: aMorph); width: 0. ^ aStyle! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousLightColorFor: aButton ^ self class lightBaseColor! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/16/2013 22:10'! glamorousLightSelectionColorFor: aMorph ^ self class lightSelectionColor! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/20/2013 22:36'! glamorousNormalFillStyleFor: aMorph height: anInteger "Return the normal button fillStyle for the given morph." ^ SolidFillStyle color: (self glamorousLightColorFor: aMorph)! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/10/2013 21:28'! glamorousNormalFillStyleWithBaseColor: aColor for: aMorph height: anInteger | top bottom | top := aColor "darker". bottom := aColor. ^(GradientFillStyle ramp: { 0.0->top. 0.7->bottom.}) origin: aMorph bounds origin; direction: 0 @ anInteger; radial: false! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 8/24/2013 20:27'! glamorousThickBorderFor: aWindow | aStyle | aStyle := SimpleBorder new baseColor: (self glamorousDarkBaseColorFor: aWindow); width: 2. aWindow borderStyle: aStyle. ^ aStyle! ! !GLMWhitespaceTheme methodsFor: 'private' stamp: 'TudorGirba 5/19/2013 14:39'! glamorousVisibleFillStyleFor: aMorph height: anInteger "Return the normal button fillStyle for the given morph." ^ SolidFillStyle color: (self glamorousLightColorFor: aMorph)! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/19/2013 22:49'! groupPanelBorderStyleFor: aGroupPanel "Answer the normal border style for a group panel." ^ self glamorousLightBorderFor: aGroupPanel! ! !GLMWhitespaceTheme methodsFor: 'growl - specific' stamp: 'TudorGirba 5/19/2013 14:15'! growlBorderColorFor: aGrowlMorph ^ self glamorousThickBorderFor: aGrowlMorph ! ! !GLMWhitespaceTheme methodsFor: 'growl - specific' stamp: 'TudorGirba 5/19/2013 14:09'! growlContentsColorFor: aGrowlMorph ^ Color black! ! !GLMWhitespaceTheme methodsFor: 'growl - specific' stamp: 'TudorGirba 5/16/2013 22:10'! growlDismissHandleFor: aGrowlMorph | form image | form := self windowCloseForm. image := ImageMorph new. image image: form. image color: Color yellow. ^ image! ! !GLMWhitespaceTheme methodsFor: 'growl - specific' stamp: 'TudorGirba 5/16/2013 22:10'! growlFillColorFor: aGrowlMorph ^ Color darkGray alpha: 0.5! ! !GLMWhitespaceTheme methodsFor: 'growl - specific' stamp: 'TudorGirba 5/19/2013 14:09'! growlLabelColorFor: aGrowlMorph ^ Color black! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! initialize "self beCurrent" super initialize. self windowActiveDropShadowStyle: #diffuse! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! initializeForms "Initialize the receiver's image forms." |inactiveForm| super initializeForms. inactiveForm := self newWindowInactiveControlForm. self forms at: #windowCloseOver put: self newWindowCloseOverForm; at: #windowMinimizeOver put: self newWindowMinimizeOverForm; at: #windowMaximizeOver put: self newWindowMaximizeOverForm; at: #windowClosePassive put: inactiveForm; at: #windowMinimizePassive put: inactiveForm; at: #windowMaximizePassive put: inactiveForm! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! listDisabledFillStyleFor: aList "Return the disabled fillStyle for the given list." ^ self textEditorDisabledFillStyleFor: aList! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/19/2013 22:49'! listNormalBorderStyleFor: aList "Return the normal borderStyle for the given list" ^ self glamorousLightBorderFor: aList! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! menuItemInDockingBarSelectedFillStyleFor: aMenuItem "Answer the selected fill style to use for the given menu item that is in a docking bar." ^ self buttonSelectedFillStyleFor: aMenuItem! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! menuPinForm "Answer the form to use for the pin button of a menu." ^ GLMUIThemeIcons menuPinForm! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 10/19/2013 03:21'! morphTreeSplitterNormalFillStyleFor: aSplitter ^ SolidFillStyle color: Color transparent! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! morphTreeSplitterPressedFillStyleFor: aSplitter ^ self splitterPressedFillStyleFor: aSplitter! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newCheckboxMarkerForm "Answer a new checkbox marker form." ^GLMUIThemeIcons checkboxMarkerForm! ! !GLMWhitespaceTheme methodsFor: 'morph creation' stamp: 'TudorGirba 5/16/2013 22:10'! newCloseControlIn: aThemedMorph for: aModel action: aValuable help: helpText "Answer a button for closing things." |form msb| form := self windowCloseForm. msb := MultistateButtonMorph new extent: form extent. msb activeEnabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowClosePassiveForm. msb extent: form extent. msb activeDisabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveEnabledNotOverUpFillStyle: (ImageFillStyle form: form). msb passiveDisabledNotOverUpFillStyle: (ImageFillStyle form: form). form := self windowCloseOverForm. msb extent: form extent. msb activeEnabledOverUpFillStyle: (ImageFillStyle form: form); passiveEnabledOverUpFillStyle: (ImageFillStyle form: form). form := self windowClosePassiveForm. msb extent: form extent; activeEnabledOverDownFillStyle: (ImageFillStyle form: form); passiveEnabledOverDownFillStyle: (ImageFillStyle form: form); addUpAction: aValuable; setBalloonText: helpText. ^msb! ! !GLMWhitespaceTheme methodsFor: 'morph creation' stamp: 'TudorGirba 5/16/2013 22:10'! newFocusIndicatorMorphFor: aMorph "Answer a new focus indicator for the given morph." |radius| radius := aMorph focusIndicatorCornerRadius. ^ BorderedMorph new fillStyle: Color transparent; borderStyle: (SimpleBorder new width: 1; baseColor: (self glamorousBaseSelectionColorFor: aMorph)); bounds: aMorph focusBounds! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newRadioButtonMarkerForm "Answer a new radio button marker form. We make it empty because we already have the selected radio button take care of the state." ^GLMUIThemeIcons radioButtonMarkerForm ! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! newRadioMarkerForm "Answer a new checkbox marker form." ^Form extent: 12@12 depth: 32! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! newTreeExpandedForm "Answer a new form for an expanded tree item." ^(Form extent: 9@9 depth: 32 fromArray: #( 1049135240 2290649224 2290649224 2290649224 2290649224 2290649224 2290649224 2290649224 1200130184 478709896 4169697416 4287137928 4287137928 4287137928 4287137928 4287137928 4236806280 646482056 16777215 2508753032 4287137928 4287137928 4287137928 4287137928 4287137928 2726856840 16777215 16777215 495487112 4186474632 4287137928 4287137928 4287137928 4236806280 612927624 16777215 16777215 16777215 2542307464 4287137928 4287137928 4287137928 2676525192 16777215 16777215 16777215 16777215 478709896 4169697416 4287137928 4220029064 579373192 16777215 16777215 16777215 16777215 16777215 2424866952 4287137928 2626193544 16777215 16777215 16777215 16777215 16777215 16777215 394823816 4018702472 529041544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 864585864 16777215 16777215 16777215 16777215) offset: 0@0)! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! newTreeUnexpandedForm "Answer a new form for an unexpanded tree item." ^(Form extent: 9@9 depth: 32 fromArray: #( 1049135240 461932680 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2324203656 4152920200 2458421384 428378248 16777215 16777215 16777215 16777215 16777215 2357758088 4287137928 4287137928 4152920200 2408089736 394823816 16777215 16777215 16777215 2391312520 4287137928 4287137928 4287137928 4287137928 4119365768 2324203656 344492168 16777215 2408089736 4287137928 4287137928 4287137928 4287137928 4287137928 4287137928 3968370824 780699784 2391312520 4287137928 4287137928 4287137928 4287137928 4236806280 2659747976 529041544 16777215 2357758088 4287137928 4287137928 4253583496 2810742920 646482056 16777215 16777215 16777215 2324203656 4253583496 2777188488 696813704 16777215 16777215 16777215 16777215 16777215 1200130184 663259272 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: 0@0)! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowCloseForm "Answer a new form for a window close box." ^ GLMUIThemeIcons windowCloseForm ! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowCloseOverForm "Answer a new form for a window menu box." ^ self newWindowCloseForm! ! !GLMWhitespaceTheme methodsFor: 'initialize-release' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowInactiveControlForm "Answer a new form for an inactive window control box." ^(Form extent: 16@16 depth: 32 fromArray: #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4291677645 4288585374 4286085240 4284243036 4284243036 4286085240 4288585374 4291677645 0 0 0 0 0 0 0 4289572269 4285756275 4286479998 4288716960 4289835441 4289835441 4288716960 4286479998 4285756275 4289572269 0 0 0 0 0 4289506476 4284835173 4287335307 4290559164 4292598747 4293322470 4293322470 4292598747 4290559164 4287335307 4284703587 4289506476 0 0 0 4291546059 4285493103 4286414205 4288980132 4291217094 4292335575 4292598747 4292598747 4292335575 4291282887 4288980132 4286282619 4285493103 4291546059 0 0 4288980132 4285361517 4287466893 4288782753 4289835441 4290295992 4290295992 4290427578 4290164406 4289835441 4288782753 4287466893 4285361517 4288980132 0 0 4286282619 4286611584 4288059030 4288716960 4289177511 4289572269 4289835441 4289835441 4289703855 4289374890 4288782753 4288059030 4286611584 4286282619 0 0 4285164138 4287664272 4288782753 4289374890 4289835441 4290427578 4290624957 4290624957 4290559164 4290032820 4289374890 4288914339 4287664272 4285164138 0 0 4285361517 4288322202 4289703855 4290295992 4290822336 4291414473 4291677645 4291677645 4291414473 4291085508 4290427578 4289703855 4288453788 4285624689 0 0 4287072135 4288716960 4290427578 4291217094 4291677645 4292203989 4292598747 4292598747 4292335575 4291809231 4291217094 4290427578 4288716960 4287203721 0 0 4288980132 4288256409 4290624957 4291677645 4292335575 4292927712 4293256677 4293256677 4293059298 4292598747 4291809231 4290822336 4288256409 4289177511 0 0 4291677645 4287664272 4290295992 4292006610 4293059298 4293454056 4293585642 4293585642 4293454056 4293125091 4292203989 4290427578 4287730065 4291677645 0 0 4293256677 4290032820 4288124823 4291217094 4292796126 4293322470 4293717228 4293717228 4293454056 4292927712 4291677645 4288256409 4290032820 4293256677 0 0 0 4293454056 4290032820 4288322202 4289967027 4291546059 4292598747 4292664540 4291677645 4290295992 4288716960 4290032820 4293454056 0 0 0 0 0 4293322470 4292203989 4289835441 4288782753 4288322202 4288453788 4288980132 4289835441 4292335575 4293322470 0 0 0 0 0 0 0 4293059298 4293585642 4293717228 4293585642 4293585642 4293585642 4293585642 4293059298 0 0 0 0) offset: 0@0)! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMaximizeForm "Answer a new form for a window maximize box." ^ GLMUIThemeIcons windowMaximizeForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMaximizeOverForm "Answer a new form for a window menu box." ^ self newWindowMaximizeForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMenuForm "Answer a new form for a window menu box." ^ GLMUIThemeIcons windowMenuForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMenuPassiveForm "Answer a new form for a window menu box." ^ GLMUIThemeIcons windowMenuInactiveForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMinimizeForm "Answer a new form for a window minimize box." ^ GLMUIThemeIcons windowMinimizeForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! newWindowMinimizeOverForm "Answer a new form for a window menu box." ^ self newWindowMinimizeForm! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/19/2013 16:32'! plainGroupPanelBorderStyleFor: aGroupPanel "Answer the normal border style for a plain group panel." ^SimpleBorder new width: 1; baseColor: Color transparent! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! progressBarFillStyleFor: aProgressBar ^ self glamorousBasePassiveBackgroundColorFor: aProgressBar! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! progressBarProgressFillStyleFor: aProgressBar ^ (self glamorousLightSelectionColorFor: aProgressBar)! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! progressFillStyleFor: aProgress "Return the progress fillStyle for the given progress morph." ^ self windowActiveFillStyleFor: aProgress ! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! radioButtonForm "Answer the form to use for a normal radio button." ^ GLMUIThemeIcons radioButtonUnselectedForm! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! radioButtonSelectedForm "Answer the form to use for a selected radio button." ^ GLMUIThemeIcons radioButtonSelectedForm ! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/21/2013 21:19'! resizerGripNormalFillStyleFor: aResizer "Return the normal fillStyle for the given resizer. For the moment, answer a transparent colour for no drawing, non transparent to draw as normal." self flag: 'this is used for the edge grip'. ^ super resizerGripNormalFillStyleFor: aResizer " aResizer instVarNamed: #handleColor put: (self glamorousDarkBaseColorFor: aResizer); instVarNamed: #dotColor put: Color transparent. ^SolidFillStyle color: Color red"! ! !GLMWhitespaceTheme methodsFor: 'scrollbars' stamp: 'TudorGirba 5/19/2013 14:46'! scrollbarArrowOfDirection: aSymbol size: finalSizeInteger color: aColor ^ Form extent: 1@1! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-scrollbars' stamp: 'TudorGirba 5/19/2013 14:41'! scrollbarNormalButtonFillStyleFor: aScrollbar "Return the normal scrollbar button fillStyle for the given scrollbar." ^ self glamorousNormalFillStyleFor: aScrollbar height: aScrollbar height! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-scrollbars' stamp: 'TudorGirba 5/16/2013 22:10'! scrollbarNormalFillStyleFor: aScrollbar "Return the normal scrollbar fillStyle for the given scrollbar." ^ Color transparent! ! !GLMWhitespaceTheme methodsFor: 'border-styles-scrollbars' stamp: 'TudorGirba 5/16/2013 22:10'! scrollbarNormalThumbBorderStyleFor: aScrollbar "Return the normal thumb borderStyle for the given scrollbar." ^ BorderStyle simple width: 0; baseColor: Color transparent! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-scrollbars' stamp: 'TudorGirba 5/19/2013 14:41'! scrollbarNormalThumbFillStyleFor: aScrollbar "Return the normal scrollbar fillStyle for the given scrollbar." ^ self glamorousVisibleFillStyleFor: aScrollbar height: aScrollbar height! ! !GLMWhitespaceTheme methodsFor: 'border-styles-scrollbars' stamp: 'TudorGirba 5/16/2013 22:10'! scrollbarPagingAreaCornerStyleIn: aThemedMorph ^#square! ! !GLMWhitespaceTheme methodsFor: 'border-styles-scrollbars' stamp: 'TudorGirba 5/16/2013 22:10'! scrollbarThumbCornerStyleIn: aThemedMorph ^#square! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! separatorFillStyleFor: aSeparator "Return the separator fillStyle for the given separator." ^ SolidFillStyle color: (self glamorousBaseColorFor: aSeparator) darker! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! sliderDisabledFillStyleFor: aSlider "Return the disabled fillStyle for the given slider." ^ self textEditorDisabledFillStyleFor: aSlider! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 9/6/2013 07:39'! splitterNormalFillStyleFor: aSplitter "Return the normal splitter fillStyle for the given splitter." ^ self glamorousNormalFillStyleFor: aSplitter height: 1! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 9/6/2013 07:41'! splitterPressedFillStyleFor: aSplitter "Return the pressed splitter fillStyle for the given splitter." ^ self splitterNormalFillStyleFor: aSplitter! ! !GLMWhitespaceTheme methodsFor: 'basic-colors' stamp: 'TudorGirba 5/19/2013 14:31'! subgroupColorFrom: paneColor "Answer the colour for a subgroup given the pane colour." ^ self glamorousBaseColorFor: paneColor! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/16/2013 22:10'! tabLabelNormalBorderStyleFor: aTabLabel " ^SimpleBorder new width: 0; baseColor: (self buttonBaseColorFor: aTabLabel) darker " ^ self buttonNormalBorderStyleFor: aTabLabel! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! tabLabelNormalFillStyleFor: aTabLabel ^ self buttonNormalFillStyleFor: aTabLabel ! ! !GLMWhitespaceTheme methodsFor: 'fill-styles-buttons' stamp: 'TudorGirba 5/16/2013 22:10'! tabLabelSelectedFillStyleFor: aTabLabel ^ self buttonSelectedFillStyleFor: aTabLabel ! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/19/2013 22:07'! tabPanelBorderStyleFor: aTabGroup ^ GLMTabPanelBorder new width: 1; baseColor: ((self glamorousLightColorFor: aTabGroup)); tabSelector: aTabGroup tabSelectorMorph! ! !GLMWhitespaceTheme methodsFor: 'basic-colors' stamp: 'TudorGirba 5/16/2013 22:10'! taskbarButtonLabelColorFor: aButton "Answer the colour for the label of the given taskbar button." ^aButton model ifNil: [super taskbarButtonLabelColorFor: aButton] ifNotNil: [:win | win isActive ifTrue: [Color black] ifFalse: [Color gray darker]]! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! taskbarFillStyleFor: aTaskbar ^ "self buttonNormalFillStyleFor: aTaskbar" SolidFillStyle color: Color transparent ! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/16/2013 22:10'! taskbarThumbnailCornerStyleFor: aMorph "Answer the corner style for the taskbar thumbnail/tasklist." ^#square! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/16/2013 22:10'! taskbarThumbnailNormalBorderStyleFor: aWindow ^ self buttonNormalBorderStyleFor: aWindow! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! textEditorDisabledFillStyleFor: aTextEditor "Return the disabled fillStyle for the given text editor." ^self glamorousBasePassiveBackgroundColorFor: aTextEditor! ! !GLMWhitespaceTheme methodsFor: 'border-styles' stamp: 'TudorGirba 5/16/2013 22:10'! textEditorNormalBorderStyleFor: aTextEditor "Return the normal text editor borderStyle for the given text editor." ^self buttonNormalBorderStyleFor: aTextEditor! ! !GLMWhitespaceTheme methodsFor: 'basic-colors' stamp: 'TudorGirba 5/16/2013 22:10'! treeLineWidth "Answer the width of the tree lines." ^0! ! !GLMWhitespaceTheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/16/2013 22:10'! watcherWindowActiveFillStyleFor: aWindow ^ SolidFillStyle color: (Color veryVeryLightGray alpha: 0.6)! ! !GLMWhitespaceTheme methodsFor: 'watcher window' stamp: 'TudorGirba 5/16/2013 22:10'! watcherWindowInactiveFillStyleFor: aWindow ^ SolidFillStyle color: (Color veryVeryLightGray alpha: 0.6)! ! !GLMWhitespaceTheme methodsFor: 'accessing' stamp: 'TudorGirba 5/16/2013 22:10'! windowActiveDropShadowStyle: anObject "Set the value of windowActiveDropShadowStyle" windowActiveDropShadowStyle := anObject! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/19/2013 21:42'! windowActiveFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^ SolidFillStyle color: (self glamorousBaseColorFor: aWindow)! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/19/2013 21:45'! windowActiveTitleFillStyleFor: aWindow ^ SolidFillStyle color: (self glamorousDarkBaseColorFor: aWindow)! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowCloseOverForm "Answer the form to use for mouse over window close buttons" ^self forms at: #windowCloseOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! windowClosePassiveForm "Answer the form to use for passive (background) window close buttons" ^GLMUIThemeIcons windowCloseInactiveForm! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/21/2013 21:20'! windowEdgeNormalFillStyleFor: anEdgeGrip "Return the normal window edge fillStyle for the given edge grip." self flag: 'this is used for the long edges'. ^ super windowEdgeNormalFillStyleFor: anEdgeGrip "self glamorousDarkBaseColorFor: anEdgeGrip"! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowInactiveFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^self windowActiveFillStyleFor: aWindow! ! !GLMWhitespaceTheme methodsFor: 'fill-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowInactiveTitleFillStyleFor: aWindow "We do not want the lighting effect when the window goes inactive" ^ SolidFillStyle color: Color transparent! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowMaximizeOverForm "Answer the form to use for mouse over window maximize buttons" ^self forms at: #windowMaximizeOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! windowMaximizePassiveForm "Answer the form to use for passive (background) window maximize/restore buttons" ^GLMUIThemeIcons windowMaximizeInactiveForm! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowMenuPassiveForm "Answer the form to use for passive (background) window menu buttons" ^self newWindowMenuPassiveForm! ! !GLMWhitespaceTheme methodsFor: 'label-styles' stamp: 'TudorGirba 5/16/2013 22:10'! windowMinimizeOverForm "Answer the form to use for mouse over window minimize buttons" ^self forms at: #windowMinimizeOver ifAbsent: [Form extent: 16@16 depth: Display depth]! ! !GLMWhitespaceTheme methodsFor: 'forms' stamp: 'TudorGirba 5/16/2013 22:10'! windowMinimizePassiveForm "Answer the form to use for passive (background) window minimize buttons" ^GLMUIThemeIcons windowMinimizeInactiveForm! ! !GLMWhitespaceTheme methodsFor: 'defaults' stamp: 'TudorGirba 5/19/2013 21:33'! windowShadowColor "Answer the window shadow color to use." ^ Color transparent! ! !UITheme methodsFor: '*glamour-morphic-theme' stamp: 'TudorGirba 5/23/2012 13:10'! configureWatcherWindowLabelAreaFor: aWindow ^ self configureWindowLabelAreaFor: aWindow! ! !UITheme methodsFor: '*glamour-morphic-theme' stamp: 'TudorGirba 5/23/2012 13:28'! watcherWindowActiveFillStyleFor: aWindow ^ self windowActiveFillStyleFor: aWindow! ! !UITheme methodsFor: '*glamour-morphic-theme' stamp: 'TudorGirba 5/23/2012 14:10'! watcherWindowInactiveFillStyleFor: aWindow ^ self windowInactiveFillStyleFor: aWindow! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 4/4/2011 00:56'! actualPageMorph ^ actualPageMorph ifNil: [actualPageMorph := self lazyPageMorphCreation value hResizing: #spaceFill; vResizing: #spaceFill; yourself]! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 17:49'! actualPageMorph: anObject actualPageMorph := anObject! ! !LazyTabPage methodsFor: 'testing' stamp: 'TudorGirba 1/22/2011 22:26'! isRendered ^ actualPageMorph notNil! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 17:49'! labelMorph ^ labelMorph! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 17:49'! labelMorph: anObject labelMorph := anObject! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 18:11'! lazyPageMorphCreation ^ lazyPageMorphCreation! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 18:11'! lazyPageMorphCreation: anObject lazyPageMorphCreation := anObject! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 20:50'! toolbar ^ toolbar! ! !LazyTabPage methodsFor: 'accessing' stamp: 'TudorGirba 1/22/2011 20:50'! toolbar: anObject toolbar := anObject! ! !MorphTreeMorph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 15:56'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !GLMMorphicSingleSpotter class methodsFor: 'instance creation' stamp: 'ML 2/26/2011 17:05'! on: aRequest ^ self basicNew initializeOn: aRequest! ! !GLMMorphicSingleSpotter class methodsFor: 'instance creation' stamp: 'MirceaLungu 2/26/2011 17:59'! on: aRequest parent: parent ^ self basicNew initializeOn: aRequest parent: parent! ! !GLMMorphicSingleSpotter class methodsFor: 'instance creation' stamp: 'ML 2/26/2011 17:05'! openOn: aRequest ^ UITheme builder openModal: (self on: aRequest)! ! !GLMMorphicSingleSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:05'! answer "Answer the result of the dialog or nil, if this dialog has been cancelled." ^ answer! ! !GLMMorphicSingleSpotter methodsFor: 'callbacks' stamp: 'ML 2/26/2011 17:05'! arrowKey: anEvent from: aMorph "Ignore this request."! ! !GLMMorphicSingleSpotter methodsFor: 'actions' stamp: 'ML 2/26/2011 17:05'! cancel answer := nil. ^ super cancel! ! !GLMMorphicSingleSpotter methodsFor: 'callbacks' stamp: 'ML 2/26/2011 17:05'! clickIconAt: anInteger "Ignore this request."! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:05'! defaultFocusMorph ^ textMorph! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'MirceaLungu 2/26/2011 18:10'! deselect self listIndex: 0. ! ! !GLMMorphicSingleSpotter methodsFor: 'callbacks' stamp: 'ML 2/26/2011 17:05'! doubleClick self ok! ! !GLMMorphicSingleSpotter methodsFor: 'callbacks' stamp: 'ML 2/26/2011 17:05'! editorKeyStroke: anEvent anEvent keyCharacter = Character arrowDown ifTrue: [ self listIndex: (self listIndex + 1 min: listValues size). ^ true ]. anEvent keyCharacter = Character arrowUp ifTrue: [ self listIndex: (self listIndex - 1 max: 1). ^ true ]. ^ false! ! !GLMMorphicSingleSpotter methodsFor: 'callbacks' stamp: 'TudorGirba 10/25/2011 17:25'! iconAt: anIndex ^ model ifNotNil: [model iconFor: (listValues at: anIndex ifAbsent: [ ^ nil ])]! ! !GLMMorphicSingleSpotter methodsFor: 'initialization' stamp: 'ML 2/26/2011 17:05'! initializeOn: aRequest model := aRequest. listValues := listLabels := #(). listIndex := 0. self initialize. self title: aRequest prompt. self text: aRequest default ! ! !GLMMorphicSingleSpotter methodsFor: 'initialization' stamp: 'MirceaLungu 2/26/2011 18:05'! initializeOn: aRequest parent: theParent parent := theParent. self initializeOn: aRequest. ! ! !GLMMorphicSingleSpotter methodsFor: 'testing' stamp: 'ML 2/26/2011 17:05'! isAssisted ^ self model assisted! ! !GLMMorphicSingleSpotter methodsFor: 'testing' stamp: 'ML 2/26/2011 17:05'! isEnabled ^ self model assisted ifTrue: [ self text isEmptyOrNil not ] ifFalse: [ self listIndex > 0 ]! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'ML 2/26/2011 17:05'! listIndex ^ listIndex! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'MirceaLungu 2/26/2011 18:09'! listIndex: anInteger anInteger isZero not ifTrue: [ parent selectionIn: self.]. listIndex = anInteger ifTrue: [ ^ self ]. listIndex := anInteger. self listSelection ifNotNil: [ :selection | self isAssisted ifTrue: [ text := self model labelFor: self listSelection. self changed: #text ] ]. self changed: #listIndex; changed: #isEnabled! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'ML 2/26/2011 17:05'! listLabels ^ listLabels! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'ML 2/26/2011 17:05'! listSelection ^ listValues at: self listIndex ifAbsent: [ nil ]! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'MirceaLungu 2/26/2011 18:04'! listSelection: anObject self listIndex: (listValues indexOf: anObject ifAbsent: [ 0 ])! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'ML 2/26/2011 17:05'! listValues ^ listValues! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-list' stamp: 'ML 2/26/2011 17:05'! listValues: aCollection | previous | previous := self listSelection. listValues := aCollection asArray. listLabels := listValues collect: [ :each | model labelFor: each ]. self changed: #listLabels; listSelection: previous! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:05'! newContentMorph ^ (self newColumn: { self newTextMorph. self newListMorph }) minWidth: 320; minHeight: 200; yourself! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'TudorGirba 10/26/2011 16:04'! newListMorph listMorph := PluggableListMorph on: self list: #listLabels selected: #listIndex changeSelected: #listIndex:. listMorph borderStyle: (self theme listNormalBorderStyleFor: listMorph); color: (self theme listNormalFillStyleFor: listMorph); cornerStyle: self preferredCornerStyle; doubleClickSelector: #doubleClick; hResizing: #spaceFill; vResizing: #spaceFill; autoDeselect: false. ^ listMorph! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:05'! newOKButton ^ self newOKButtonFor: self getEnabled: #isEnabled! ! !GLMMorphicSingleSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:05'! newTextMorph textMorph := self newTextEntryFor: self getText: #text setText: #text: help: nil. textMorph autoAccept: true; selectAll. textMorph textMorph on: #keyStroke send: #editorKeyStroke: to: self. ^ textMorph! ! !GLMMorphicSingleSpotter methodsFor: 'actions' stamp: 'ML 2/26/2011 17:05'! ok answer := self model assisted ifTrue: [ self text ] ifFalse: [ self listSelection ]. ^ super ok! ! !GLMMorphicSingleSpotter methodsFor: 'accessing' stamp: 'MirceaLungu 2/26/2011 17:58'! parent ^ parent! ! !GLMMorphicSingleSpotter methodsFor: 'accessing' stamp: 'MirceaLungu 2/26/2011 17:58'! parent: anObject parent := anObject! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-text' stamp: 'ML 2/26/2011 17:05'! text ^ text! ! !GLMMorphicSingleSpotter methodsFor: 'accessing-text' stamp: 'ML 2/26/2011 17:05'! text: aString text = aString ifTrue: [ ^ self ]. text := aString. self listValues: (self model valuesFor: text). self isAssisted ifFalse: [ self listIndex: (self listLabels size = 1 ifTrue: [ 1 ] ifFalse: [ self listLabels findFirst: [ :each | each sameAs: text ] ]) ]. self changed: #text; changed: #isEnabled! ! !GLMMorphicSpotter class methodsFor: 'instance creation' stamp: 'ML 2/26/2011 17:15'! on: aRequest ^ self basicNew initializeOn: aRequest! ! !GLMMorphicSpotter class methodsFor: 'instance creation' stamp: 'ML 2/26/2011 17:15'! openOn: aRequest ^ UITheme builder openModal: (self on: aRequest)! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:08'! answer ^ answer! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:08'! answer: anObject answer := anObject! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:08'! childrenMorphs ^ childrenMorphs! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:08'! childrenMorphs: anObject childrenMorphs := anObject! ! !GLMMorphicSpotter methodsFor: 'callbacks' stamp: 'ML 2/26/2011 17:21'! editorKeyStroke: anEvent " anEvent keyCharacter = Character arrowDown ifTrue: [ self listIndex: (self listIndex + 1 min: listValues size). ^ true ]. anEvent keyCharacter = Character arrowUp ifTrue: [ self listIndex: (self listIndex - 1 max: 1). ^ true ]." ^ false! ! !GLMMorphicSpotter methodsFor: 'initialization' stamp: 'ML 2/26/2011 17:18'! initialize childrenMorphs := OrderedCollection new. super initialize! ! !GLMMorphicSpotter methodsFor: 'initialization' stamp: 'ML 2/26/2011 17:16'! initializeOn: aRequest model := aRequest. self initialize. self title: aRequest prompt. self text: aRequest default ! ! !GLMMorphicSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:21'! newContentMorph ^ (self newColumn: ((OrderedCollection with: self newTextMorph) addAll: self newListMorphs; yourself) ) minWidth: 320; minHeight: 200; yourself! ! !GLMMorphicSpotter methodsFor: 'morphic' stamp: 'TudorGirba 2/27/2011 15:25'! newListMorphs | list | self model requests do: [:each | list := (GLMMorphicSingleSpotter on: each parent: self). self childrenMorphs add: list ]. ^ childrenMorphs collect: #newListMorph! ! !GLMMorphicSpotter methodsFor: 'morphic' stamp: 'ML 2/26/2011 17:13'! newTextMorph textMorph := self newTextEntryFor: self getText: #text setText: #text: help: nil. textMorph autoAccept: true; selectAll. textMorph textMorph on: #keyStroke send: #editorKeyStroke: to: self. ^ textMorph! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'MirceaLungu 2/26/2011 18:14'! ok | nonEmpty | nonEmpty := (self childrenMorphs select: [:e| e listIndex isZero not]). nonEmpty size = 1 ifTrue: [ answer := nonEmpty first listSelection ] . ^ super ok! ! !GLMMorphicSpotter methodsFor: 'callbacks' stamp: 'MirceaLungu 2/26/2011 18:10'! selectionIn: singleSpotlight (self childrenMorphs reject: [:e| e = singleSpotlight] ) do: [:e| e deselect. ]! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:08'! text ^ text! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:14'! text: aString text = aString ifTrue: [ ^ self ]. text := aString. self childrenMorphs do: [:each | each text: aString ]. self changed: #text; changed: #isEnabled! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:07'! textMorph ^ textMorph! ! !GLMMorphicSpotter methodsFor: 'accessing' stamp: 'ML 2/26/2011 17:07'! textMorph: anObject textMorph := anObject! ! !GLMTextMorphForEditView commentStamp: 'TudorGirba 7/14/2011 09:44' prior: 34264874! GLMTextMorphForEditView is meant to work with GLMPluggableTextMorph.! !GLMTextMorphForEditView methodsFor: 'private' stamp: 'TudorGirba 7/14/2011 21:37'! editorClass "Answer the class used to create the receiver's editor" ^GLMSmalltalkEditor! ! !GLMTextMorphForEditView methodsFor: 'callbacks' stamp: 'TudorGirba 7/14/2011 11:10'! keyStroke: anEvent | isHandledByModel | isHandledByModel := self editView model keystroke: anEvent from: self editView. isHandledByModel ifFalse: [ super keyStroke: anEvent ]! ! !Color class methodsFor: '*roassal-core'! gray256: intensity "between 0 and 256" | i | i := intensity asFloat / 256. ^ self r: i g: i b: i ! ! !Color class methodsFor: '*roassal-core'! wheel: s alpha: a ^ (Color wheel: 6) collect: [:c | c alpha: a ].! ! !Text methodsFor: '*petitparser-core-converting' stamp: 'lr 2/7/2010 20:53'! asPetitStream ^ string asPetitStream! ! !GLMUIThemeIcons commentStamp: 'TudorGirba 1/30/2011 22:49' prior: 34265014! This class holds a set of icons to be used in the Glamorous UI Theme.! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:22'! checkboxMarkerForm "Answer a new radio button marker form. We make it empty because we already have the selected radio button take care of the state." ^Form extent: 12@12 depth: 32! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 14:10'! checkboxSelectedForm ^ self form16x16FromContents: self checkboxSelectedFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 14:10'! checkboxSelectedFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4278190080 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4278190080 0 0 0 0 0 0 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:40'! checkboxUnselectedForm ^ self form16x16FromContents: self checkboxUnselectedFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:26'! checkboxUnselectedFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 0 0 4278190080 0 0 0 0 0 0 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:39'! form16x16FromContents: aByteArray ^ Form extent: 16@16 depth: 32 fromArray: aByteArray offset: 0@0! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:40'! menuPinForm ^self form16x16FromContents: self menuPinFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:26'! menuPinFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83886080 100663296 83886080 0 0 0 0 0 0 0 0 0 0 0 0 1291845632 3774873600 4194304000 3774873600 788529152 0 0 0 0 0 0 0 0 0 0 1107296256 4278190080 4278190080 4278190080 4278190080 4278190080 788529152 0 0 0 0 0 0 0 0 83886080 3992977408 4278190080 4278190080 4278190080 4278190080 4278190080 3774873600 83886080 0 0 0 0 0 0 0 100663296 4194304000 4278190080 4278190080 4278190080 4278190080 4278190080 4194304000 100663296 0 0 0 0 0 0 0 83886080 3774873600 4278190080 4278190080 4278190080 4278190080 4278190080 3992977408 83886080 0 0 0 0 0 0 0 0 1291845632 4261412864 4278190080 4278190080 4278190080 4261412864 1107296256 0 0 0 0 0 0 0 0 0 0 1107296256 3992977408 4194304000 3774873600 1291845632 0 0 0 0 0 0 0 0 0 0 0 0 83886080 100663296 83886080 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 09:11'! radioButtonMarkerForm "Answer a new radio button marker form. We make it empty because we already have the selected radio button take care of the state." ^Form extent: 12@12 depth: 32! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:40'! radioButtonSelectedForm ^ self form16x16FromContents: self radioButtonSelectedFormContents! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:27'! radioButtonSelectedFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50331648 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 1023410176 3422946822 4043572228 4043572228 3422946822 1023410176 0 0 0 0 0 0 0 0 0 2214987270 4161078533 4284045657 4285690482 4285690482 4284045657 4161078533 1058280468 0 0 0 0 0 0 0 1023410176 4278190080 4285887861 4286611584 4286611584 4286611584 4286611584 4285887861 4278190080 1023410176 0 0 0 0 0 50331648 3422946822 4284045657 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4284045657 3422946822 50331648 0 0 0 0 0 4043572228 4285690482 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4285690482 4043572228 0 0 0 0 0 0 4043572228 4285690482 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4285690482 4043572228 0 0 0 0 0 33554432 3422946822 4284045657 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4284045657 3422946822 50331648 0 0 0 0 0 1006632960 4161078533 4285887861 4286611584 4286611584 4286611584 4286611584 4285887861 4278190080 1023410176 0 0 0 0 0 0 0 2214987270 4278190080 4284045657 4285690482 4285690482 4284045657 4161078533 2214987270 0 0 0 0 0 0 0 0 0 1006632960 3422946822 4043572228 4043572228 3422946822 1023410176 0 0 0 0 0 0 0 0 0 0 0 33554432 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:40'! radioButtonUnselectedForm ^ self form16x16FromContents: self radioButtonUnselectedFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:27'! radioButtonUnselectedFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50331648 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 1023410176 3238002688 3909091328 3909091328 3238002688 1023410176 0 0 0 0 0 0 0 0 0 2097152000 3976200192 1275068416 452984832 452984832 1275068416 3976200192 872415232 0 0 0 0 0 0 0 1023410176 4278190080 335544320 0 0 0 0 335544320 4278190080 1023410176 0 0 0 0 0 50331648 3238002688 1275068416 0 0 0 0 0 0 1275068416 3238002688 50331648 0 0 0 0 0 3909091328 452984832 0 0 0 0 0 0 452984832 3909091328 0 0 0 0 0 0 3909091328 452984832 0 0 0 0 0 0 452984832 3909091328 0 0 0 0 0 33554432 3238002688 1275068416 0 0 0 0 0 0 1275068416 3238002688 50331648 0 0 0 0 0 1006632960 3992977408 335544320 0 0 0 0 335544320 4278190080 1023410176 0 0 0 0 0 0 0 2097152000 4278190080 1275068416 452984832 452984832 1275068416 3976200192 2097152000 0 0 0 0 0 0 0 0 0 1006632960 3238002688 3909091328 3909091328 3238002688 1023410176 0 0 0 0 0 0 0 0 0 0 0 33554432 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:14'! radioSelectedForm ^ Form fromBinaryStream: ( Base64MimeConverter mimeDecodeToBytes: self radioSelectedFormContents readStream) ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:13'! radioSelectedFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50331648 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 1023410176 3422946822 4043572228 4043572228 3422946822 1023410176 0 0 0 0 0 0 0 0 0 2214987270 4161078533 4284045657 4285690482 4285690482 4284045657 4161078533 1058280468 0 0 0 0 0 0 0 1023410176 4278190080 4285887861 4286611584 4286611584 4286611584 4286611584 4285887861 4278190080 1023410176 0 0 0 0 0 50331648 3422946822 4284045657 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4284045657 3422946822 50331648 0 0 0 0 0 4043572228 4285690482 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4285690482 4043572228 0 0 0 0 0 0 4043572228 4285690482 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4285690482 4043572228 0 0 0 0 0 33554432 3422946822 4284045657 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4284045657 3422946822 50331648 0 0 0 0 0 1006632960 4161078533 4285887861 4286611584 4286611584 4286611584 4286611584 4285887861 4278190080 1023410176 0 0 0 0 0 0 0 2214987270 4278190080 4284045657 4285690482 4285690482 4284045657 4161078533 2214987270 0 0 0 0 0 0 0 0 0 1006632960 3422946822 4043572228 4043572228 3422946822 1023410176 0 0 0 0 0 0 0 0 0 0 0 33554432 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) offset: 0@0! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:14'! radioUnselectedForm ^ Form fromBinaryStream: ( Base64MimeConverter mimeDecodeToBytes: self radioUnselectedFormContents readStream) ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:13'! radioUnselectedFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50331648 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 1023410176 3238002688 3909091328 3909091328 3238002688 1023410176 0 0 0 0 0 0 0 0 0 2097152000 3976200192 1275068416 452984832 452984832 1275068416 3976200192 872415232 0 0 0 0 0 0 0 1023410176 4278190080 335544320 0 0 0 0 335544320 4278190080 1023410176 0 0 0 0 0 50331648 3238002688 1275068416 0 0 0 0 0 0 1275068416 3238002688 50331648 0 0 0 0 0 3909091328 452984832 0 0 0 0 0 0 452984832 3909091328 0 0 0 0 0 0 3909091328 452984832 0 0 0 0 0 0 452984832 3909091328 0 0 0 0 0 33554432 3238002688 1275068416 0 0 0 0 0 0 1275068416 3238002688 50331648 0 0 0 0 0 1006632960 3992977408 335544320 0 0 0 0 335544320 4278190080 1023410176 0 0 0 0 0 0 0 2097152000 4278190080 1275068416 452984832 452984832 1275068416 3976200192 2097152000 0 0 0 0 0 0 0 0 0 1006632960 3238002688 3909091328 3909091328 3238002688 1023410176 0 0 0 0 0 0 0 0 0 0 0 33554432 0 0 50331648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) offset: 0@0! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowCloseForm ^ self form16x16FromContents: self windowCloseFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:24'! windowCloseFormContents ^#( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 167772160 0 0 0 0 0 0 0 0 167772160 3875536896 4076863488 234881024 0 234881024 2919235584 3858759680 0 0 0 0 0 0 0 0 402653184 3674210304 4261412864 3758096384 671088640 3758096384 4261412864 4278190080 335544320 0 0 0 0 0 0 0 0 352321536 3758096384 4143972352 4211081216 4143972352 3758096384 352321536 0 0 0 0 0 0 0 0 0 0 671088640 4211081216 4261412864 4211081216 671088640 0 0 0 0 0 0 0 0 0 0 352321536 3758096384 4143972352 4211081216 4143972352 3758096384 352321536 0 0 0 0 0 0 0 0 335544320 4278190080 4244635648 3758096384 671088640 3758096384 4143972352 3724541952 402653184 0 0 0 0 0 0 0 0 3892314112 2919235584 234881024 0 234881024 4278190080 1761607680 167772160 0 0 0 0 0 0 0 0 167772160 67108864 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowCloseInactiveForm ^ self form16x16FromContents: self windowCloseInactiveFromContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:23'! windowCloseInactiveFromContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 176193664 0 0 0 0 0 0 0 0 176193664 3883958400 4085284992 243302528 0 243302528 2927657088 3867181184 0 0 0 0 0 0 0 0 411074688 3682631808 4269834368 3766517888 679049593 3766517888 4269834368 4286611584 343965824 0 0 0 0 0 0 0 0 360282489 3766517888 4152328063 4219436927 4152393856 3766517888 360282489 0 0 0 0 0 0 0 0 0 0 679049593 4219436927 4269834368 4219436927 679049593 0 0 0 0 0 0 0 0 0 0 360282489 3766517888 4152393856 4219436927 4152328063 3766517888 360282489 0 0 0 0 0 0 0 0 343965824 4286611584 4253057152 3766517888 679049593 3766517888 4152328063 3732963456 411074688 0 0 0 0 0 0 0 0 3900735616 2927657088 243302528 0 243302528 4286611584 1769897598 176193664 0 0 0 0 0 0 0 0 176193664 75530368 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowMaximizeForm ^ self form16x16FromContents: self windowMaximizeFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:07'! windowMaximizeFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowMaximizeInactiveForm ^ self form16x16FromContents: self windowMaximizeInactiveFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:23'! windowMaximizeInactiveFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:52'! windowMenuForm ^self form16x16FromContents: self windowMenuFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:52'! windowMenuFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 0 0 0 0 369098752 3556769792 3556769792 352321536 0 0 0 0 0 0 0 0 0 0 0 0 0 369098752 352321536 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowMenuInactiveForm ^self form16x16FromContents: self windowMenuInactiveFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:15'! windowMenuInactiveFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 0 0 0 0 377520256 3565191296 3565191296 360282489 0 0 0 0 0 0 0 0 0 0 0 0 0 377520256 360282489 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:41'! windowMinimizeForm ^self form16x16FromContents: self windowMinimizeFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:09'! windowMinimizeFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 0 0 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/28/2010 13:42'! windowMinimizeInactiveForm ^self form16x16FromContents: self windowMinimizeInactiveFormContents ! ! !GLMUIThemeIcons class methodsFor: 'icons' stamp: 'FernandoOlivero 10/27/2010 15:23'! windowMinimizeInactiveFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 0 0 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMUIThemeIcons methodsFor: 'see class side' stamp: 'TudorGirba 1/30/2011 22:49'! seeClassSide! ! !GLMExpanderContentsNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/5/2011 16:49'! containerNode ^ containerNode! ! !GLMExpanderContentsNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/5/2011 16:49'! containerNode: anObject containerNode := anObject! ! !GLMExpanderContentsNodeModel methodsFor: 'callbacks' stamp: 'TudorGirba 2/15/2011 12:25'! elementColumn | row morph | morph := GLMMorphicPaneWithoutTitleRenderer new render: self containerNode item. morph borderStyle: (UITheme current buttonSelectedBorderStyleFor: morph). row := OrderedCollection with: morph. ^ UITheme current newRowIn: World for: row! ! !GLMExpanderContentsNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/5/2011 14:09'! icon ^ nil! ! !GLMExpanderLabelNodeModel class methodsFor: 'instance creation' stamp: 'TudorGirba 1/2/2011 21:16'! with: anObject in: aTreeModel ^ (self with: anObject) containerTree: aTreeModel; yourself! ! !GLMExpanderLabelNodeModel methodsFor: 'callbacks' stamp: 'TudorGirba 1/5/2011 17:24'! childrenItems ^ OrderedCollection with: ((GLMExpanderContentsNodeModel with: (self->self item)) containerNode: self)! ! !GLMExpanderLabelNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/3/2011 13:53'! containerTree ^ containerTree! ! !GLMExpanderLabelNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/3/2011 13:53'! containerTree: anObject containerTree := anObject! ! !GLMExpanderLabelNodeModel methodsFor: 'callbacks' stamp: 'TudorGirba 1/5/2011 10:50'! contents ^ self childrenItems! ! !GLMExpanderLabelNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/3/2011 14:10'! displayText ^ UITheme current newTextIn: World text: (self item presentations titleValue ifNil: ['noname']) ! ! !GLMExpanderLabelNodeModel methodsFor: 'callbacks' stamp: 'TudorGirba 1/5/2011 23:21'! elementColumn | row tags tagsFilter | row := OrderedCollection with: (self displayText). " tags:= self containerTree glamourPresentation tagsFor: self item to: #show. tagsFilter := self containerTree glamourPresentation tagsFor: self item to: #filter. tags withIndexDo:[ :each :index | row addLast: (self buttonForTag: each filter: (tagsFilter at: index ifAbsentPut:[ each ])) ]. " ^ (UITheme current newRowIn: World for: row) fillStyle: Color veryLightGray! ! !GLMExpanderLabelNodeModel methodsFor: 'accessing' stamp: 'TudorGirba 1/5/2011 14:20'! icon ^ nil! ! !GLMTreeMorphNodeModel methodsFor: 'testing' stamp: 'ewe 11/16/2012 14:32'! = anObject "This is needed to handle the update of the whole list while still preserving the selection" ^ self species = anObject species and: [ self item = anObject item ]! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'DamienCassou 5/11/2011 08:15'! allContents ^ self childrenItems collect: [ :d | (self class with: d) parentNode: self; containerTree: self containerTree; yourself ]! ! !GLMTreeMorphNodeModel methodsFor: 'callbacks' stamp: 'VeronicaUquillas 6/15/2010 11:13'! buttonForTag: each filter: filter | button | button := GLMMorphic togglingButtonLabelled: each pressed: (self containerTree shouldFilterByTag: filter) style: self containerTree glamourPresentation tagsStyle. button target: self; actionSelector: #toggleFilteringByTag:; arguments: (Array with: filter). ^ button! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 4/18/2010 23:19'! childrenItems ^ (self containerTree glamourPresentation childrenValueOf: self item atLevel: self path size) ifNil: [OrderedCollection new]! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 9/8/2009 21:08'! containerTree ^ containerTree! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 9/8/2009 21:08'! containerTree: anObject containerTree := anObject! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'DamienCassou 5/11/2011 08:16'! contents ^ contents ifNil: [ contents := self allContents select: [ :each | each shouldBeDisplayed ] ]! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/6/2011 12:57'! displayText ^ (UITheme current newTextIn: World text: (self containerTree glamourPresentation formatedDisplayValueOf: self item)) backgroundColor: self textBackgroundColor; yourself! ! !GLMTreeMorphNodeModel methodsFor: 'callbacks' stamp: 'cyrilledelaunay 7/6/2011 12:07'! elementColumn | row tags tagsFilter | row := OrderedCollection with: self displayText. tags:= self containerTree glamourPresentation tagsFor: self item to: #show. tagsFilter := self containerTree glamourPresentation tagsFor: self item to: #filter. tags withIndexDo:[ :each :index | row addLast: (self buttonForTag: each filter: (tagsFilter at: index ifAbsentPut:[ each ])) ]. ^ (UITheme current newRowIn: World for: row).! ! !GLMTreeMorphNodeModel methodsFor: 'testing' stamp: 'alain.plantec 9/8/2009 14:37'! enabled ^ true! ! !GLMTreeMorphNodeModel methodsFor: 'menu' stamp: 'tg 9/16/2009 23:39'! executeMenuAction: anAction self containerTree announce: (GLMMenuItemSelected action: anAction)! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'AlainPlantec 5/28/2012 07:32'! expandParentPath " self openItemPath: anArray" self containerTree changed: {#rootNodes. #openItemPath}, (self path collect: [:each | each item]).! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 9/11/2009 19:54'! icon ^ self containerTree glamourPresentation iconFor: self item! ! !GLMTreeMorphNodeModel methodsFor: 'menu' stamp: 'tg 9/8/2009 21:09'! keyStroke: aCharacter from: aTreeMorph ^ false ! ! !GLMTreeMorphNodeModel methodsFor: 'menu' stamp: 'EstebanLorenzano 4/20/2012 16:18'! menu: aMenuMorph shifted: b | subMenus targetMenuMorph subMenu | subMenus := Dictionary new. self containerTree allMenuActions do: [ :action | targetMenuMorph := action category notNil ifTrue: [ subMenus at: action category ifAbsentPut: [ subMenu := MenuMorph new. aMenuMorph add: action category subMenu: subMenu. subMenu ] ] ifFalse: [ aMenuMorph ]. (targetMenuMorph add: action title target: self selector: #executeMenuAction: argument: action) icon: action icon; keyText: (action hasShortcut ifTrue: [ action shortcutAsString ] ifFalse: [ nil ]) ]. ^ aMenuMorph! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'alain.plantec 9/8/2009 14:12'! parentNode ^ parentNode! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'alain.plantec 9/8/2009 14:12'! parentNode: aNode parentNode := aNode ! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 4/15/2010 00:24'! path "returns the list of nodes to the root" ^ self pathIn: OrderedCollection new.! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'tg 9/10/2009 12:44'! pathIn: aCollection self parentNode ifNotNil: [ (aCollection includes: self parentNode) ifFalse: [self parentNode pathIn: aCollection]]. aCollection add: self. ^ aCollection! ! !GLMTreeMorphNodeModel methodsFor: 'printing' stamp: 'tg 9/9/2009 13:30'! printOn: aStream aStream nextPutAll: 'a NodeModel with '. aStream nextPutAll: self item printString.! ! !GLMTreeMorphNodeModel methodsFor: 'actions' stamp: 'DamienCassou 5/11/2011 07:55'! resetContents contents := nil! ! !GLMTreeMorphNodeModel methodsFor: 'actions' stamp: 'DamienCassou 5/11/2011 08:17'! resetContentsRecursively self resetContents. self allContents do: [:each | each resetContentsRecursively]! ! !GLMTreeMorphNodeModel methodsFor: 'callbacks' stamp: 'TudorGirba 6/8/2013 21:45'! rowMorphForColumn: aGlamourColumn ^ StringMorph contents: (self containerTree glamourPresentation column: aGlamourColumn valueFor: self item)! ! !GLMTreeMorphNodeModel methodsFor: 'testing' stamp: 'tg 11/30/2009 02:10'! shouldBeDisplayed ^ self shouldBeDisplayedByTags and: [ self shouldBeDisplayedByText ]! ! !GLMTreeMorphNodeModel methodsFor: 'testing' stamp: 'tg 11/30/2009 02:15'! shouldBeDisplayedByTags | nodeTags | self flag: 'it looks like this method does not really get called for children'. " self item mooseName = #'org::easymock' ifTrue: [self haltOnce ]. " self containerTree tagsToFilterBy isEmpty ifTrue: [ ^ true ]. self withContentsDo: [ :node | nodeTags := self containerTree glamourPresentation tagsFor: node item to: #filter. (self containerTree tagsToFilterBy allSatisfy: [ :each | nodeTags includes: each ]) ifTrue: [ ^ true ] ]. ^ false! ! !GLMTreeMorphNodeModel methodsFor: 'testing' stamp: 'tg 11/13/2009 02:10'! shouldBeDisplayedByText self containerTree shouldFilterByTextInput ifFalse: [ ^ true ]. self withContentsDo: [ :node | self flag: 'this should be delegated to the presentation and glamourValue should be used to include the entity ports'. (self containerTree glamourPresentation filterStrategy value: self containerTree inputText asString value: node item) == true ifTrue: [ ^ true ] ]. ^ false! ! !GLMTreeMorphNodeModel methodsFor: 'callbacks' stamp: 'VeronicaUquillas 11/19/2009 22:44'! tagsColumn | tags | tags := (self containerTree glamourPresentation tagsFor: self item to: #show). tags isEmpty ifFalse: [ ^ self buttonForTag: tags last filter: tags last ]. ^ RectangleMorph new! ! !GLMTreeMorphNodeModel methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/6/2011 12:50'! textBackgroundColor ^ self containerTree glamourPresentation textBackgroundColorFor: self item! ! !GLMTreeMorphNodeModel methodsFor: 'callbacks' stamp: 'tg 9/14/2009 23:33'! toggleFilteringByTag: aTag self containerTree toggleFilteringByTag: aTag! ! !GLMTreeMorphNodeModel methodsFor: 'enumerating' stamp: 'tg 9/9/2009 13:42'! withContentsDo: aBlock self flag: 'if the tree is infinite due to recursion, this might not stop'. aBlock value: self. self contents do: [:each | each withContentsDo: aBlock ]! ! !UndefinedObject methodsFor: '*petitparser-converting' stamp: 'lr 11/29/2011 20:49'! asParser "Answer a parser that succeeds and does not consume anything." ^ PPEpsilonParser new! ! !GLMExpanderTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 1/2/2011 19:32'! glamourExpander ^ glamourExpander! ! !GLMExpanderTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 1/2/2011 19:32'! glamourExpander: anObject glamourExpander := anObject! ! !GLMExpanderTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 1/4/2011 15:06'! nodeModelFor: anObject ^ GLMExpanderLabelNodeModel with: anObject in: self! ! !GLMExpanderTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 1/3/2011 14:07'! roots " | filtered |" roots ifNil: [ self roots: self glamourExpander panes ]. ^ roots " filtered := roots select: [ :each | each shouldBeDisplayed ]. ((self shouldFilterByAmount and: [ self amountToFilterBy < filtered size]) and: [ filtered notEmpty]) ifTrue: [ filtered := filtered first: self amountToFilterBy ]. ^ filtered"! ! !GLMExpanderTreeMorphModel methodsFor: 'accessing' stamp: 'TudorGirba 1/3/2011 13:52'! roots: anObjectOrCollection roots := anObjectOrCollection isCollection ifTrue: [ anObjectOrCollection collect: [:each | self nodeModelFor: each ] ] ifFalse: [ OrderedCollection with: (self nodeModelFor: anObjectOrCollection) ]! ! !Collection methodsFor: '*petitparser-core-converting' stamp: 'lr 11/29/2011 20:38'! asChoiceParser ^ PPChoiceParser withAll: (self collect: [ :each | each asParser ])! ! !Collection methodsFor: '*petitparser-core-converting' stamp: 'lr 11/29/2011 20:38'! asSequenceParser ^ PPSequenceParser withAll: (self collect: [ :each | each asParser ])! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'jannik.laval 1/28/2009 17:30'! collectAsSet: aBlock "Evaluates aBlock for each element of the receiver and collects the resulting values into a Set." "This is an efficient shorthand for [ (self collect: aBlock) asSet ]." "originally developed by a. kuhn and released under MIT." ^self inject: Set new into: [ :set :each | set add: (aBlock value: each); yourself ].! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 10/25/2009 01:19'! copyEmpty: aSize "Answer a copy of the receiver that contains no elements. This method should be redefined in subclasses that add instance variables, so that the state of those variables is preserved" ^self class new: aSize! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'simondenier 2/4/2011 22:55'! deepFlatten ^ Array streamContents: [ :stream | self do: [ :each | each deepFlattenInto: stream ]]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'simondenier 2/4/2011 22:57'! deepFlattenInto: stream self do: [ :each | each deepFlattenInto: stream ]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 7/10/2010 11:02'! detect: aBlock ifOne: presentBlock ^ self detect: aBlock ifOne: presentBlock ifNone: [nil] ! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 7/10/2010 11:01'! detect: aBlock ifOne: presentBlock ifNone: noneBlock | result | result := self detect: aBlock ifNone: [nil]. ^ result isNil ifTrue: [ noneBlock value ] ifFalse: [ presentBlock value: result ]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'jannik.laval 1/28/2009 08:04'! equalsTo: aCollection "Answer true if the reciever contains the same elements as aCollection, and vice versa." ^(aCollection isCollection) and: [ aCollection size = self size and: [ aCollection allSatisfy: [ :each | (aCollection occurrencesOf: each) = (self occurrencesOf: each) ]]]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 6/21/2013 12:24'! flatCollect: aBlock "Evaluate aBlock for each of the receiver's elements and answer the list of all resulting values flatten one level. Assumes that aBlock returns some kind of collection for each element. Equivalent to the lisp's mapcan" "original written by a. Kuhn and released under MIT" | stream | self isEmpty ifTrue: [ ^ self copy ]. stream := (self species new: 0) writeStream. self do: [ :each | stream nextPutAll: (aBlock value: each) ]. ^ stream contents! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'jannik.laval 8/27/2010 15:54'! flatCollect: aBlock as: aCollectionClass "Evaluate aBlock for each of the receiver's elements and answer the list of all resulting values flatten one level. Assumes that aBlock returns some kind of collection for each element. Equivalent to the lisp's mapcan" | col | self isEmpty ifTrue: [^self copy ]. col := aCollectionClass new: self size. self do: [ :each | col addAll: (aBlock value: each) ]. ^col! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'jannik.laval 2/12/2009 14:06'! flatCollectAsSet: aBlock "Evaluate aBlock for each of the receiver's elements and answer the list of all resulting values flatten one level. Assumes that aBlock returns some kind of collection for each element. Equivalent to the lisp's mapcan" "original written by a. Kuhn and released under MIT" | set | self isEmpty ifTrue: [^self copy ]. set := Set new. self do: [ :each | set addAll: (aBlock value: each) ]. ^set! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 7/11/2010 14:27'! flatten "Recursively collect each non-collection element of the receiver and its descendant collections. Please note, this implementation assumes that strings are to be treated as objects rather than as collection." ^self gather: [ :each | each ]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 4/26/2010 21:43'! groupedBy: aBlock affect: anotherBlock "First, evaluate aBlock for each of the receiver's elements and group the elements by the resulting values, and second, evaluate anotherBlock for each of the resulting groups and return a dictionary with the first pass' results as keys and the second pass' results as values." "This is a shorthand for [ (self groupedBy: aBlock) collect: anotherBlock ]." ^(self groupedBy: aBlock) associationsDo: [ :each | each value: (anotherBlock value: each value) ]! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 10/14/2009 08:47'! nilSafeGroupedBy: aBlock ^ self groupedBy: [ :each | | value | value := aBlock value: each. value ifNil: [ UndefinedObject ]. ] ! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'Jannik.Laval 4/18/2009 17:47'! selectAsSet: aBlock "Evaluate aBlock with each of the receiver's elements as the argument. Collect into a new set, only those elements for which aBlock evaluates to true. Answer the new collection." | newSet | newSet := Set new. self do: [:each | (aBlock value: each) ifTrue: [newSet add: each]]. ^newSet! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 10/15/2009 11:59'! shuffle "Swaps the receiver's elements at random." self shuffle: (self size * self size log) asInteger! ! !Collection methodsFor: '*CollectionExtensions' stamp: 'tg 10/15/2009 11:58'! shuffle: times "Swaps random elements of the receiver." | size random | size := self size. random := Random new. times timesRepeat: [ self swap: (random next * size) floor + 1 with: (random next * size) floor + 1 ].! ! !RORectangleTreeMap commentStamp: '' prior: 34265144! A RORectangleTreeMap is an extension of Rectangle that adds some useful functionalities for ther ROTreeMapBuilder. Roberto Minelli @ REVEAL, Lugano (CH) roberto.minelli@usi.ch! !RORectangleTreeMap class methodsFor: 'as yet unclassified' stamp: 'RobertoMinelli 10/9/2013 07:50'! fromContainerBounds: aRectangle withInset: anInteger | treeRectangle relativeOrigin relativeCorner | treeRectangle := self new. treeRectangle inset: anInteger. relativeOrigin := 0@0. relativeCorner := aRectangle corner - aRectangle origin. self flag: 'FIXME: I should probably.. do something instead of removing the inset'. ((aRectangle width < (anInteger * 2)) or: [ (aRectangle height < (anInteger * 2))]) ifTrue: [ treeRectangle origin: relativeOrigin. treeRectangle corner: relativeCorner. ] ifFalse: [ treeRectangle origin: relativeOrigin + anInteger . treeRectangle corner: relativeCorner - anInteger. ]. ^ treeRectangle .! ! !RORectangleTreeMap class methodsFor: 'as yet unclassified' stamp: 'RobertoMinelli 10/7/2013 08:13'! fromRectangle: aRectangle | treeRectangle | treeRectangle := self new. treeRectangle origin: aRectangle origin. treeRectangle corner: aRectangle corner. ^ treeRectangle .! ! !RORectangleTreeMap class methodsFor: 'as yet unclassified' stamp: 'RobertoMinelli 10/7/2013 14:19'! fromRectangle: aRectangle withInset: anInteger | treeRectangle | treeRectangle := self new. treeRectangle inset: anInteger. self flag: 'FIXME: I should probably.. do something instead of removing the inset'. ((aRectangle width < (anInteger * 2)) or: [ (aRectangle height < (anInteger * 2))]) ifTrue: [ treeRectangle origin: aRectangle origin . treeRectangle corner: aRectangle corner. ] ifFalse: [ treeRectangle origin: aRectangle origin + anInteger . treeRectangle corner: aRectangle corner - anInteger. ]. ^ treeRectangle .! ! !RORectangleTreeMap class methodsFor: 'as yet unclassified' stamp: 'RobertoMinelli 10/7/2013 13:37'! withInset: anInteger | treeRectangle | treeRectangle := self new. treeRectangle inset: anInteger. ^ treeRectangle .! ! !RORectangleTreeMap methodsFor: 'utils' stamp: 'RobertoMinelli 10/4/2013 17:13'! addSubrectangle: aDFTreeMapRectangle self subrectangles add: aDFTreeMapRectangle . self currentSubrectangle: aDFTreeMapRectangle.! ! !RORectangleTreeMap methodsFor: 'utils' stamp: 'RobertoMinelli 10/10/2013 08:37'! computeHorizontalRemainingSubrectangleFrom: row | areaToLayout remainingSubrectangle currentRect currentOrigin | areaToLayout := row inject: 0 into: [ :s :e | s + (e area) ]. remainingSubrectangle := RORectangleTreeMap new. currentRect := self currentSubrectangle. currentOrigin := currentRect origin. remainingSubrectangle origin: ((currentOrigin x + (areaToLayout / currentRect height)) @ currentOrigin y). remainingSubrectangle corner: currentRect corner. ^ remainingSubrectangle. ! ! !RORectangleTreeMap methodsFor: 'utils' stamp: 'RobertoMinelli 10/7/2013 10:30'! computeRemainingSpaceFrom: row | remainingSubrectangle | remainingSubrectangle := self computeRemainingSubrectangleFrom: row. ^ remainingSubrectangle shortestSide.! ! !RORectangleTreeMap methodsFor: 'utils' stamp: 'RobertoMinelli 10/7/2013 08:03'! computeRemainingSubrectangleFrom: row (self currentSubrectangle isHorizontal) ifTrue: [ ^ self computeHorizontalRemainingSubrectangleFrom: row ] ifFalse: [ ^ self computeVerticalRemainingSubrectangleFrom: row ].! ! !RORectangleTreeMap methodsFor: 'utils' stamp: 'RobertoMinelli 10/10/2013 08:37'! computeVerticalRemainingSubrectangleFrom: row | areaToLayout remainingSubrectangle currentRect currentOrigin | areaToLayout := row inject: 0 into: [ :s :e | s + (e area) ]. remainingSubrectangle := RORectangleTreeMap new. currentRect := self currentSubrectangle. currentOrigin := currentRect origin. remainingSubrectangle origin: ((currentOrigin x) @ ((currentOrigin y) + (areaToLayout / currentRect width))). remainingSubrectangle corner: currentRect corner. ^ remainingSubrectangle. ! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/7/2013 17:58'! corner: aPoint corner := aPoint! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/3/2013 13:28'! currentSubrectangle ^ currentSubrectangle! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/3/2013 13:28'! currentSubrectangle: anObject currentSubrectangle := anObject! ! !RORectangleTreeMap methodsFor: 'initialize' stamp: 'RobertoMinelli 10/7/2013 13:33'! initialize super initialize. currentSubrectangle := self. subrectangles := OrderedCollection new. inset := 0.! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/7/2013 13:38'! inset ^ inset! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/7/2013 13:38'! inset: anInteger inset := anInteger! ! !RORectangleTreeMap methodsFor: 'testing' stamp: 'RobertoMinelli 10/3/2013 14:53'! isHorizontal ^ (self width >= self height)! ! !RORectangleTreeMap methodsFor: 'accessing-computing' stamp: 'RobertoMinelli 10/3/2013 14:10'! nextSubrectangle self currentSubrectangle: self subrectangles last.! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/7/2013 17:58'! origin: aPoint origin := aPoint! ! !RORectangleTreeMap methodsFor: 'printing' stamp: 'RobertoMinelli 10/3/2013 14:46'! printOn: aStream aStream nextPutAll: self printString! ! !RORectangleTreeMap methodsFor: 'printing' stamp: 'RobertoMinelli 10/3/2013 14:46'! printString ^ 'R', self origin printString, ' <', self width printString, 'x', self height printString,'>'.! ! !RORectangleTreeMap methodsFor: 'accessing-computing' stamp: 'RobertoMinelli 10/7/2013 10:30'! shortestSide ^ self width min: self height! ! !RORectangleTreeMap methodsFor: 'accessing' stamp: 'RobertoMinelli 10/3/2013 14:36'! subrectangles ^ subrectangles ! ! !Rectangle methodsFor: '*Roassal-Core' stamp: 'AlexandreBergel 8/27/2012 09:57'! roCorner: aPoint "This method should not be. But the tree map layout works that way" corner := aPoint! ! !Rectangle methodsFor: '*Roassal-Core' stamp: 'AlexandreBergel 8/27/2012 09:57'! roOrigin: aPoint "This method should not be. But the tree map layout works that way" origin := aPoint! ! !PPStream commentStamp: '' prior: 34265371! A positional stream implementation used for parsing. It overrides some methods for optimization reasons.! !PPBrowserStream methodsFor: 'converting' stamp: 'lr 4/15/2010 15:12'! asExecutionTrace | trace | trace := OrderedCollection new: parsers size. 1 to: parsers size do: [ :index | | parser | parser := parsers at: index. parser name isNil ifFalse: [ | start stop | start := positions at: index. stop := positions at: index + 1 ifAbsent: [ self size ]. trace addLast: (Array with: parser with: start with: stop) ] ]. ^ trace! ! !PPBrowserStream methodsFor: 'converting' stamp: 'lr 2/3/2010 20:21'! asFrequencyTable | bag total result | bag := parsers asBag. total := 100.0 / bag size. result := OrderedCollection new. bag sortedCounts do: [ :each | result addLast: (Array with: each value with: each key with: total * each key) ]. ^ result! ! !PPBrowserStream methodsFor: 'converting' stamp: 'lr 6/3/2010 10:29'! asPositionDrawing | stream source last | stream := WriteStream on: String new. source := self contents readStream. last := 0. [ source atEnd ] whileFalse: [ [ source atEnd not and: [ source peek isSeparator ] ] whileTrue: [ source next ]. stream nextPutAll: '\fill [source] ('; print: source position / 100.0; nextPutAll: ', 0) rectangle ('. [ source atEnd not and: [ source peek isSeparator not ] ] whileTrue: [ source next ]. stream print: source position / 100.0; nextPutAll: ', '; print: self positions size / 100.0; nextPutAll: ');'; cr ]. stream nextPutAll: '\draw [parser] (0, 0)'. 1 to: self positions size do: [ :index | last <= (self positions at: index) ifTrue: [ stream nextPutAll: ' --' ]. last := self positions at: index. stream nextPutAll: ' ('; print: last / 100.0; nextPutAll: ', '; print: index / 100.0; nextPut: $) ]. stream nextPut: $;. ^ stream contents! ! !PPBrowserStream methodsFor: 'converting' stamp: 'lr 6/4/2010 14:53'! asPositionMorph | width height canvas morph | width := self size + 1 min: 2048. height := self positions size min: 2048. canvas := FormCanvas extent: width @ height. self contents keysAndValuesDo: [ :index :char | char isSeparator ifFalse: [ canvas line: index @ 1 to: index @ height color: Color paleBlue ] ]. 1 to: height do: [ :index | canvas form colorAt: (self positions at: index) @ index put: Color black ]. morph := canvas form asMorph. morph on: #mouseDown send: #mouseDown:with: to: self. ^ morph! ! !PPBrowserStream methodsFor: 'converting' stamp: 'lr 2/3/2010 20:21'! asTimingTable | bag total result | bag := Bag new. 1 to: stamps size - 1 do: [ :index | bag add: (parsers at: index) withOccurrences: (stamps at: index + 1) - (stamps at: index) ]. total := stamps last - stamps first. result := OrderedCollection new. bag sortedCounts do: [ :each | result addLast: (Array with: each value with: each key with: total * each key) ]. ^ result! ! !PPBrowserStream methodsFor: 'accessing' stamp: 'DiegoLont 6/25/2013 09:58'! displayName ^self class name! ! !PPBrowserStream methodsFor: 'private' stamp: 'lr 1/30/2013 19:35'! mouseDown: anEvent with: aMorph | location string parser | location := anEvent position. string := collection copyFrom: (location x - 5 min: collection size max: 1) asInteger to: (location x + 5 min: collection size max: 1) asInteger. parser := parsers at: location y! ! !PPBrowserStream methodsFor: 'accessing' stamp: 'lr 2/3/2010 13:45'! next | result | result := super next. self step. ^ result! ! !PPBrowserStream methodsFor: 'accessing' stamp: 'lr 2/3/2010 13:45'! next: aNumber | result | result := super next: aNumber. self step. ^ result! ! !PPBrowserStream methodsFor: 'information' stamp: 'lr 2/3/2010 14:55'! parsers ^ parsers! ! !PPBrowserStream methodsFor: 'positioning' stamp: 'lr 2/3/2010 13:46'! position: aNumber super position: aNumber. self step! ! !PPBrowserStream methodsFor: 'information' stamp: 'lr 2/3/2010 14:55'! positions ^ positions! ! !PPBrowserStream methodsFor: 'positioning' stamp: 'lr 2/3/2010 14:53'! reset super reset. positions := OrderedCollection new: 1024. stamps := OrderedCollection new: 1024. parsers := OrderedCollection new: 1024! ! !PPBrowserStream methodsFor: 'information' stamp: 'lr 2/3/2010 14:55'! stamps ^ stamps! ! !PPBrowserStream methodsFor: 'private' stamp: 'TudorGirba 3/8/2011 12:08'! step positions addLast: position. stamps addLast: Time millisecondClockValue. parsers addLast: thisContext sender sender receiver! ! !PPStream methodsFor: 'converting' stamp: 'lr 2/7/2010 20:53'! asPetitStream ^ self! ! !PPStream methodsFor: 'accessing' stamp: 'lr 2/13/2012 20:25'! collection "Answer the underlying collection." ^ collection! ! !PPStream methodsFor: 'accessing' stamp: 'lr 4/29/2008 21:48'! peek "An improved version of peek, that is slightly faster than the built in version." ^ self atEnd ifFalse: [ collection at: position + 1 ]! ! !PPStream methodsFor: 'accessing' stamp: 'lr 8/25/2010 11:36'! position: anInteger "The receiver does not check for invalid arguments passed to this method, as it is solely used with valid indexes for backtracking." position := anInteger! ! !PPStream methodsFor: 'printing' stamp: 'lr 11/4/2010 19:23'! printOn: aStream collection isString ifFalse: [ ^ super printOn: aStream ]. aStream nextPutAll: (collection copyFrom: 1 to: position); nextPutAll: '·'; nextPutAll: (collection copyFrom: position + 1 to: readLimit)! ! !PPStream methodsFor: 'accessing' stamp: 'lr 10/5/2010 16:29'! uncheckedPeek "An unchecked version of peek that throws an error if we try to peek over the end of the stream, even faster than #peek." ^ collection at: position + 1! ! !Point class methodsFor: '*roassal-core'! radius: radius theta: angle ^ (radius * angle cos) @ (radius * angle sin)! ! !SimpleButtonMorph methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 16:01'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !MessageSend methodsFor: '*glamour-helpers' stamp: 'TudorGirba 9/25/2013 06:53'! glamourValueWithArgs: anArray "This is the same as valueWithPossibleArgs: from squeak. Unfortunately, VW's cullValue: is incompatible." self selector isUnary ifTrue: [^self value]. self selector numArgs = anArray size ifTrue: [^self valueWithArguments: anArray]. self selector numArgs > anArray size ifTrue: [^self valueWithArguments: anArray , (Array new: self selector numArgs - anArray size)]. ^self valueWithArguments: (anArray copyFrom: 1 to: self selector numArgs)! ! !Association methodsFor: '*Glamour-Helpers' stamp: 'tg 10/25/2010 02:00'! asGlamourOriginIdentifier ^ GLMPortIdentifier new paneName: self key; portName: self value! ! !Association methodsFor: '*Glamour-Helpers' stamp: 'tg 10/25/2010 02:01'! asGlamourTargetIdentifier ^ GLMPortIdentifier new paneName: self key; portName: self value! ! !BlockClosure methodsFor: '*petitparser-core-converting' stamp: 'lr 11/29/2011 20:48'! asParser "Answer a parser implemented in the receiving one-argument block." ^ PPPluggableParser on: self! ! !BlockClosure methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! glamourValueWithArgs: anArray "This is the same as valueWithPossibleArgs: from squeak. Unfortunately, VW's cullValue: is incompatible." self numArgs = 0 ifTrue: [^self value]. self numArgs = anArray size ifTrue: [^self valueWithArguments: anArray]. self numArgs > anArray size ifTrue: [^self valueWithArguments: anArray , (Array new: self numArgs - anArray size)]. ^self valueWithArguments: (anArray copyFrom: 1 to: self numArgs)! ! !BlockClosure methodsFor: '*roassalmorphic' stamp: 'DR 1/15/2013 20:52'! roValue: valueOrArray self numArgs = 0 ifTrue: [ ^ self value ]. self numArgs = 1 ifTrue: [ ^ self value: valueOrArray ]. "if I have more than 1 argument, then the valueOrArray is a collection" valueOrArray isCollection ifFalse: [ self error: 'A block with more than one argument can only be evaluated with a collection ' ]. self numArgs = valueOrArray size ifTrue: [ ^ self valueWithArguments: valueOrArray ]. self error: 'Incorrect number of arguments' ! ! !ScrollBar methodsFor: '*glamour-morphic-widgets' stamp: 'TudorGirba 1/16/2011 13:10'! glmAnimateValue: aNumber duration: anInteger " aNumber = value ifTrue: [^ self ]." anInteger <= 0 ifTrue: [ self setValue: aNumber ] ifFalse: [ | startTime start end | startTime := Time millisecondClockValue. start := value "roundTo: scrollDelta". [ | delta | [ (delta := Time millisecondClockValue - startTime) < anInteger ] whileTrue: [ self setValue: (aNumber - start) * (delta / anInteger) + start. Processor yield ]. self setValue: aNumber ] fork ]! ! !ScrollBar methodsFor: '*glamour-morphic-widgets' stamp: 'cyrilledelaunay 6/6/2011 15:58'! setOptimalResizing self hResizing: #rigid. self vResizing: #rigid! ! !AbstractFont methodsFor: '*roassalmorphic' stamp: 'DR 1/23/2013 17:40'! fontSize ^self ascent + self descent! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:43'! adjustPaneHeight "This gets called after the scrollbar has been shown or hidden, to move the bottom of the panes to the right place." transform bounds: self innerBounds. transform submorphsDo: [:m | m bounds: (m bounds withHeight: self paneHeight)]! ! !GLMPaneScroller methodsFor: 'scrolling'! adoptPaneColor: aColor super adoptPaneColor: aColor. scrollBar adoptPaneColor: aColor! ! !GLMPaneScroller methodsFor: 'private' stamp: 'jorge.ressia 5/25/2009 16:25'! basicUpdateSizing sizing := (self paneCount min: self maxPanes) max: 1! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:21'! bounds: aRectangle super bounds: aRectangle. self layoutWidgets. self layoutPanes. self setScrollDeltas. ! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:21'! computeMorphWidths | paneWidths widths | paneWidths := self paneWidthsToFit: self totalPaneWidth. widths := OrderedCollection new. paneWidths do: [:w | widths add: w] separatedBy: [widths add: self separatorWidth]. ^ widths asArray ! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! hideOrShowScrollBar self isScrollable ifTrue: [self showScrollBar] ifFalse: [self hideScrollBar]! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! hideScrollBar self removeMorph: scrollBar. self adjustPaneHeight.! ! !GLMPaneScroller methodsFor: 'initialization' stamp: 'TudorGirba 11/30/2012 14:26'! initialize super initialize. self color: Color transparent; borderWidth: 0; vResizing: #spaceFill; hResizing: #spaceFill. self initializeTransform; initializeScrollbar. paneCount := 0. maxPanes := 2.! ! !GLMPaneScroller methodsFor: 'initialization' stamp: 'TudorGirba 2/17/2012 07:47'! initializeScrollbar scrollBar := ScrollBar new model: self; setValueSelector: #scrollBarValue:; yourself. scrollBar borderWidth: 0; borderColor: #inset; height: self scrollBarHeight. self resizeScrollBar. ! ! !GLMPaneScroller methodsFor: 'initialization' stamp: 'david_roethlisberger 3/18/2009 14:26'! initializeTransform transform := TransformMorph new. transform color: Color transparent; borderWidth: 0; vResizing: #spaceFill; hResizing: #spaceFill; disableTableLayout; bounds: super innerBounds. self addMorphBack: transform. ! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:21'! innerBounds | rect | rect := super innerBounds. ^ self scrollBarIsVisible ifTrue: [rect withHeight: rect height - self scrollBarHeight - 1] ifFalse: [rect]! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! isScrollable ^ self leftoverScrollRange > 0! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:21'! layoutPanes | widths rect | widths := self computeMorphWidths. rect := 0@0 extent: (0 @ self paneHeight). transform submorphs with: widths do: [:m :w | rect := rect withWidth: w. m bounds: rect. rect := rect translateBy: (w@0)] ! ! !GLMPaneScroller methodsFor: 'layout'! layoutWidgets | inner outer | outer := super innerBounds. inner := self innerBounds. transform bounds: inner. scrollBar bounds: ((inner left @ inner bottom) corner: outer bottomRight)! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! leftoverScrollRange ^ (self totalScrollRange - self innerBounds width roundTo: self scrollDeltaWidth) max: 0 ! ! !GLMPaneScroller methodsFor: 'configuration' stamp: 'TudorGirba 1/26/2011 07:14'! maxPanes ^ maxPanes! ! !GLMPaneScroller methodsFor: 'configuration' stamp: 'TudorGirba 1/26/2011 07:14'! maxPanes: anInteger maxPanes := anInteger! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'jorge.ressia 5/25/2009 16:18'! paneCount ^ paneCount! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:22'! paneHeight ^ transform bounds height! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:22'! paneWidthsToFit: limit | padded | padded := Array new: self paneCount. padded atAllPut: (limit / self sizing) floor. (1 to: limit - padded sum) do: [:i | padded at: i put: (padded at: i) + 1]. ^ padded ! ! !GLMPaneScroller methodsFor: 'panes' stamp: 'tg 8/22/2010 22:40'! popAndReplacePane: aMorph transform removeMorph: transform lastSubmorph. "one for the separator" transform submorphs isEmpty ifFalse: [ transform removeMorph: transform lastSubmorph ]. paneCount := paneCount - 1. aMorph borderWidth: 0; hResizing: #spaceFill; vResizing: #spaceFill; layoutInset: 0. transform hasSubmorphs ifTrue: [ transform addMorphBack: self separator ]. transform addMorphBack: (aMorph adoptPaneColor: self paneColor). paneCount := paneCount + 1. self updatePanes! ! !GLMPaneScroller methodsFor: 'panes'! popPane transform removeMorph: transform lastSubmorph. "one for the separator" transform submorphs isEmpty ifFalse: [ transform removeMorph: transform lastSubmorph ]. paneCount := paneCount - 1. self updatePanes.! ! !GLMPaneScroller methodsFor: 'panes'! pushPane: aMorph aMorph borderWidth: 0; hResizing: #spaceFill; vResizing: #spaceFill; layoutInset: 0. transform hasSubmorphs ifTrue: [ transform addMorphBack: self separator ]. transform addMorphBack: (aMorph adoptPaneColor: self paneColor). paneCount := paneCount + 1. self updatePanes! ! !GLMPaneScroller methodsFor: 'layout'! resizeScrollBar | inner outer | outer := super innerBounds. inner := outer withHeight: outer height - self scrollBarHeight. scrollBar bounds: ((inner left @ inner bottom) corner: outer bottomRight)! ! !GLMPaneScroller methodsFor: 'layout'! scrollBarHeight ^ self theme scrollbarThickness! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! scrollBarIsVisible ^ submorphs includes: scrollBar! ! !GLMPaneScroller methodsFor: 'input events'! scrollBarMenuButtonPressed: anObject! ! !GLMPaneScroller methodsFor: 'updating' stamp: 'david_roethlisberger 3/18/2009 14:27'! scrollBarValue: value transform hasSubmorphs ifFalse: [^ self]. transform offset: (self leftoverScrollRange * value) rounded @ 0.! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:25'! scrollDeltaWidth ^ 1! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'TudorGirba 2/17/2012 07:48'! scrollToRight " (transform submorphs size + 1) / 2 > paneCount ifTrue: [ " scrollBar glmAnimateValue: 1.0 duration: 200 "]"! ! !GLMPaneScroller methodsFor: 'panes' stamp: 'TudorGirba 3/3/2013 21:42'! separator ^ "BorderedSubpaneDividerMorph new vertical; adoptPaneColor: self paneColor; yourself" GLMMorphic emptyMorph! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'TudorGirba 5/20/2013 06:37'! separatorWidth ^ 20! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:26'! setScrollDeltas | range interval value | transform hasSubmorphs ifFalse: [scrollBar interval: 1.0. ^ self]. range := self leftoverScrollRange. range = 0 ifTrue: [^ scrollBar interval: 1.0; setValue: 0]. interval := ((self innerBounds width) / self totalScrollRange) asFloat. value := (transform offset x / range min: 1.0) asFloat. scrollBar interval: interval. scrollBar setValue: value.! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:26'! showScrollBar self scrollBarIsVisible ifTrue: [^ self]. self resizeScrollBar. self addMorphFront: scrollBar. self adjustPaneHeight. ! ! !GLMPaneScroller methodsFor: 'accessing' stamp: 'david_roethlisberger 3/18/2009 14:27'! sizing ^ sizing ifNil: [self updateSizing]! ! !GLMPaneScroller methodsFor: 'layout' stamp: 'david_roethlisberger 3/18/2009 14:22'! totalPaneWidth ^ self innerBounds width - ((self sizing - 1) * self separatorWidth)! ! !GLMPaneScroller methodsFor: 'scrolling' stamp: 'david_roethlisberger 3/18/2009 14:26'! totalScrollRange | submorphBounds | submorphBounds := transform localSubmorphBounds ifNil: [^ 0]. ^ submorphBounds width ! ! !GLMPaneScroller methodsFor: 'updating' stamp: 'jorge.ressia 5/25/2009 16:40'! updatePanes self basicUpdateSizing. self layoutPanes. self hideOrShowScrollBar. self setScrollDeltas. self scrollToRight! ! !GLMPaneScroller methodsFor: 'updating' stamp: 'david_roethlisberger 3/18/2009 14:27'! updateSizing | old | old := sizing. self basicUpdateSizing. sizing = old ifFalse: [self layoutPanes]. ^sizing! ! !Array methodsFor: '*roassal-core'! @ interactionClassOrObject | obj | obj := interactionClassOrObject elementToBeAdded. self do: [ :el | el addInteraction: obj ]. ^ self! ! !Character methodsFor: '*petitparser-core-operators' stamp: 'lr 6/12/2010 09:04'! - aCharacter "Create a range of characters between the receiver and the argument." ^ PPPredicateObjectParser between: self and: aCharacter! ! !Character methodsFor: '*petitparser-core-converting' stamp: 'lr 12/18/2011 15:58'! asParser "Answer a parser that accepts the receiving character." ^ PPLiteralObjectParser on: self! ! !Number methodsFor: '*roassal-core'! max: max in: anInterval " (0 max: 20 in: (1 to: 10)) == 1 (0 max: 20 in: (0 to: 10)) == 0 (0 max: 20 in: (1 to: 10)) == 1 (2 max: 20 in: (0 to: 10)) == 1 (4 max: 20 in: (0 to: 10)) == 2 (20 max: 20 in: (0 to: 10)) == 10 " ^ self min: 0 max: max in: anInterval! ! !Number methodsFor: '*roassal-core' stamp: 'JurajKubelka 5/22/2013 14:06'! min: min max: max in: anInterval " (0 max: 20 in: (1 to: 10)) == 1 (0 max: 20 in: (0 to: 10)) == 0 (0 max: 20 in: (1 to: 10)) == 1 (2 max: 20 in: (0 to: 10)) == 1 (4 max: 20 in: (0 to: 10)) == 2 (19 max: 20 in: (0 to: 10)) == 10 " min = max ifTrue: [ ^ min ]. ^ (self - min) / (max - min) * (anInterval last - anInterval first) + anInterval first ! ! !ArrayedCollection class methodsFor: '*Glamour-Helpers' stamp: 'tg 5/4/2009 22:14'! with: anObject withAll: aCollection | newArray | newArray := self new: aCollection size + 1. newArray at: 1 put: anObject. newArray replaceFrom: 2 to: newArray size with: aCollection. ^newArray "Array with: 1 withAll: #(2 3 4)"! ! !GLMAnnouncer commentStamp: 'TudorGirba 1/23/2011 00:58' prior: 34265544! This is a specialization of the Announcer. The main added functionality is the ability to suspend the announcements from this announcer.! !GLMAnnouncer methodsFor: 'announce' stamp: 'TudorGirba 5/18/2011 13:41'! announce: anAnnouncement self suspendAll ifTrue: [ ^ anAnnouncement asAnnouncement ]. ^ super announce: anAnnouncement! ! !GLMAnnouncer methodsFor: 'accessing' stamp: 'tg 5/24/2010 17:27'! announcer ^ self! ! !GLMAnnouncer methodsFor: 'accessing' stamp: 'TudorGirba 7/10/2011 02:10'! glmSubscriptions ^ registry glmSubscriptions! ! !GLMAnnouncer methodsFor: 'copying' stamp: 'TudorGirba 7/11/2011 11:16'! postCopy super postCopy. registry := registry copy.! ! !GLMAnnouncer methodsFor: 'accessing' stamp: 'TudorGirba 5/18/2011 13:45'! resetAnnouncer registry reset! ! !GLMAnnouncer methodsFor: 'suspending' stamp: 'tg 2/17/2010 23:04'! suspendAll ^ suspendAll ifNil: [ suspendAll := false ].! ! !GLMAnnouncer methodsFor: 'suspending' stamp: 'tg 2/18/2010 00:00'! suspendAllWhile: aBlock | previousSuspensionState | previousSuspensionState := suspendAll. suspendAll := true. aBlock value. suspendAll := previousSuspensionState.! ! !GLMAction commentStamp: '' prior: 34265732! Actions are elements of behavior that are executed upon a keyboard shortcut or other event. Instances of Action are stored and maintained by Presentations. The exact representation is determined by the renderer, but actions can define a keyboard shortcut that should trigger the action or a title, category and position to be able to use the action as a context menu item.! !GLMAction methodsFor: 'public interface' stamp: 'TudorGirba 12/16/2011 17:45'! actOn: aPresentation ^ self action glamourValueWithArgs: (Array with: aPresentation withAll: aPresentation entity asGlamorousArray)! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! action "The code that should be executed when this action is triggered." ^action! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! action: aBlock "The code that should be executed when this action is triggered. The block can take optional arguments, the first will always be the presentation on which this action was triggered." action := aBlock! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! category "The name of the category that should be used when this action is displayed in a context menu." ^category! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! category: aString "The name of the category that should be used when this action is displayed in a context menu." category := aString! ! !GLMAction methodsFor: 'testing' stamp: 'tg 9/28/2009 11:09'! hasIcon ^self icon notNil! ! !GLMAction methodsFor: 'testing' stamp: ' 4/5/09 22:18'! hasShortcut ^self shortcut notNil! ! !GLMAction methodsFor: 'testing' stamp: ' 4/5/09 22:18'! hasTitle ^self title notNil! ! !GLMAction methodsFor: 'accessing' stamp: 'tg 9/28/2009 11:06'! icon ^ icon! ! !GLMAction methodsFor: 'accessing' stamp: 'tg 9/28/2009 11:06'! icon: anObject icon := anObject! ! !GLMAction methodsFor: 'testing' stamp: 'EstebanLorenzano 4/20/2012 15:00'! isButton ^self hasIcon! ! !GLMAction methodsFor: 'testing' stamp: 'tg 9/17/2009 15:02'! isCategorized ^self category notNil! ! !GLMAction methodsFor: 'testing' stamp: 'EstebanLorenzano 4/20/2012 15:00'! isMenu ^self hasTitle and: [ self hasIcon not]! ! !GLMAction methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 8/9/2011 13:56'! morphicActOn: aPresentation ^ self actOn: aPresentation! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! position "The relative position within a context menu." ^position! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! position: anInteger "The relative position within a context menu." position := anInteger! ! !GLMAction methodsFor: 'as yet unclassified' stamp: 'EstebanLorenzano 4/20/2012 15:11'! renderGlamorouslyOn: aRenderer ^aRenderer renderAction: self! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! shortcut "Shortcut character that this action should be triggered with when the focus rests on the corresponding presentation. Modifiers are platform specific an can not be defined." ^shortcut! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! shortcut: aCharacter "Shortcut character that this action should be triggered with when the focus rests on the corresponding presentation. Modifiers are platform specific an can not be defined." shortcut := aCharacter! ! !GLMAction methodsFor: 'accessing' stamp: 'TudorGirba 11/28/2012 22:12'! shortcutAsString "Answers a string explaining shortcut" ^self shortcut isNil ifTrue: [''] ifFalse: [ 'alt+', (self shortcut isUppercase ifTrue: [ 'shift+' ] ifFalse: [ '' ]), self shortcut asLowercase asString ]! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! title "Title that this action should use in a context menu." ^title! ! !GLMAction methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! title: anObject "Title that this action should use in a context menu." title := anObject! ! !GLMAction methodsFor: 'testing' stamp: 'tg 9/25/2010 17:52'! worksWithMorphic ^ false! ! !GLMAction methodsFor: 'testing' stamp: 'tg 9/25/2010 17:52'! worksWithSeaside ^ false! ! !GLMGenericAction commentStamp: '' prior: 34266164! This is an action that is supposed to work in any context (e.g., Morphic or Seaside)! !GLMGenericAction methodsFor: 'testing' stamp: 'tg 9/25/2010 17:53'! worksWithMorphic ^ true! ! !GLMGenericAction methodsFor: 'testing' stamp: 'tg 9/25/2010 17:53'! worksWithSeaside ^ true! ! !GLMSpawnBrowserAction methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 8/9/2011 13:57'! morphicActOn: aPresentation ^ (self actOn: aPresentation) open! ! !GLMMorphicAction commentStamp: '' prior: 34266307! A GLMMorphicAction is special GLMAction that is only active when rendering Glamour browsers with Morphic.! !GLMMorphicAction methodsFor: 'testing' stamp: 'tg 9/24/2010 15:36'! worksWithMorphic ^ true! ! !GLMLoggedObject class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 17:05'! initialize logger := GLMLogger instance! ! !GLMLoggedObject class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 16:47'! logger ^ logger! ! !GLMLoggedObject class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 16:48'! logger: aLogger logger := aLogger! ! !GLMLoggedObject methodsFor: 'announce' stamp: 'tg 5/25/2010 23:53'! announce: anAnnouncement self logger logAnnouncement: anAnnouncement from: self. super announce: anAnnouncement! ! !GLMLoggedObject methodsFor: 'initialize-release' stamp: 'TudorGirba 5/18/2011 12:06'! initialize super initialize. logger := GLMLogger instance ! ! !GLMLoggedObject methodsFor: 'accessing' stamp: 'tg 5/24/2010 16:43'! logger ^ logger! ! !GLMLoggedObject methodsFor: 'accessing' stamp: 'tg 5/24/2010 16:43'! logger: anObject logger := anObject! ! !GLMLoggedObject methodsFor: 'copying' stamp: 'TudorGirba 7/11/2011 11:20'! postCopy super postCopy. self resetAnnouncer! ! !GLMNoBrowser commentStamp: 'TudorGirba 2/4/2011 20:22' prior: 34266480! A NoBrowser is a browser without behavior and that does not require a container pane. The root pane is always placed in a NoBrowser. Given that it has no behavior, a NoBrowser is a singleton to avoid multiple unnecessary instances.! !GLMNoBrowser class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 6/3/2009 08:30'! initialize self initializeUniqueInstance! ! !GLMNoBrowser class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 17:17'! initializeUniqueInstance uniqueInstance := self basicNew initialize! ! !GLMNoBrowser class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 6/3/2009 08:29'! new ^self uniqueInstance! ! !GLMNoBrowser class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 6/3/2009 08:30'! uniqueInstance ^uniqueInstance! ! !GLMNoBrowser methodsFor: 'accessing' stamp: 'TudorGirba 2/4/2011 20:23'! innerPortEvent: aPortEvent "Needed for simulating a browser"! ! !GLMPane commentStamp: 'TudorGirba 2/15/2011 11:03' prior: 34266775! A GLMPane represents the "physical" building block of a browser. A pane is presented using a composite presentation (held in the presentations instance var). It announces: - GLMMatchingPresentationsChanged - GLMPresentationsChanged Instance Variables browser: Browser lastActivePresentation: Presentation name: Symbol ports: Collection of Ports presentations: CompositePresentation! !GLMPane class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 6/3/2009 09:09'! in: aBrowser ^self new initializeIn: aBrowser! ! !GLMPane class methodsFor: 'instance creation' stamp: 'jorge.ressia 6/2/2009 23:42'! named: aString ^self new initializeNamed: aString! ! !GLMPane class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 6/2/2009 20:28'! named: aString in: aBrowser ^self new initializeNamed: aString in: aBrowser ! ! !GLMPane class methodsFor: 'private' stamp: ' 4/5/09 22:18'! portClass ^GLMPanePort! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 4/11/2010 23:28'! addPresentation: aPresentation self addPresentations: (OrderedCollection with: aPresentation)! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 5/25/2010 14:40'! addPresentationSilently: each ^ presentations add: (each pane: self; yourself)! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 5/25/2010 14:40'! addPresentations: aCollection self notingPresentationChangeDo: [ aCollection do: [ :each | self addPresentationSilently: each ] ]! ! !GLMPane methodsFor: 'converting' stamp: ' 4/5/09 22:18'! asGlamorousPane ^self! ! !GLMPane methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! browser ^browser! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 12/29/2009 23:19'! browser: aBrowser browser := aBrowser! ! !GLMPane methodsFor: 'accessing' stamp: 'TudorGirba 12/5/2011 12:55'! cachedMatchingPresentations ^ cachedMatchingPresentations ifNil: [ cachedMatchingPresentations := self matchingPresentations ]! ! !GLMPane methodsFor: 'accessing' stamp: 'TudorGirba 12/5/2011 12:54'! cachedMatchingPresentations: anObject ^ cachedMatchingPresentations := anObject! ! !GLMPane methodsFor: 'accessing' stamp: 'TudorGirba 7/21/2011 13:43'! clearIn: aContext self notingPresentationChangeDo: [ self presentations clear. self ports do: [:each | each value: nil in: aContext copy ]]! ! !GLMPane methodsFor: 'initialization' stamp: 'jorge.ressia 6/3/2009 09:10'! defaultName ^'undefined'! ! !GLMPane methodsFor: 'testing' stamp: ' 4/5/09 22:18'! hasBrowser ^self browser isNil not! ! !GLMPane methodsFor: 'initialization' stamp: 'tg 5/25/2010 14:12'! initialize super initialize. ports := OrderedCollection new. presentations := GLMCompositePresentation new pane: self; yourself! ! !GLMPane methodsFor: 'initialization' stamp: 'jorge.ressia 6/3/2009 09:10'! initializeIn: aBrowser self initializeNamed: self defaultName in: aBrowser! ! !GLMPane methodsFor: 'initialization' stamp: 'jorge.ressia 6/2/2009 23:43'! initializeNamed: aString self initializeNamed: aString in: GLMNoBrowser new ! ! !GLMPane methodsFor: 'initialization' stamp: 'tg 1/11/2010 21:59'! initializeNamed: aString in: aBrowser self initialize. name := aString ifNil: [ self defaultName ]. browser := aBrowser! ! !GLMPane methodsFor: 'private' stamp: 'tg 12/30/2009 18:50'! isAllowedToNotePresentationsChanged ^ allowedToNotePresentationsChanged ifNil: [allowedToNotePresentationsChanged := true ]! ! !GLMPane methodsFor: 'testing' stamp: 'TudorGirba 1/28/2011 00:13'! isLastActivePresentation: aPresentation ^ self lastActivePresentation notNil and: [ aPresentation title = self lastActivePresentation title ]! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 10/18/2009 19:29'! lastActivePresentation ^ lastActivePresentation! ! !GLMPane methodsFor: 'accessing' stamp: 'AndreiChis 5/24/2013 11:29'! lastActivePresentation: anObject (self port: #activePresentation) value: anObject. lastActivePresentation := anObject! ! !GLMPane methodsFor: 'accessing' stamp: 'TudorGirba 12/5/2011 12:54'! matchingPresentations ^ cachedMatchingPresentations := presentations matchingPresentations! ! !GLMPane methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! name ^name! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 1/12/2010 07:30'! name: aString name := aString! ! !GLMPane methodsFor: 'private' stamp: 'TudorGirba 12/5/2011 12:54'! notingPresentationChangeDo: aBlock "Executes aBlock. If during the execution of the block one of my presentations change, I will emit announces. I also take care of not entering an infinite loop." | oldPresentations oldMatchingPresentations | self isAllowedToNotePresentationsChanged ifFalse: [ aBlock value. ^ self]. "this should create a context and then check for it before announcing. Like this we can deal with the problem of announcing the same announcement twice" allowedToNotePresentationsChanged := false. oldPresentations := presentations presentations copy. oldMatchingPresentations := self cachedMatchingPresentations. aBlock value. presentations presentations ~= oldPresentations ifTrue: [ self announce: ((GLMPresentationsChanged new) pane: self; oldPresentations: oldPresentations; yourself)]. self matchingPresentations ~= oldMatchingPresentations ifTrue: [ self announce: ((GLMMatchingPresentationsChanged new) pane: self; oldMatchingPresentations: oldMatchingPresentations; yourself)]. allowedToNotePresentationsChanged := true. ! ! !GLMPane methodsFor: 'accessing' stamp: 'TudorGirba 2/4/2011 15:36'! port: aSymbol "returns the port with the given name" ^ ports detect: [ :each | each name = aSymbol ] ifNone: [ ports addLast: ( (self class portClass new) pane: self; name: aSymbol; yourself) ]! ! !GLMPane methodsFor: 'private' stamp: 'AndreiChis 11/15/2012 14:19'! portEvent: aPortEvent "we unregister all presentations from announcements because they will get replaced anyway" aPortEvent portName = #entity ifTrue: [ self unregisterFromAllAnnouncements ]. self browser innerPortEvent: aPortEvent. self presentations outerPortEvent: aPortEvent! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 1/12/2010 07:36'! ports ^ ports! ! !GLMPane methodsFor: 'copying' stamp: 'TudorGirba 7/11/2011 11:17'! postCopy | newPort | super postCopy. self flag: 'self unregisterFromAllAnnouncements ?'. presentations := presentations copy. ports := ports collect: [:each | newPort := each copy. newPort pane: self. self flag: 'what about value?'. newPort ]! ! !GLMPane methodsFor: 'accessing' stamp: 'tg 1/11/2010 18:06'! presentations ^ presentations! ! !GLMPane methodsFor: 'accessing' stamp: 'AndreiChis 6/23/2013 21:46'! presentations: aCompositePresentation self notingPresentationChangeDo: [ presentations pane: nil. presentations resetAnnouncer. aCompositePresentation pane: self. presentations := aCompositePresentation. presentations initializePresentation ]! ! !GLMPane methodsFor: 'printing' stamp: 'DamienCassou 7/3/2011 19:56'! printOn: aStream super printOn: aStream. aStream nextPut: $(; nextPutAll: self identityHash printString; space; nextPutAll: self name; nextPut: $)! ! !GLMPane methodsFor: 'rendering' stamp: ' 4/5/09 22:18'! renderGlamorouslyOn: aRenderer ^aRenderer renderPane: self! ! !GLMPane methodsFor: 'announcements' stamp: 'TudorGirba 7/10/2011 17:25'! resetAnnouncer super resetAnnouncer. self presentations do: [ :each | each resetAnnouncer ]! ! !GLMPane methodsFor: 'updating' stamp: 'tg 1/31/2010 00:26'! unregisterFromAllAnnouncements self presentations unregisterFromAllAnnouncements! ! !GLMPane methodsFor: 'updating' stamp: 'TudorGirba 12/5/2011 12:57'! update self notingPresentationChangeDo: [ "nothing in particular. just make sure that matching presentations are recomputed"]. self presentations do: [ :each | each update ]! ! !GLMPane methodsFor: 'enumerating' stamp: 'TudorGirba 7/10/2011 01:19'! withAllPanes | result | result := OrderedCollection new. self withAllPanesAndPresentationsDo: [:each | (each isKindOf: GLMPane) ifTrue: [ result add: each ]]. ^ result! ! !GLMPane methodsFor: 'enumerating' stamp: 'TudorGirba 7/9/2011 19:45'! withAllPanesAndPresentationsDo: aBlock aBlock value: self. self presentations withAllPanesAndPresentationsDo: aBlock! ! !GLMPane methodsFor: 'enumerating' stamp: 'TudorGirba 7/9/2011 20:06'! withAllPresentations | result | result := OrderedCollection new. self withAllPanesAndPresentationsDo: [:each | (each isKindOf: GLMPresentation) ifTrue: [ result add: each ]]. ^ result! ! !GLMPort commentStamp: 'tg 12/19/2009 00:15' prior: 34267225! GLMPort represents the abstract port. Any port has a name. Subclasses can provide further semantics to a port.! !GLMBoundPort methodsFor: 'comparing' stamp: ' 4/5/09 22:18'! = anObject "Compare this port with another for equality. This is used to compare ParentPorts with PanePorts where the earlier is a proxy for the latter." ^((anObject isKindOf: GLMBoundPort) and: [self pane = anObject pane]) and: [self name = anObject name]! ! !GLMBoundPort methodsFor: 'testing' stamp: ' 4/5/09 22:18'! hasPane ^self pane notNil! ! !GLMBoundPort methodsFor: 'comparing' stamp: ' 4/5/09 22:18'! hash "Ports which are equal should return hash. Since equality is used only for matching port proxies (ParentPort) with their actual port, the hash function is overridden only in ParentPort." ^super hash! ! !GLMBoundPort methodsFor: 'validation' stamp: 'simondenier 4/15/2010 15:55'! notingPresentationChangeDo: aBlock self pane notingPresentationChangeDo: aBlock! ! !GLMBoundPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane self subclassResponsibility! ! !GLMBoundPort methodsFor: 'validation' stamp: 'JorgeRessia 11/6/2009 13:09'! validate: anObject self pane presentations isEmpty ifTrue: [^true]. ^self pane presentations allSatisfy: [ :each | each validate: anObject on: self]! ! !GLMPanePort commentStamp: '' prior: 34267389! A port that belongs to a pane. Bound ports have a few special characteristics in comparison to their superclass. For one, they don't just assign a value to themselves using #value: but rather generate a transmission that set the value so that the pane can handle the transmission and forward it to other ports if necessary, depending on the policy of the containing browser.! !GLMPanePort methodsFor: 'accessing' stamp: 'jorge.ressia 5/30/2009 14:05'! basicValue: anObject value := anObject. ! ! !GLMPanePort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:43'! changeValueTo: anObject in: aTransmissionContext | oldValue | oldValue := self value. self pane notingPresentationChangeDo: [ self silentValue: anObject. self pane portEvent: (GLMPortEvent on: self previouslyValued: oldValue in: aTransmissionContext) ]! ! !GLMPanePort methodsFor: 'copying' stamp: 'tg 12/30/2009 03:04'! copyAccordingToPaneMapping: newPanesMapping inNewBrowser: anotherBrowser ^ (newPanesMapping at: self pane) port: self name! ! !GLMPanePort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane ^pane! ! !GLMPanePort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane: aPane pane := aPane! ! !GLMPanePort methodsFor: 'accessing' stamp: 'jre 9/19/2009 08:16'! printOn: aStream aStream nextPutAll: 'Port (pane='; nextPutAll: self pane name printString; nextPutAll: ' name='; nextPutAll: self name printString; nextPutAll: ' value='; nextPutAll: self value printString; nextPut: $)! ! !GLMPanePort methodsFor: 'accessing' stamp: 'tg 12/17/2009 03:12'! receive: aTransmission in: aContext self value: aTransmission value in: aContext! ! !GLMPanePort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 22:30'! resetValue | context | context := GLMTransmissionContext new. context addPort: self. self changeValueTo: nil in: context.! ! !GLMPanePort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:43'! silentValue: anObject value := anObject! ! !GLMPanePort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! value ^value! ! !GLMPanePort methodsFor: 'accessing' stamp: 'tg 2/17/2010 22:51'! value: anObject in: aContext (self validate: anObject) ifFalse: [^ self]. aContext addPort: self. self changeValueTo: anObject in: aContext.! ! !GLMPresentationBoundPort commentStamp: 'TudorGirba 2/4/2011 20:27' prior: 34267844! This is a fancy port that enables us to access the value of a port from outside of a browser. It is bound to a presentation in the sense that it asks the presentation dynamically for the pane. In this way, when a presentation is placed (or copied) in another pane, the value will be dynamically looked up. Instance Variables: presentation ! !GLMPresentationBoundPort methodsFor: 'copying' stamp: 'tg 12/30/2009 03:06'! copyAccordingToPaneMapping: newPanesMapping inNewBrowser: anotherBrowser ^ self copy presentation: anotherBrowser! ! !GLMPresentationBoundPort methodsFor: 'comparing' stamp: ' 4/5/09 22:18'! hash ^self port hash! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane ^self presentation pane! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! port ^self pane port: self name! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! presentation ^presentation! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! presentation: aPresentation presentation := aPresentation! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: 'tg 12/17/2009 03:14'! receive: aTransmission in: aContext self port receive: aTransmission in: aContext ! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:44'! silentValue: anObject self port silentValue: anObject ! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: 'TudorGirba 12/5/2011 14:33'! value self flag: 'checking for #entity is rather not elegant, but it is a solution to not affect the other custom ports that will probably be desired to be populated in other ways.'. ^ self name == #entity ifTrue: [ self presentation transformation glamourValue: self port value asGlamorousMultiValue ] ifFalse: [ self port value ]! ! !GLMPresentationBoundPort methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:57'! value: anObject in: aContext (self validate: anObject) ifFalse: [^ self]. self port value: anObject in: aContext! ! !GLMPort methodsFor: 'copying' stamp: 'tg 12/30/2009 03:05'! copyAccordingToPaneMapping: newPanesMapping inNewBrowser: anotherBrowser ^ self subclassResponsibility! ! !GLMPort methodsFor: 'testing' stamp: 'tg 1/5/2010 13:40'! hasPane ^ false! ! !GLMPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! name ^name! ! !GLMPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! name: aSymbol name := aSymbol! ! !GLMPort methodsFor: 'validation' stamp: 'simondenier 4/15/2010 15:56'! notingPresentationChangeDo: aBlock aBlock value! ! !GLMPort methodsFor: 'printing' stamp: 'tg 1/13/2010 16:31'! printOn: aStream super printOn: aStream. aStream nextPut: Character space; nextPutAll: self identityHash printString; nextPutAll: ' (name='; nextPutAll: self name printString; nextPutAll: ' value='; nextPutAll: self value printString; nextPut: $)! ! !GLMPort methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:53'! receive: aTransmission self receive: aTransmission in: GLMTransmissionContext new! ! !GLMPort methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:53'! receive: aTransmission in: aContext self subclassResponsibility! ! !GLMPort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:42'! silentValue: anObject "This is meant to be used internally" self subclassResponsibility! ! !GLMPort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:45'! transientValue: anObject | previousValue | previousValue := self value. self value: anObject. self silentValue: previousValue! ! !GLMPort methodsFor: 'validation' stamp: 'JorgeRessia 11/6/2009 13:10'! validate: anObject ^true! ! !GLMPort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! value self subclassResponsibility! ! !GLMPort methodsFor: 'accessing' stamp: 'tg 2/17/2010 14:02'! value: anObject self value: anObject in: GLMTransmissionContext new! ! !GLMPort methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:55'! value: anObject in: aContext self subclassResponsibility! ! !GLMSimplePort commentStamp: 'TudorGirba 2/4/2011 20:29' prior: 34268271! GLMSimplePort simply offers a hardcoded value. It is typically used in tests, but it can be useful in special cases when we need to simulate a Port. Instance Variables: value ! !GLMSimplePort methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:57'! receive: aTransmission in: aContext self value: aTransmission value in: aContext! ! !GLMSimplePort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:43'! silentValue: anObject value := anObject! ! !GLMSimplePort methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! value ^value! ! !GLMSimplePort methodsFor: 'accessing' stamp: 'TudorGirba 4/18/2011 19:43'! value: anObject in: aContext aContext addPort: self. self silentValue: anObject ! ! !GLMPortEvent commentStamp: 'tg 12/19/2009 00:12' prior: 34268539! A GLMPortEvent is passed to the parent pane every time a Port changes. Instance Variables oldValue: port: Port transmission: Transmission transmissionContext: TransmissionContext! !GLMPortEvent class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 5/30/2009 11:47'! on: aPort previouslyValued: anObject ^ self new initializeOn: aPort previouslyValued: anObject! ! !GLMPortEvent class methodsFor: 'as yet unclassified' stamp: 'jorge.ressia 5/30/2009 12:55'! on: aPort previouslyValued: anObject in: aTransmissionContext ^self new initializeOn: aPort previouslyValued: anObject in: aTransmissionContext ! ! !GLMPortEvent methodsFor: 'testing' stamp: 'DamienCassou 7/3/2011 19:52'! hasChanged "Answer whether the port value changed due to the event." ^ self value ~~ self oldValue! ! !GLMPortEvent methodsFor: 'initialize-release' stamp: 'jorge.ressia 5/30/2009 13:01'! initializeOn: aPort previouslyValued: anObject self initializeOn: aPort previouslyValued: anObject in: OrderedCollection new! ! !GLMPortEvent methodsFor: 'initialize-release' stamp: 'jorge.ressia 5/30/2009 12:58'! initializeOn: aPort previouslyValued: anObject in: aTransmissionContext port := aPort. oldValue := anObject. transmissionContext := aTransmissionContext! ! !GLMPortEvent methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! oldValue ^oldValue! ! !GLMPortEvent methodsFor: 'accessing-convenience' stamp: ' 4/5/09 22:18'! pane ^self port pane! ! !GLMPortEvent methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! port ^port! ! !GLMPortEvent methodsFor: 'accessing-convenience' stamp: ' 4/5/09 22:18'! portName ^self port name! ! !GLMPortEvent methodsFor: 'printing' stamp: 'tg 2/17/2010 19:10'! printOn: aStream super printOn: aStream. aStream nextPutAll: '(port='. self port printOn: aStream. aStream nextPutAll: ' oldValue='; nextPutAll: self oldValue printString; nextPut: $) ! ! !GLMPortEvent methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:58'! transmissionContext ^ transmissionContext! ! !GLMPortEvent methodsFor: 'accessing-convenience' stamp: ' 4/5/09 22:18'! value ^self port value! ! !GLMPresentation commentStamp: 'DamienCassou 7/19/2011 21:14' prior: 34268808! A GLMPresentation is the abstract class for the hierarchy of presentations. A presentation specifies how the pane (held in the pane instance variable) is going to be displayed. It typically reads at least the #entity port of a pane and populates at least the #selection port. updateActions holds a collection of GLMUpdateAction that are used to update the presentation via announcements. rawSelectionTransmissions holds a collection of transmission whose origins are this presentation's #rawSelection port. Destinations of this transmissions are on the pane. This collection always contains at least one transmission to the pane's #selection port. To transform the values travelling through this transmission use #send:. To add new transmissions, use #send:as:. Because Glamour has a prototype-based design it relies on copying the presentations before installing them in panes (via transmissions). The parentPrototype instance variable keeps track of the presentation from which the current one was copied. It raises: - GLMContextChanged to let the world know that something has changed in the containing pane. This is typically used by the renderer to update the rendering. - GLMPresentationUpdated to let the world know that the presentations wants to be updated because of reasons other than the pane context changed.! !GLMBrowser commentStamp: 'TudorGirba 2/4/2011 17:50' prior: 34270199! The Browser is one of the core components in Glamour. It contains panes and transmissions between their ports. These transformations can either be explicitely defined by the user (such as in the Tabulator) or implicitely defined (such as in the Finder). Browsers serve as composition managers. They determine when and under which conditions transmissions should be triggered and how they connect the ports of panes. In return, panes inform the browsers when event occur on their ports so that the browser can make an informed decission on what to do. A Browser is a Presentation which means that it can be nested into other browsers.! !GLMBrowser class methodsFor: 'constants' stamp: 'tg 3/31/2010 19:23'! defaultStatusbarPane ^ #'_statusbar'! ! !GLMBrowser class methodsFor: 'scripting' stamp: 'tg 4/1/2010 07:01'! withStatusbar ^ self new addStatusbar! ! !GLMBrowser methodsFor: 'accessing' stamp: 'tg 3/31/2010 21:55'! addPane: aPane aPane browser: self. self panes add: aPane. self hasStatusbar ifTrue: [ self addDefaultStatusbarTransmissionFrom: aPane ]. ^ aPane! ! !GLMBrowser methodsFor: 'accessing' stamp: 'TudorGirba 4/22/2012 21:56'! addTransmission: aTransmission aTransmission browser: self. ^ self transmissions addLast: aTransmission! ! !GLMBrowser methodsFor: 'events' stamp: 'AndreiChis 10/24/2012 13:48'! close self announce: GLMBrowserClosed new! ! !GLMBrowser methodsFor: 'scripting' stamp: 'jorge.ressia 6/2/2009 17:11'! context ^OrderedCollection new! ! !GLMBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! custom: aPresentation self subclassResponsibility! ! !GLMBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! defaultRenderer ^GLMRenderer subclasses first new! ! !GLMBrowser methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/30/2011 11:55'! initialExtent ^ initialExtent ifNil: [ initialExtent := RealEstateAgent standardWindowExtent]! ! !GLMBrowser methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/30/2011 11:56'! initialExtent: aPoint initialExtent := aPoint! ! !GLMBrowser methodsFor: 'initialize-release' stamp: 'TudorGirba 5/20/2012 23:40'! initialize super initialize. panes := OrderedCollection new. transmissions := OrderedCollection new. statusPane := nil. watcherPane := nil! ! !GLMBrowser methodsFor: 'scripting' stamp: 'tg 5/24/2009 19:15'! initializeScriptingDefaults "Initialize some default behavior if the user did not explcitly script it. Subclasses can use this to create a default startup transmission or show a default pane or something like that." ^self! ! !GLMBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! open ^self openWith: self defaultRenderer! ! !GLMBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! openOn: anObject ^self openOn: anObject with: self defaultRenderer! ! !GLMBrowser methodsFor: 'scripting' stamp: 'TudorGirba 7/15/2011 13:54'! openOn: anObject with: aRenderer self startOn: anObject. ^ self openWith: aRenderer! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/27/2013 16:27'! openTree | composer | composer := GLMCompositePresentation new. composer act: [:b | b update] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Update'. composer tabulator with: [:t | t column: #theOne. t transmit to: #theOne; andShow: [:a | a roassal updateOn: GLMTransmissionTriggered from: [ self announcer ]; painting: [:view :b | self viewTreeOn: view ] ]]. composer openOn: self! ! !GLMBrowser methodsFor: 'scripting' stamp: 'TudorGirba 7/15/2011 13:54'! openWith: aRenderer ^ aRenderer open: self! ! !GLMBrowser methodsFor: 'events' stamp: 'TudorGirba 5/20/2012 22:21'! outerPortEvent: aPortEvent super outerPortEvent: aPortEvent. aPortEvent hasChanged ifTrue: [ (self transmissions select: [:each | (each originatesAt: aPortEvent port) and: [ ( aPortEvent transmissionContext includesPort: each destination) not ]]) do: [:each | each transmitIn: aPortEvent transmissionContext copy ]]! ! !GLMBrowser methodsFor: 'accessing' stamp: 'tg 3/31/2010 19:45'! panes ^ panes ifNil: [ panes := OrderedCollection new ]! ! !GLMBrowser methodsFor: 'copying' stamp: 'TudorGirba 5/21/2012 00:32'! postCopy | newPane newPanes newPanesMapping newTransmission oldPane oldWatcherPane | super postCopy. "needed for setting the right panes for the new transmissions" newPanesMapping := Dictionary new. newPanes := OrderedCollection new. self panes do: [:each | newPane := each copy. newPane browser: self. newPanes addLast: newPane. newPanesMapping at: each put: newPane ]. oldPane := self pane. oldWatcherPane := self watcherPane. watcherPane := nil. pane := nil. newPanesMapping at: oldPane ifAbsentPut: [ self pane ]. newPanesMapping at: oldWatcherPane ifAbsentPut: [ self watcherPane ]. self flag: 'we should also copy the values of ports from pane and watcherPane'. transmissions := self transmissions collect: [ :each | newTransmission := each copy. newTransmission changePortsAccordingToPaneMapping: newPanesMapping fromOldBrowser: nil toNewBrowser: self. newTransmission ]. panes := newPanes! ! !GLMBrowser methodsFor: 'accessing' stamp: 'TudorGirba 1/18/2011 14:23'! removeAllPanes self panes do: [:each | each unregisterFromAllAnnouncements]. ^ self panes removeAll! ! !GLMBrowser methodsFor: 'accessing' stamp: 'tg 8/22/2010 21:33'! removeLastPane self panes last unregisterFromAllAnnouncements. ^ self panes removeLast! ! !GLMBrowser methodsFor: 'accessing' stamp: 'tg 1/31/2010 00:26'! removePane: aPane aPane unregisterFromAllAnnouncements. self panes remove: aPane! ! !GLMBrowser methodsFor: 'announcements' stamp: 'TudorGirba 7/10/2011 17:00'! resetAnnouncer super resetAnnouncer. self panes do: [:each | each resetAnnouncer ]! ! !GLMBrowser methodsFor: 'scripting-private' stamp: 'tg 10/25/2010 02:35'! resolveDestinationPort: aPortReference self flag: 'this is a temporary hack due to initializeScripting transmitting directly a port'. (aPortReference isKindOf: GLMPort) ifTrue: [ ^ aPortReference ]. ^self resolvePort: aPortReference asGlamourTargetIdentifier defaultPortName: #entity! ! !GLMBrowser methodsFor: 'scripting-private' stamp: 'tg 10/25/2010 02:21'! resolveOriginPort: aPortReference ^self resolvePort: aPortReference asGlamourOriginIdentifier defaultPortName: #selection! ! !GLMBrowser methodsFor: 'scripting-private' stamp: 'tg 10/25/2010 02:35'! resolvePort: aPortReference defaultPortName: aSymbol ^ aPortReference paneName = #outer ifTrue: [ (GLMPresentationBoundPort new) presentation: self; name: aPortReference portName; yourself] ifFalse: [ (self paneNamed: aPortReference paneName) port: aPortReference portName].! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'tg 5/18/2010 13:50'! screenshot: aFilenameString on: anObject after: aBlock | window | window := self openOn: anObject. aBlock glamourValue: self asGlamorousMultiValue. World doOneCycle. PNGReadWriter putForm: window imageForm onFileNamed: aFilenameString. ^ window! ! !GLMBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! startOn: anObject self initializeScriptingDefaults. self entity: anObject! ! !GLMBrowser methodsFor: 'accessing' stamp: 'tg 3/31/2010 19:33'! transmissions ^ transmissions! ! !GLMBrowser methodsFor: 'scripting' stamp: 'tg 1/18/2010 13:29'! transmit ^ self addTransmission: (GLMTransmission new browser: self; yourself)! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 13:31'! umlClassWithTitle: umlName view: view nodes: aNodes forEach: aOneArgForEachBlock self umlClassWithTitle: umlName view: view nodes: aNodes forEachInstanceVariable: [:e | e] methods: aOneArgForEachBlock! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 13:33'! umlClassWithTitle: umlName view: view nodes: aNodes forEachInstanceVariable: aOneArgForEachBlock1 methods: aOneArgForEachBlock2 view shape rectangle color: Color white. view extensibleSizeWithPaddingGap: 0. view nodes: aNodes forEach: [ :eachNode | view interaction nodraggable; forward: ROAbstractMouseDragging; forward: ROMouseClick. view interaction popupText. view shape centeredLabel text: umlName. view node: eachNode. view interaction nodraggable; forward: ROAbstractMouseDragging; forward: ROMouseClick. view shape rectangle. view nodes: (Array with: eachNode) forEach: aOneArgForEachBlock1. view interaction nodraggable; forward: ROAbstractMouseDragging; forward: ROMouseClick. view shape rectangle color: Color white. view nodes: (Array with: eachNode) forEach: aOneArgForEachBlock2. view verticalLineLayout gapSize: 0; on: ROLayoutBegin do: [ :event | | maxWidth | maxWidth := event elements maxValue: #width. event elements do: [ :eachElement | eachElement width: maxWidth ] ]; on: ROLayoutEnd do: [ :event | | strategy | strategy := ROFixedSizedParent new paddingGap: 0. event elements do: [ :eachElement | eachElement resizeStrategy: strategy ] ] ].! ! !GLMBrowser methodsFor: 'updating' stamp: 'TudorGirba 1/7/2011 07:25'! unregisterFromAllAnnouncements super unregisterFromAllAnnouncements. self panes do: [:each | each unregisterFromAllAnnouncements ]! ! !GLMBrowser methodsFor: 'updating' stamp: 'tg 8/24/2010 21:41'! update self panes do: [:each | each update ]. self announce: (GLMPresentationUpdated new presentation: self).! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 12:20'! viewAnnouncements | view | view := ROMondrianViewBuilder new. self viewAnnouncementsOn: view. ^ view open setLabel: 'Announcements'! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 12:46'! viewAnnouncementsOn: view view shape rectangle withoutBorder. view node: 'Glamour' forIt: [ self viewTreeOn: view ]. self umlClassWithTitle: #yourself view: view nodes: (Array with: 'Announced objects') forEach: [ :eachNode | view interaction nodraggable; forward: ROAbstractMouseDragging. view shape label text: [:p | (p class name removePrefix: 'GLM') removeSuffix: 'Renderer' ]. view nodes: (self pane withAllPanes flatCollect: [:each | each glmSubscriptions collect: [:eachSub | eachSub subscriber]]) asSet. view interaction nodraggable; forward: ROAbstractMouseDragging. view shape label text: [:p | (p class name removePrefix: 'GLM') removeSuffix: 'Renderer' ]. view nodes: (self pane withAllPresentations flatCollect: [:each | each glmSubscriptions collect: [:eachSub | eachSub subscriber]]) asIdentitySet. view verticalLineLayout ]. view shape line color: Color red twiceLighter; attachPoint: (ROHorizontalAttachPoint new). view edges: self pane withAllPanes from: #yourself toAll: [:each | each glmSubscriptions collect: [:eachSub | eachSub subscriber]]. view shape line color: Color red twiceLighter; attachPoint: (ROHorizontalAttachPoint new). view edges: self pane withAllPresentations from: #yourself toAll: [:each | each glmSubscriptions collect: [:eachSub | eachSub subscriber]]. view horizontalLineLayout horizontalGap: 50! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 13:38'! viewNestedOn: view self umlClassWithTitle: #name view: view nodes: self panes forEachInstanceVariable: [ :each | view interaction nodraggable; forward: ROAbstractMouseDragging. view shape label text: #name. view nodes: each ports. view verticalLineLayout gapSize: 2 ] methods: [ :each | each presentations presentations do: [:eachPresentation | eachPresentation viewNestedOn: view ]. view verticalLineLayout gapSize: 2 ]. view edges: self transmissions fromAll: #origins to: #destination! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 12:10'! viewSketch | view | view := ROMondrianViewBuilder new. self viewSketchOn: view. ^ view openWithStatusbar setLabel: 'Sketch'! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 12:18'! viewSketchOn: view | simpleName viewBrowser allTransmissions inTransmission| simpleName := [ :each | (each class name removePrefix: 'GLM') removeSuffix: 'Presentation' ]. allTransmissions := (self withAllPresentations select: [ :each | each isKindOf: GLMBrowser ]) flatCollect: #transmissions. inTransmission := [:port | allTransmissions anySatisfy: [:tr | (tr origins includes: port) or: [tr destination = port]]]. viewBrowser := [ :browser | self umlClassWithTitle: simpleName view: view nodes: (Array with: browser) forEach: [ :each | view interaction nodraggable; forward: ROAbstractMouseDragging. view nodes: browser panes forEach: [ :inPane | view interaction nodraggable; forward: ROAbstractMouseDragging. view nodes: (inPane ports select: inTransmission). view interaction nodraggable; forward: ROAbstractMouseDragging. view shape label text: simpleName. view nodes: inPane presentations presentations forEach: [ :inPresentation | (inPresentation isKindOf: GLMBrowser) ifTrue: [ viewBrowser value: inPresentation ] ] ]. ((browser isKindOf: GLMTabulator) and: [ browser cell isSplitIntoRows ]) ifTrue: [ view verticalLineLayout gapSize: 2 ] ] ]. viewBrowser value: self. view shape line color: Color blue. view edges: allTransmissions fromAll: #origins to: #destination! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/27/2013 16:27'! viewTree | view | view := ROMondrianViewBuilder new. self viewTreeOn: view. ^ view openWithStatusbar setLabel: 'Tree'! ! !GLMBrowser methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 12:07'! viewTreeOn: view | edges1 edges2 edges3 edges4 | self umlClassWithTitle: #name view: view nodes: self pane withAllPanes forEach: [ :each | view interaction nodraggable; forward: ROAbstractMouseDragging. view shape label text: #name. view nodes: each ports. view verticalLineLayout gapSize: 2 ]. view shape label text: [:p | (p class name removePrefix: 'GLM') removeSuffix: 'Presentation' ]. view nodes: self pane withAllPresentations. view shape orthoVerticalLine color: Color lightGray. edges1 := view edges: self pane withAllPanes from: #yourself to: [:each | each presentations ]. view shape orthoVerticalLine color: Color lightGray. edges2 := view edges: self pane withAllPanes from: #browser to: #yourself. view shape orthoVerticalLine color: Color lightGray. edges3 := view edges: (self pane withAllPresentations select: [:each | each isKindOf: GLMDynamicPresentation]) from: #yourself to: #cachedPresentation. view shape orthoVerticalLine color: Color lightGray. edges4 := view edges: (self pane withAllPresentations select: [:each | each isKindOf: GLMCompositePresentation]) from: #yourself toAll: #presentations. view treeLayout layered userDefinedEdges: (edges1, edges2, edges3, edges4). view shape line color: Color blue. view edges: ((self pane withAllPresentations select: [:each | each isKindOf: GLMBrowser]) flatCollect: [:each | each transmissions]) fromAll: #origins to: #destination. view shape line color: Color blue ! ! !GLMBrowser methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2012 23:40'! watcherPane ^ watcherPane ifNil: [watcherPane := GLMPane named: #'_watcher']! ! !GLMBrowser methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2012 23:18'! watcherPane: anObject watcherPane := anObject ! ! !GLMBrowser methodsFor: 'events' stamp: 'AndreiChis 10/31/2012 09:42'! windowIsClosing self announce: GLMBrowserClosing new! ! !GLMBrowser methodsFor: 'enumerating' stamp: 'TudorGirba 7/9/2011 20:03'! withAllPanesAndPresentationsDo: aBlock super withAllPanesAndPresentationsDo: aBlock. self panes do: [:each | each withAllPanesAndPresentationsDo: aBlock ]! ! !GLMExplicitBrowser commentStamp: 'TudorGirba 2/4/2011 17:50' prior: 34270909! A GLMExplicitBrowser is a browser that allows the user to explicitly define the panes and the flow of transmissions between them.! !GLMDashboard methodsFor: 'scripting' stamp: 'cyrilledelaunay 5/12/2011 16:08'! addPaneNamed: aString self addNewPaneNamed: aString! ! !GLMDashboard methodsFor: 'scripting' stamp: 'cyrilledelaunay 5/17/2011 10:47'! addPaneNamed: aSymbol extent: aPoint self addPaneNamed: aSymbol. self panesExtents at: aSymbol put: aPoint! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/29/2011 13:42'! defaultPaneExtent ^ defaultPaneExtent ifNil: [defaultPaneExtent := 300@150]! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/29/2011 13:46'! defaultPaneExtent: anObject "so that each renderer can make specific the way to compute the default extent" defaultPaneExtent := anObject! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/29/2011 13:39'! extentOfPaneNamed: aSymbol ^ self panesExtents at: aSymbol ifAbsent: [ "default extent for a pane" "#glamourOptimalExtent" self defaultPaneExtent ]! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/20/2011 11:40'! extentStrategy ^ extentStrategy ifNil: [extentStrategy := GLMFillWidthStrategy new].! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/20/2011 11:03'! extentStrategy: aGLMDashboardExtentStrategy extentStrategy := aGLMDashboardExtentStrategy.! ! !GLMDashboard methodsFor: 'scripting' stamp: 'cyrilledelaunay 5/20/2011 11:06'! fillWidthStrategy self extentStrategy: GLMFillWidthStrategy new ! ! !GLMDashboard methodsFor: 'scripting' stamp: 'TudorGirba 7/2/2011 22:53'! initializeScriptingDefaults super initializeScriptingDefaults. self transmissions detect: [ :each | each originatesAt: (self pane port: #entity) ] ifNone: [ self transmit to: (self panes first port: #entity); from: #outer port: #entity; andShow: [:a | a custom: GLMFlexiblePresentation new ] ]! ! !GLMDashboard methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/17/2011 10:46'! panesExtents ^ panesExtents ifNil: [panesExtents := Dictionary new]! ! !GLMDashboard methodsFor: 'rendering' stamp: 'cyrilledelaunay 6/7/2011 17:01'! renderGlamorouslyOn: aRenderer ^aRenderer renderDashboard: self! ! !GLMDashboard methodsFor: 'scripting' stamp: 'cyrilledelaunay 5/20/2011 11:06'! rigidStrategy self extentStrategy: GLMRigidStrategy new ! ! !GLMExplicitBrowser methodsFor: 'accessing' stamp: 'jorge.ressia 6/2/2009 21:48'! addNewPane ^self addNewPaneNamed: 'undefined'! ! !GLMExplicitBrowser methodsFor: 'accessing' stamp: 'tg 3/31/2010 22:49'! addNewPaneNamed: aString ^ self addPane: (GLMPane named: aString in: self)! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'tg 1/11/2010 20:39'! custom: aPresentation "this message sets a custom presentation to the current Transmission. it is to be used within the using: block. this message is particularly useful when you want to set a browser as a presentation" self lastTransmission addPresentation: aPresentation. ^ aPresentation! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'tg 1/11/2010 20:38'! from: anOriginPortReference "send this message after showOn: to specify an origin for the Transmission. you can cascade several from: to specify additional origins" self lastTransmission addActiveOrigin: (self resolveOriginPort: anOriginPortReference)! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'TudorGirba 12/2/2010 20:10'! fromOutside: aPortName ^ self fromOutsidePort: aPortName! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'TudorGirba 12/2/2010 20:10'! fromOutsidePort: aPortName ^ self from: #outer->aPortName! ! !GLMExplicitBrowser methodsFor: 'events' stamp: 'DamienCassou 7/3/2011 19:52'! innerPortEvent: aPortEvent | wantedTransmissions | aPortEvent hasChanged ifFalse: [ ^ self ]. wantedTransmissions := self transmissions select: [ :each | (each originatesAt: aPortEvent port) and: [ (aPortEvent transmissionContext includesPort: each destination) not ] ]. wantedTransmissions do: [ :each | each transmitIn: aPortEvent transmissionContext copy ]! ! !GLMExplicitBrowser methodsFor: 'accessing' stamp: 'tg 1/11/2010 20:37'! lastTransmission ^ self transmissions last! ! !GLMExplicitBrowser methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! paneNamed: aSymbol ^self panes detect: [:each | each name = aSymbol]! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'tg 1/11/2010 20:38'! passivelyFrom: anOriginPortReference "passivelyForm: is similar to from: only the origin will be a passive one. in other words, a change in the origin port will not initiate a Transmission" self lastTransmission addPassiveOrigin: (self resolveOriginPort: anOriginPortReference)! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'tg 1/14/2010 16:10'! sendTo: aDesinationPortReference from: anOriginPortReference "this message links two port references with a transmission that holds no presentation" self transmissions addLast: ((GLMTransmission new) addActiveOrigin: (self resolveOriginPort: anOriginPortReference); destination: (self resolveDestinationPort: aDesinationPortReference); yourself)! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'tg 1/14/2010 16:10'! sendTo: aDesinationPortReference from: anOriginPortReference with: aBlock "this message links two port references with a transmission that holds no presentation" self transmissions addLast: ((GLMTransmission new) addActiveOrigin: (self resolveOriginPort: anOriginPortReference); destination: (self resolveDestinationPort: aDesinationPortReference); transformation: aBlock; yourself)! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! sendTo: aDesinationPortReference fromOutside: anOriginPortName "this is a shortcut method for propagating inside an outer port name to an inner port reference" self sendTo: aDesinationPortReference from: #outer -> anOriginPortName! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! sendToOutside: aPortName from: anOriginPortReference "this is a shortcut method for exposing an inner port reference as an outer port name" self sendTo: #outer -> aPortName from: anOriginPortReference! ! !GLMExplicitBrowser methodsFor: 'scripting' stamp: 'DamienCassou 7/9/2011 20:19'! showOn: aDestinationPane "send this message when at the beginning of specifying a Transmission" self addTransmission: ( GLMTransmission new ensureReplacePresentationsStrategy; destination: (self resolveDestinationPort: aDestinationPane); yourself)! ! !GLMExplicitBrowser methodsFor: 'accessing' stamp: 'jorge.ressia 6/2/2009 23:25'! updateContextWith: aPane ! ! !GLMStacker commentStamp: '' prior: 34271091! A GLMStacker is an explicit browser that allows us to stack panes on top of each other and typically show them as tabs.! !GLMStacker methodsFor: 'scripting' stamp: 'tg 6/12/2010 14:21'! aPane: aBlockOrSymbol ^ self addNewPaneNamed: aBlockOrSymbol! ! !GLMStacker methodsFor: 'scripting' stamp: 'DamienCassou 7/25/2011 08:48'! panes: blocksOrSymbols ^ blocksOrSymbols do: [:each | self aPane: each]! ! !GLMStacker methodsFor: 'rendering' stamp: 'tg 6/12/2010 14:18'! renderGlamorouslyOn: aRenderer ^aRenderer renderStacker: self! ! !GLMTabulator commentStamp: '' prior: 34271265! A GLMTabulator is an explicit browser that allows us to place panes in columns and rows.! !GLMTabulator methodsFor: 'layout' stamp: ' 4/5/09 22:18'! addColumn: aBlockOrSymbol ^self cellOrRow addColumn: aBlockOrSymbol! ! !GLMTabulator methodsFor: 'layout' stamp: 'tg 10/22/2009 13:27'! addColumn: aBlockOrSymbol size: anInteger ^(self addColumn: aBlockOrSymbol) size: anInteger; span: 0! ! !GLMTabulator methodsFor: 'layout' stamp: ' 4/5/09 22:18'! addColumn: aBlockOrSymbol span: anInteger ^(self addColumn: aBlockOrSymbol) span: anInteger! ! !GLMTabulator methodsFor: 'layout' stamp: ' 4/5/09 22:18'! addRow: aBlockOrSymbol ^self cellOrColumn addRow: aBlockOrSymbol! ! !GLMTabulator methodsFor: 'layout' stamp: 'tg 10/22/2009 13:27'! addRow: aBlockOrSymbol size: anInteger ^(self addRow: aBlockOrSymbol) size: anInteger; span: 0! ! !GLMTabulator methodsFor: 'layout' stamp: ' 4/5/09 22:18'! addRow: aBlockOrSymbol span: anInteger ^(self addRow: aBlockOrSymbol) span: anInteger! ! !GLMTabulator methodsFor: 'layout' stamp: ' 4/5/09 22:18'! cell ^cell! ! !GLMTabulator methodsFor: 'private' stamp: ' 4/5/09 22:18'! cellOrColumn ^cell ifNil: [cell := GLMCustomColumn new browser: self]! ! !GLMTabulator methodsFor: 'private' stamp: ' 4/5/09 22:18'! cellOrRow ^cell ifNil: [cell := GLMCustomRow new browser: self]! ! !GLMTabulator methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! column: aBlockOrSymbol ^self addColumn: aBlockOrSymbol! ! !GLMTabulator methodsFor: 'scripting' stamp: 'tg 10/22/2009 13:27'! column: aBlockOrSymbol size: anInteger ^self addColumn: aBlockOrSymbol size: anInteger! ! !GLMTabulator methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! column: aBlockOrSymbol span: anInteger ^self addColumn: aBlockOrSymbol span: anInteger! ! !GLMTabulator methodsFor: 'scripting' stamp: 'TudorGirba 7/2/2011 19:03'! initializeScriptingDefaults super initializeScriptingDefaults. self cell isNil ifTrue: [ self addColumn: #pane ]. self transmissions detect: [ :each | each originatesAt: (self pane port: #entity) ] ifNone: [ self transmit to: (self panes first port: #entity); from: #outer port: #entity; andShow: [ :a | a custom: GLMFlexiblePresentation new ] ]! ! !GLMTabulator methodsFor: 'rendering' stamp: 'tg 1/10/2010 16:20'! renderGlamorouslyOn: aRenderer ^aRenderer renderTabulator: self! ! !GLMTabulator methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! row: aBlockOrSymbol ^self addRow: aBlockOrSymbol! ! !GLMTabulator methodsFor: 'scripting' stamp: 'tg 10/22/2009 13:26'! row: aBlockOrSymbol size: anInteger ^self addRow: aBlockOrSymbol size: anInteger! ! !GLMTabulator methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! row: aBlockOrSymbol span: anInteger ^self addRow: aBlockOrSymbol span: anInteger! ! !GLMImplicitBrowser commentStamp: 'TudorGirba 3/5/2011 21:22' prior: 34271427! A GLMImplicitBrowser is an abstract implementation of a browser that defines an implicit flow of transmissions. When using implicit browsers, the developer does not have access to the internal transmissions.! !GLMAccumulator commentStamp: 'TudorGirba 4/21/2011 21:20' prior: 34271706! An GLMAccumulator is an implicit type of browser that has the following behavior: - each input entity has associated a pane without any relationship with the other panes - based on the input entity if there already exists a pane associated, it is selected via GLMPaneSelected - if there isnt a pane, a new pane is created - based on entityToSelect, the associated pane is searched and potentially selected - when a pane is selected in the user interface, the activeEntity is populated with the entity behind the selected pane Input ports: - entity - entityToSelect Output ports: - activeEntity! !GLMAccumulator methodsFor: 'accessing ports' stamp: 'tg 2/2/2010 22:03'! activeEntity ^ (self pane port: #activeEntity) value! ! !GLMAccumulator methodsFor: 'accessing ports' stamp: 'tg 2/2/2010 21:31'! activeEntity: anObject ^ (self pane port: #activeEntity) value: anObject ! ! !GLMAccumulator methodsFor: 'private' stamp: 'AndreiChis 5/30/2013 21:49'! addPaneFrom: aPort aPort value isNil ifTrue: [ ^ self ]. (self tryToSelectPaneFrom: aPort) ifTrue: [ ^ self ]. self panes addLast: (GLMPane named: (self panes size + 1) asString in: self). self newTransmission addActiveOrigin: aPort; destination: (self panes last port: #entity); transmit. self announce: (GLMPaneAdded pane: self panes last atPosition: self panes size inBrowser: self)! ! !GLMAccumulator methodsFor: 'accessing ports' stamp: 'tg 2/2/2010 22:00'! entityToSelect ^ (self pane port: #entityToSelect) value! ! !GLMAccumulator methodsFor: 'accessing ports' stamp: 'tg 1/19/2010 21:24'! entityToSelect: anObject ^ (self pane port: #entityToSelect) value: anObject ! ! !GLMAccumulator methodsFor: 'events' stamp: 'tg 1/18/2010 07:47'! innerPortEvent: aPortEvent aPortEvent portName = #entity ifFalse: [ "We don't want to resend the transmission, but use a new SimpleTransmission." (self pane port: aPortEvent portName) value: aPortEvent value]! ! !GLMAccumulator methodsFor: 'events' stamp: 'cyrilledelaunay 3/29/2011 10:04'! outerPortEvent: aPortEvent super outerPortEvent: aPortEvent. aPortEvent port name = #entityToSelect ifTrue: [ self tryToSelectPaneFrom: aPortEvent port ]. aPortEvent port name = #entity ifTrue: [ self addPaneFrom: aPortEvent port ]! ! !GLMAccumulator methodsFor: 'private' stamp: 'tg 1/31/2010 01:13'! removePaneIndex: i | paneRemoved | paneRemoved := self panes removeAt: i. paneRemoved unregisterFromAllAnnouncements. self announce: (GLMPaneRemoved pane: paneRemoved fromBrowser: self )! ! !GLMAccumulator methodsFor: 'rendering' stamp: 'tg 1/18/2010 08:36'! renderGlamorouslyOn: aRenderer ^ aRenderer renderAccumulator: self! ! !GLMAccumulator methodsFor: 'private' stamp: 'tg 1/19/2010 21:50'! tryToSelectPaneFrom: aPort self panes withIndexDo: [:each :i | (each port: #entity) value = aPort value ifTrue: [ self announce: (GLMPaneSelected pane: each atPosition: i inBrowser: self). ^ true ] ]. ^ false! ! !GLMExpander commentStamp: 'DamienCassou 7/26/2011 19:10' prior: 34272371! GLMExpander aims to implement a Hopscotch-like browser. This is similar to a tree where each tree node content is itself a presentation.! !GLMExpander methodsFor: 'events' stamp: 'AndreiChis 5/30/2013 21:50'! addPaneFrom: aPort self panes addLast: (GLMPane in: self). self newTransmission addActiveOrigin: aPort; destination: (self panes last port: #entity); transmit. self announce: (GLMPaneAdded pane: self panes last atPosition: self panes size inBrowser: self)! ! !GLMExpander methodsFor: 'events' stamp: 'TudorGirba 1/9/2011 01:46'! innerPortEvent: aPortEvent aPortEvent portName = #entity ifFalse: [ "We resend the value to the outer pane" "We don't want to resend the transmission, but use a new SimpleTransmission." (self pane port: aPortEvent portName) value: aPortEvent value]! ! !GLMExpander methodsFor: 'events' stamp: 'TudorGirba 1/9/2011 01:34'! outerPortEvent: aPortEvent aPortEvent port name = #entity ifFalse: [^self]. panes := nil. self matches ifTrue: [ "We only want to execute the transformation if the visibility condition matches" (self transformation glamourValue: aPortEvent port value) do: [:each | self addPaneFrom: (GLMSimplePort new value: each) ] ]! ! !GLMExpander methodsFor: 'rendering' stamp: 'TudorGirba 1/2/2011 18:59'! renderGlamorouslyOn: aRenderer ^ aRenderer renderExpander: self! ! !GLMFinder commentStamp: 'TudorGirba 7/9/2011 18:16' prior: 34272572! A GLMFinder models a browsers that behaves like the Mac Finder: whenever the selection port is set on one pane, a new one is created to the right with the selection as entity. The Finder opens the first pane on the entity. The Finder communicates with the Renderer Input ports: - entity: this is passed to the first pane Output ports: - selection: this port is populated with the value from the last selection port from one of the panes! !GLMFinder methodsFor: 'private' stamp: 'AndreiChis 5/29/2013 13:53'! addPaneFromInner: aPort "This method adds a new pane at the end of the finder. Data comes from a port that is in a pane inside the current browser." | newPane lastActive | "the lastActivePresentation is needed for knowing what presentation to show by default" lastActive := self panes isEmpty ifTrue: [nil] ifFalse: [ self lastActivePresentation ]. newPane := GLMPane named: (self panes size + 1) asString in: self. newPane lastActivePresentation: lastActive. self panes addLast: newPane. self newTransmission addActiveOrigin: aPort; destination: (newPane port: #entity); " presentations: (self presentations copy); " transmit. "This code was supposed to offer custom transmissions" " realTransmissions := self transmissions collect: [:oldTransmission | newTransmission := GLMTransmission new ensureReplacePresentationsStrategy. oldTransmission activeOrigins do: [:eachPort | newTransmission addActiveOrigin: (aPort pane port: eachPort name)]. oldTransmission passiveOrigins do: [:eachPort | newTransmission addPassiveOrigin: (aPort pane port: eachPort name)]. newTransmission destination: (newPane port: #entity); addPresentations: (self presentations collect: #copy); addPresentations: (oldTransmission presentations collect: #copy)] . [realTransmissions isEmpty] assert. (realTransmissions select: [:each | each originatesAt: aPort]) do: [:each | each transmit]. "! ! !GLMFinder methodsFor: 'private' stamp: 'AndreiChis 5/29/2013 13:54'! addPaneFromOuter: aPort "This method adds a new pane at the end of the finder." |newPane | newPane := self panes addLast: (GLMPane named: (self panes size + 1) asString in: self). self newFirstTransmission addActiveOrigin: aPort; destination: (newPane port: #entity); transmit! ! !GLMFinder methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 13:50'! firstTransmission ^ firstTransmission ifNil: [ firstTransmission := GLMTransmission new ensureReplacePresentationsStrategy ]! ! !GLMFinder methodsFor: 'scripting' stamp: 'TudorGirba 1/26/2011 12:42'! fixedSizePanes ^ fixedSizePanes ifNil: [fixedSizePanes := 2]! ! !GLMFinder methodsFor: 'scripting' stamp: 'TudorGirba 1/26/2011 12:33'! fixedSizePanes: anInteger self hasFixedSizePanes: true. fixedSizePanes := anInteger! ! !GLMFinder methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 02:46'! fromPrevious: aPortSymbol self flag: 'needs revisiting. it does not work anymore'. self scriptTransmission addActiveOrigin: (GLMPort new name: aPortSymbol)! ! !GLMFinder methodsFor: 'accessing' stamp: 'TudorGirba 1/26/2011 10:59'! hasFixedSizePanes ^ hasFixedSizePanes ifNil: [hasFixedSizePanes := true]! ! !GLMFinder methodsFor: 'accessing' stamp: 'TudorGirba 1/26/2011 10:59'! hasFixedSizePanes: aBoolean hasFixedSizePanes := aBoolean! ! !GLMFinder methodsFor: 'events' stamp: 'TudorGirba 12/5/2011 13:49'! innerPortEvent: aPortEvent aPortEvent portName = #entity ifFalse: [ "We don't want to resend the transmission, but use a new SimpleTransmission." (self pane port: aPortEvent portName) value: aPortEvent value]. aPortEvent port name = #selection ifTrue: [ | index toReplace | index := self panes reversed indexOf: aPortEvent pane. (self panes reversed first: index - 2) do: [ :each | self removeLastPane. self announce: (GLMPaneRemoved pane: each fromBrowser: self) ]. index <= 1 ifTrue: [ self addPaneFromInner: aPortEvent port. self announce: (GLMPaneAdded pane: self panes last atPosition: self panes size inBrowser: self) ] ifFalse: [ toReplace := self removeLastPane. self lastActivePresentation: toReplace lastActivePresentation. self addPaneFromInner: aPortEvent port. self announce: (GLMPaneReplaced oldPane: toReplace newPane: self panes last fromBrowser: self ) ] ]! ! !GLMFinder methodsFor: 'private' stamp: 'TudorGirba 12/5/2011 13:50'! lastActivePresentation ^ lastActivePresentation ifNil: [ self panes last lastActivePresentation ]! ! !GLMFinder methodsFor: 'private' stamp: 'TudorGirba 12/5/2011 13:50'! lastActivePresentation: aPresentation lastActivePresentation := aPresentation! ! !GLMFinder methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 13:55'! newFirstTransmission ^ firstTransmission ifNil: [ self newTransmission ] ifNotNil: [ self firstTransmission copy ]! ! !GLMFinder methodsFor: 'events' stamp: 'TudorGirba 10/30/2012 20:37'! outerPortEvent: aPortEvent | toReplace | super outerPortEvent: aPortEvent. aPortEvent port name = #entity ifFalse: [^self]. self panes isEmpty ifFalse: [ toReplace := self panes first. panes := nil. self addPaneFromOuter: aPortEvent port. self announce: (GLMPaneReplaced oldPane: toReplace newPane: self panes first fromBrowser: self ) ] ifTrue: [ self addPaneFromOuter: aPortEvent port. self announce: (GLMPaneAdded pane: self panes last atPosition: self panes size inBrowser: self)]! ! !GLMFinder methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 02:46'! passivelyFromPrevious: aPortSymbol self flag: 'needs revisiting. it does not work anymore'. self scriptTransmission addPassiveOrigin: (GLMPort new name: aPortSymbol)! ! !GLMFinder methodsFor: 'rendering' stamp: 'TudorGirba 12/5/2011 12:15'! renderGlamorouslyOn: aRenderer ^ aRenderer renderFinder: self! ! !GLMFinder methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 13:51'! showFirst: aBlock ^ self firstTransmission transmissionStrategy presentationsFactory: aBlock ! ! !GLMFinder methodsFor: 'scripting' stamp: 'TudorGirba 1/26/2011 11:04'! variableSizePanes self hasFixedSizePanes: false! ! !GLMImplicitBrowser methodsFor: 'accessing' stamp: 'AndreiChis 5/30/2013 17:21'! addPresentation: aPresentation self transmission transmissionStrategy addPresentation: aPresentation ! ! !GLMImplicitBrowser methodsFor: 'accessing' stamp: 'AndreiChis 5/29/2013 13:41'! newTransmission ^ self transmission copy! ! !GLMImplicitBrowser methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 13:41'! show: aBlock self transmission transmissionStrategy presentationsFactory: aBlock! ! !GLMImplicitBrowser methodsFor: 'accessing' stamp: 'AndreiChis 5/29/2013 13:41'! transmission ^ transmission ifNil: [ transmission := GLMTransmission new ensureReplacePresentationsStrategy. transmission ]! ! !GLMValidator methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/23/2011 13:04'! addButtonAction: aGLMGenericAction self buttonActions addLast: aGLMGenericAction ! ! !GLMValidator methodsFor: 'private' stamp: 'AndreiChis 5/30/2013 21:51'! addPaneFrom: aPort self panes isEmpty ifTrue: [ self panes addLast: (GLMPane in: self). self newTransmission addActiveOrigin: aPort; destination: (self panes last port: #entity); transmit ] ! ! !GLMValidator methodsFor: 'private' stamp: 'AndreiChis 5/29/2013 13:39'! addPaneFromInner: aPort | newTransmission realTransmissions lastActivePresentation | "the lastActivePresentation is needed for knowing what presentation to show by default" self panes isEmpty ifFalse: [lastActivePresentation := self panes last lastActivePresentation ]. self panes addLast: ( (GLMPane in: self) lastActivePresentation: lastActivePresentation; yourself). self newTransmission addActiveOrigin: aPort; destination: (self panes last port: #entity); presentations: (self presentations copy); transmit. realTransmissions := self transmissions collect: [:each | newTransmission := GLMTransmission new ensureReplacePresentationsStrategy. each activeOrigins do: [:eachPort | newTransmission addActiveOrigin: (aPort pane port: eachPort name)]. each passiveOrigins do: [:eachPort | newTransmission addPassiveOrigin: (aPort pane port: eachPort name)]. newTransmission destination: (self panes last port: #entity); addPresentations: (self presentations collect: #copy); addPresentations: (each presentations collect: #copy)] . (realTransmissions select: [:each | each originatesAt: aPort]) do: [:each | each transmit]. ! ! !GLMValidator methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/23/2011 13:00'! buttonActions ^ buttonActions! ! !GLMValidator methodsFor: 'events' stamp: 'DiegoLont 9/11/2013 10:05'! explicitlyInnerPortNamed: aPortName aPortName = #entity ifFalse: [ self panes first ports do: [:each | (self pane port: each name) value: each value] ]! ! !GLMValidator methodsFor: 'initialize-release' stamp: 'cyrilledelaunay 3/23/2011 13:20'! initialize super initialize. buttonActions := OrderedCollection new! ! !GLMValidator methodsFor: 'events' stamp: 'cyrilledelaunay 3/31/2011 13:57'! innerPortEvent: aPortEvent ! ! !GLMValidator methodsFor: 'announcements' stamp: 'cyrilledelaunay 5/5/2011 12:01'! on: anAnnouncementClass send: aSelector self specificAnnouncementActions at: anAnnouncementClass put: aSelector ! ! !GLMValidator methodsFor: 'events' stamp: 'cyrilledelaunay 3/30/2011 10:35'! outerPortEvent: aPortEvent super outerPortEvent: aPortEvent. aPortEvent port name = #entityToSelect ifTrue: [ self tryToSelectPaneFrom: aPortEvent port ]. aPortEvent port name = #entity ifTrue: [ self addPaneFrom: aPortEvent port ]! ! !GLMValidator methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:44'! renderGlamorouslyOn: aRenderer ^ aRenderer renderValidator: self! ! !GLMValidator methodsFor: 'announcements' stamp: 'cyrilledelaunay 5/5/2011 12:01'! setSpecificAnnouncementActionsTo: aRenderer self specificAnnouncementActions keysAndValuesDo: [:anAnnouncementClass :aSymbol | self on: anAnnouncementClass send: aSymbol to: aRenderer. ]! ! !GLMValidator methodsFor: 'announcements' stamp: 'cyrilledelaunay 5/5/2011 12:00'! specificAnnouncementActions ^ specificAnnouncementActions ifNil: [specificAnnouncementActions := Dictionary new]! ! !GLMValidator methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 15:33'! validator: aString act: aBlock "will populate all ports by default at the end" self addButtonAction: ((GLMGenericAction new) action: [:tmpBrowser | tmpBrowser panes first ports do: [:aPort | tmpBrowser explicitlyInnerPortNamed: aPort name ]. aBlock value: tmpBrowser. ]; title: aString; yourself). ! ! !GLMValidator methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 15:33'! validator: aString act: aBlock populatePorts: aCollectionOfPorts self addButtonAction: ((GLMGenericAction new) action: [:tmpBrowser | aCollectionOfPorts do: [:aSymbol | tmpBrowser explicitlyInnerPortNamed: aSymbol. ]. aBlock value: tmpBrowser. ]; title: aString; yourself). ! ! !GLMValidator methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/31/2011 13:56'! validator: aString populatePorts: aCollectionOfPorts self addButtonAction: ((GLMGenericAction new) action: [:tmpBrowser | aCollectionOfPorts do: [:aSymbol | tmpBrowser explicitlyInnerPortNamed: aSymbol. ] ]; title: aString; yourself). ! ! !GLMWizard class methodsFor: 'examples' stamp: 'cyrilledelaunay 4/4/2011 14:11'! genericStepWithGenericSizeExample "self genericStepWithGenericSizeExample" | wizard | wizard := GLMWizard new. (wizard genericStep: #step) show: [:a | a list display: [:aNumber | 1 to: aNumber] ] ; name: 'Wizard pane'; size: [:aNumber | aNumber]. wizard openOn: 4. ! ! !GLMWizard class methodsFor: 'examples' stamp: 'cyrilledelaunay 4/4/2011 13:59'! linkedStepsExample "self linkedStepsExample" | wizard | wizard := GLMWizard new. (wizard step: #step1) show: [:a | a list display: [:aList | aList ]. ]; name: 'first pane' . (wizard step: #step2) from: #step1; show: [:a | a list display: [:aNumber | 1 to: aNumber ] ]; name: 'second pane'. wizard openOn: (1 to: 100). ! ! !GLMWizard class methodsFor: 'examples' stamp: 'cyrilledelaunay 4/4/2011 13:52'! simpleExample "self simpleExample" | wizard | wizard := GLMWizard new. (wizard genericStep: #step) show: [:a | a list display: [:list | list] ] ; name: 'Wizard pane'; size: 2. wizard openOn: (1 to: 100). ! ! !GLMWizard methodsFor: 'private' stamp: 'AndreiChis 5/29/2013 13:39'! addPaneFrom: aPort self panes addLast: self computePane. self newTransmission addActiveOrigin: aPort; destination: (self panes last port: #entity); presentations: (self presentations copy); transmit! ! !GLMWizard methodsFor: 'testing' stamp: 'cyrilledelaunay 4/4/2011 13:33'! atBeginning ^ self currentIndex = 1 and: [ self stepToUse atBeginning ]! ! !GLMWizard methodsFor: 'testing' stamp: 'cyrilledelaunay 4/4/2011 13:32'! atEnd ^ self currentIndex = self steps size and: [ self stepToUse atEnd ]! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 4/1/2011 14:04'! backSign ^ '<< Back'! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 14:24'! cancelButtonAction self externalCancelButtonAction value: self entity. self announce: (GLMBrowserClosed new) ! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 3/31/2011 15:46'! computeFirstPaneValidator |tmpValidator| tmpValidator := self computePaneValidator. self setFirstPaneButtonsTo: tmpValidator. ^ tmpValidator ! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 3/31/2011 15:46'! computeLastPaneValidator |tmpValidator| tmpValidator := self computePaneValidator. self setLastPaneButtonsTo: tmpValidator. ^ tmpValidator ! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 3/31/2011 15:47'! computeMiddlePaneValidator |tmpValidator| tmpValidator := self computePaneValidator. self setMiddlePaneButtonsTo: tmpValidator. ^ tmpValidator ! ! !GLMWizard methodsFor: 'building pane' stamp: 'cyrilledelaunay 4/4/2011 14:35'! computePane self hasUniquePane ifTrue: [^ self computePaneWith: self computeSinglePaneValidator]. self atBeginning ifTrue: [^ self computePaneWith: self computeFirstPaneValidator]. self atEnd ifTrue: [^ self computePaneWith: self computeLastPaneValidator]. ^( self computePaneWith: self computeMiddlePaneValidator). ! ! !GLMWizard methodsFor: 'building internal' stamp: 'AndreiChis 5/30/2013 22:09'! computePaneValidator |tmpPresentation tmpValidator| tmpPresentation := (self stepToUse presentationBlock glamourValue: self transmission transmissionStrategy presentations). tmpValidator := GLMValidator new. tmpValidator show: [:a | a custom: tmpPresentation]. "tmpValidator startOn: self entity." ^ tmpValidator ! ! !GLMWizard methodsFor: 'building pane' stamp: 'cyrilledelaunay 5/25/2011 10:57'! computePaneWith: aValidator | tmpPane | tmpPane := GLMPane in: self. tmpPane addPresentation: aValidator. (tmpPane port: #entity) value: self stepToUse input. self updateBrowserTitle. ^ tmpPane! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 3/31/2011 17:12'! computeSinglePaneValidator |tmpValidator| tmpValidator := self computePaneValidator. self setSinglePaneButtonsTo: tmpValidator. ^ tmpValidator ! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 16:15'! currentIndex ^ currentIndex ifNil: [currentIndex := 1]! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/31/2011 14:56'! currentIndex: anInteger currentIndex := anInteger! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 16:01'! currentStep ^ self steps at: self currentIndex! ! !GLMWizard methodsFor: 'accessing - scripting' stamp: 'cyrilledelaunay 4/4/2011 14:21'! defaultStepName ^'default_step_name'! ! !GLMWizard methodsFor: 'accessing ports' stamp: 'cyrilledelaunay 4/4/2011 15:47'! entity: anObject super entity: anObject. self updateWhenNext! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:56'! externalCancelButtonAction ^ externalCancelButtonAction ifNil: [externalCancelButtonAction := [:input | ]]! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:41'! externalCancelButtonAction: aBlock externalCancelButtonAction := aBlock! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:55'! externalNextButtonAction ^ externalNextButtonAction ifNil: [externalNextButtonAction := [:input | ]]! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:42'! externalNextButtonAction: aBlock externalNextButtonAction := aBlock ! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:55'! externalPreviousButtonAction ^ externalPreviousButtonAction ifNil: [externalPreviousButtonAction := [:input | ]]! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:43'! externalPreviousButtonAction: aBlock externalPreviousButtonAction := aBlock! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:54'! externalTerminateButtonAction ^ externalTerminateButtonAction ifNil: [externalTerminateButtonAction := [:input | ]]! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:58'! externalTerminateButtonAction: aBlock externalTerminateButtonAction := aBlock! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 3/31/2011 16:17'! forwardSign ^ 'Next >>'! ! !GLMWizard methodsFor: 'accessing - scripting' stamp: 'cyrilledelaunay 4/4/2011 14:23'! genericStep |tmpSymbol| tmpSymbol := (self defaultStepName, self steps size asString) asSymbol. self steps add: tmpSymbol. ^ self stepsDictionary at: tmpSymbol put: GLMWizardGenericStep new.! ! !GLMWizard methodsFor: 'accessing - scripting' stamp: 'cyrilledelaunay 4/4/2011 13:15'! genericStep: aSymbol self steps add: (aSymbol). ^ self stepsDictionary at: aSymbol put: GLMWizardGenericStep new.! ! !GLMWizard methodsFor: 'testing' stamp: 'cyrilledelaunay 4/4/2011 13:49'! hasUniquePane ^ self steps size = 1 and: [self stepToUse size = 1]! ! !GLMWizard methodsFor: 'initialize-release' stamp: 'cyrilledelaunay 4/1/2011 15:41'! initialize super initialize. scriptTransmission := GLMTransmission new.! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 5/24/2011 17:09'! nextButtonAction self externalNextButtonAction value: self entity. self updateWhenNext. ! ! !GLMWizard methodsFor: 'building pane' stamp: 'DiegoLont 9/11/2013 13:46'! notifyAndAddNewPane: aGLMPane (self stepsAndPanes at: self currentStep ifAbsentPut: [OrderedCollection new]) addLast: aGLMPane. self announce: (GLMPaneAdded new pane: aGLMPane; browser: self; yourself ) ! ! !GLMWizard methodsFor: 'building pane' stamp: 'cyrilledelaunay 4/4/2011 16:47'! notifyAndRemoveCurrentPane |oldPane tmpPanes| tmpPanes := self stepsAndPanes at: self currentStep ifAbsentPut: [OrderedCollection new]. oldPane := tmpPanes last. tmpPanes removeLast. self announce: (GLMPaneRemoved new pane: oldPane; browser: self; yourself ) ! ! !GLMWizard methodsFor: 'building pane' stamp: 'cyrilledelaunay 4/4/2011 16:22'! notifyAndSetAsCurrentPane: aGLMPane |oldPane tmpPanes| tmpPanes := self stepsAndPanes at: self currentStep ifAbsentPut: [OrderedCollection new]. tmpPanes removeLast. tmpPanes addLast: aGLMPane. "self panes addLast: aGLMPane. " self announce: (GLMPaneReplaced oldPane: oldPane newPane: tmpPanes last fromBrowser: self ) ! ! !GLMWizard methodsFor: 'announcements' stamp: 'cyrilledelaunay 4/1/2011 10:37'! on: anAnnouncementClass send: aSelector self specificAnnouncementActions at: anAnnouncementClass put: aSelector ! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:57'! onCancelDo: aBlock self externalCancelButtonAction: aBlock! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:58'! onNextDo: aBlock self externalNextButtonAction: aBlock! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:58'! onPreviousDo: aBlock self externalPreviousButtonAction: aBlock! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 13:58'! onTerminateDo: aBlock self externalTerminateButtonAction: aBlock! ! !GLMWizard methodsFor: 'events' stamp: 'cyrilledelaunay 4/12/2011 12:08'! populateInputOfStep: aGLMWiizardStep self stepToUse previousStep isEmpty ifTrue: [ self stepToUse input: (self pane port: #entity) value. ] ifFalse: [ (self stepToUse previousStep size = 1) ifTrue: [ self stepToUse input: ((self stepsAndPanes at: self stepToUse previousStep anyOne) last port: #selection) value. ] ifFalse: [ |tmpInputs| tmpInputs := self stepToUse previousStep collect: [:aSymbol | ((self stepsAndPanes at: aSymbol) last port: #selection) value ]. self stepToUse input: tmpInputs ]. ]. ! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 14:01'! previousButtonAction self externalPreviousButtonAction value: self entity. self updateWhenPrevious ! ! !GLMWizard methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:45'! renderGlamorouslyOn: aRenderer ^ aRenderer renderWizard: self! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 4/1/2011 14:04'! setFirstPaneButtonsTo: aValidator aValidator validator: 'Cancel' act: [:input | self cancelButtonAction ] . aValidator validator: self forwardSign act: [:input | self nextButtonAction ] populatePorts: #(#selection).! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 5/24/2011 14:31'! setLastPaneButtonsTo: aValidator aValidator validator: 'Cancel' act: [:input | self cancelButtonAction ]. aValidator validator: self backSign act: [:input | self previousButtonAction ]. aValidator validator: 'Finish' act: [:input | self terminateButtonAction ].! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 4/1/2011 14:02'! setMiddlePaneButtonsTo: aValidator aValidator validator: 'Cancel' act: [:input | self cancelButtonAction ]. aValidator validator: self backSign act: [:input | self previousButtonAction ]. aValidator validator: self forwardSign act: [:input | self nextButtonAction ]. ! ! !GLMWizard methodsFor: 'building internal' stamp: 'cyrilledelaunay 5/24/2011 14:31'! setSinglePaneButtonsTo: aValidator aValidator validator: 'Cancel' act: [:input | self cancelButtonAction ]. aValidator validator: 'Finish' act: [:input | self terminateButtonAction ]. ! ! !GLMWizard methodsFor: 'announcements' stamp: 'cyrilledelaunay 4/1/2011 10:37'! setSpecificAnnouncementActionsTo: aRenderer self specificAnnouncementActions keysAndValuesDo: [:anAnnouncementClass :aSymbol | self on: anAnnouncementClass send: aSymbol to: aRenderer. ]! ! !GLMWizard methodsFor: 'announcements' stamp: 'cyrilledelaunay 4/1/2011 10:36'! specificAnnouncementActions ^ specificAnnouncementActions ifNil: [specificAnnouncementActions := Dictionary new]! ! !GLMWizard methodsFor: 'accessing - scripting' stamp: 'cyrilledelaunay 4/4/2011 14:22'! step |tmpSymbol| tmpSymbol := (self defaultStepName, self steps size asString) asSymbol. self steps add: tmpSymbol. ^ self stepsDictionary at: tmpSymbol put: GLMWizardStep new.! ! !GLMWizard methodsFor: 'accessing - scripting' stamp: 'cyrilledelaunay 4/4/2011 13:14'! step: aSymbol self steps add: (aSymbol). ^ self stepsDictionary at: aSymbol put: GLMWizardStep new.! ! !GLMWizard methodsFor: 'private' stamp: 'cyrilledelaunay 4/4/2011 13:48'! stepToUse ^ self stepsDictionary at: (self steps at: self currentIndex) ! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/1/2011 12:37'! steps ^ steps ifNil: [steps := OrderedCollection new]! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 14:59'! stepsAndPanes ^ stepsAndPanes ifNil: [stepsAndPanes := Dictionary new]! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 14:58'! stepsAndPanesDictionary ^ stepsDictionary ifNil: [stepsDictionary := Dictionary new]! ! !GLMWizard methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:16'! stepsDictionary ^ stepsDictionary ifNil: [stepsDictionary := Dictionary new]! ! !GLMWizard methodsFor: 'accessing - buttons actions ' stamp: 'cyrilledelaunay 4/1/2011 14:24'! terminateButtonAction self externalTerminateButtonAction value: self entity. self announce: (GLMBrowserClosed new) ! ! !GLMWizard methodsFor: 'events' stamp: 'cyrilledelaunay 5/25/2011 10:57'! updateBrowserTitle self title: self stepToUse name. self update! ! !GLMWizard methodsFor: 'events' stamp: 'cyrilledelaunay 4/1/2011 11:52'! updatePane |tmpPane| self notifyAndSetAsCurrentPane: self computePane.! ! !GLMWizard methodsFor: 'events' stamp: 'cyrilledelaunay 5/25/2011 10:58'! updateWhenNext |tmpPane| self populateInputOfStep: self stepToUse. self stepToUse incrementNumberOfDisplay. self stepToUse overEnd ifTrue: [ self currentIndex: self currentIndex + 1. self populateInputOfStep: self stepToUse. ]. tmpPane := self computePane. self notifyAndAddNewPane: self computePane. ! ! !GLMWizard methodsFor: 'events' stamp: 'cyrilledelaunay 5/25/2011 10:58'! updateWhenPrevious |tmpPane| self notifyAndRemoveCurrentPane. self stepToUse decrementNumberOfDisplay. self stepToUse overBeginning ifTrue: [ self currentIndex: self currentIndex - 1]. self stepToUse input: self entity. self notifyAndSetAsCurrentPane: (self stepsAndPanes at: self currentStep) last . self updateBrowserTitle.! ! !GLMWizard methodsFor: 'private' stamp: 'cyrilledelaunay 3/31/2011 16:08'! valueOf: anObject ^ anObject moValue: (self pane port: #entity) value! ! !GLMWrapper commentStamp: '' prior: 34273065! The GLMWrapper is a browser that has only one pane and that is typically used as a placeholder. The pane takes only entity as input.! !GLMWrapper methodsFor: 'initialize-release' stamp: 'TudorGirba 5/19/2012 09:18'! addDefaultPane self addPane: (GLMPane named: #default)! ! !GLMWrapper methodsFor: 'accessing' stamp: 'TudorGirba 5/18/2012 22:28'! defaultPane ^ self panes anyOne ! ! !GLMWrapper methodsFor: 'initialize-release' stamp: 'TudorGirba 5/18/2012 22:20'! initialize super initialize. self addDefaultPane.! ! !GLMWrapper methodsFor: 'events' stamp: 'TudorGirba 5/19/2012 09:19'! innerPortEvent: aPortEvent "We forward all inner ports to the outside world" aPortEvent portName = #entity ifFalse: [ "We don't want to resend the transmission, but use a new SimpleTransmission." (self pane port: aPortEvent portName) value: aPortEvent value]! ! !GLMWrapper methodsFor: 'events' stamp: 'AndreiChis 5/30/2013 21:50'! outerPortEvent: aPortEvent "We only treat the #entity port, and for it we simply trigger a transmission to the default pane" super outerPortEvent: aPortEvent. aPortEvent port name = #entity ifFalse: [^self]. self newTransmission addActiveOrigin: (aPortEvent port); destination: (self panes anyOne port: #entity); transmit! ! !GLMWrapper methodsFor: 'rendering' stamp: 'TudorGirba 5/13/2012 09:37'! renderGlamorouslyOn: aRenderer ^ aRenderer renderWrapper: self! ! !GLMCompositePresentation commentStamp: 'tg 2/20/2010 14:51' prior: 34273271! A composite presentation offers means to control the composition of multiple presentations by providing the arrangement of these presentations.! !GLMBrowserWithoutBlocksExample commentStamp: '' prior: 34273487! self openOn: 42! !GLMBrowserWithoutBlocksExample methodsFor: 'as yet unclassified' stamp: 'TudorGirba 9/25/2013 06:54'! compose | wrapper | wrapper := self wrapper. wrapper show: [ :a | a list display: (MessageSend receiver: self selector: #displayList:) ]! ! !GLMBrowserWithoutBlocksExample methodsFor: 'as yet unclassified' stamp: 'TudorGirba 9/25/2013 06:52'! displayList: aNumber ^ 1 to: aNumber! ! !GLMCompositePresentation class methodsFor: 'openning' stamp: 'TudorGirba 4/1/2013 08:56'! openOn: anObject ^ self new openOn: anObject! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'tg 1/6/2010 23:15'! accordionArrangement ^ self arrangement: GLMAccordionArrangement new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/31/2012 16:19'! accumulator ^ self custom: GLMAccumulator new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! actionList ^ self custom: GLMActionListPresentation new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'TudorGirba 10/8/2011 16:39'! add: aPresentation self pane notingPresentationChangeDo: [ self presentations add: aPresentation. aPresentation pane: self pane ]. ^ aPresentation! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:11'! allSatisfy: aBlock ^ self presentations allSatisfy: aBlock ! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:11'! anySatisfy: aBlock ^ self presentations anySatisfy: aBlock ! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/12/2010 14:39'! arrangement ^ arrangement ifNil: [arrangement := GLMTabbedArrangement of: self]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/6/2010 23:16'! arrangement: anArrangement anArrangement composite: self. ^ arrangement := anArrangement! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:14'! at: aNumber ^ self presentations at: aNumber ! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 5/25/2010 23:55'! clear arrangement := nil. presentations := nil! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:16'! collect: aBlock ^ self copy presentations: (self presentations collect: aBlock ); yourself! ! !GLMCompositePresentation methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 00:55'! compose "by default this method is empty. override this method in subclasses to define a custom browser"! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! composite: aBlock | composite | composite := GLMCompositePresentation new. aBlock value: composite. ^ self custom: composite! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'AndreiChis 5/24/2013 11:40'! custom: aPresentation ^ self add: (aPresentation sourceContext: thisContext sender)! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:16'! defaultRenderer ^GLMRenderer subclasses first new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! diff ^ self custom: GLMDiffPresentation new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:12'! do: aBlock ^ self presentations do: aBlock ! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! dropDownList ^ self custom: GLMDropDownListPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! dynamic ^ self custom: GLMDynamicPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! finder ^ self custom: GLMFinder new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:05'! first ^ self presentations first! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 21:09'! includes: aPresentation ^ self presentations includes: aPresentation ! ! !GLMCompositePresentation methodsFor: 'initialize-release' stamp: 'TudorGirba 9/9/2012 00:54'! initialize super initialize. self compose! ! !GLMCompositePresentation methodsFor: 'initialize-release' stamp: 'AndreiChis 6/23/2013 21:39'! initializePresentation super initializePresentation. self do: [:each| each initializePresentation]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 15:17'! isEmpty ^ self presentations isEmpty! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! label ^ self custom: GLMLabelPresentation new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:28'! last ^ self presentations last! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! list ^ self custom: GLMListPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! magritte ^ self custom: GLMMagrittePresentation new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 21:09'! matchingPresentations ^ self presentations select: [:each | each matches]! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! morph ^ self custom: GLMMorphPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:16'! open ^self openWith: self defaultRenderer! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:16'! openOn: anObject ^self openOn: anObject with: self defaultRenderer! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:16'! openOn: anObject with: aRenderer self startOn: anObject. ^ self openWith: aRenderer! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:15'! openWith: aRenderer ^ aRenderer open: self! ! !GLMCompositePresentation methodsFor: 'events' stamp: 'AndreiChis 11/15/2012 14:24'! outerPortEvent: aPortEvent super outerPortEvent: aPortEvent. self do: [:each| each outerPortEvent: aPortEvent]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'TudorGirba 10/8/2011 15:21'! pane ^ pane ifNil: [ pane := (GLMPane named: 'root' in: GLMNoBrowser new) presentations: self; yourself]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/6/2010 11:56'! pane: aPane super pane: aPane. self presentations do: [:each | each pane: aPane ]! ! !GLMCompositePresentation methodsFor: 'comparison' stamp: 'TudorGirba 7/10/2011 13:08'! postCopy super postCopy. presentations ifNotNil: [ :arg | presentations := presentations collect: [ :each | each copy ] ]. arrangement ifNotNil: [ :arg | arrangement := arrangement copy. arrangement composite: self ]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 12/16/2009 17:45'! presentations ^ presentations ifNil: [presentations := OrderedCollection new]! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 12/14/2009 23:55'! presentations: anObject presentations := anObject! ! !GLMCompositePresentation methodsFor: 'rendering' stamp: 'tg 1/18/2010 21:31'! renderGlamorouslyOn: aRenderer "we delegate to the arrangement to dispatch the type of the actual arrangement of the nested presentations" self registerAnnouncements. ^ self arrangement renderGlamorouslyOn: aRenderer! ! !GLMCompositePresentation methodsFor: 'announcements' stamp: 'tg 1/30/2010 23:31'! resetAnnouncer super resetAnnouncer. self presentations do: [:each | each resetAnnouncer ]! ! !GLMCompositePresentation methodsFor: '*glamour-roassal-presentations' stamp: 'TudorGirba 5/5/2012 14:35'! roassal ^ self custom: GLMRoassalPresentation new! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:11'! select: aBlock ^ self presentations select: aBlock! ! !GLMCompositePresentation methodsFor: 'accessing' stamp: 'tg 1/5/2010 16:13'! size ^ self presentations size! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! smalltalkCode ^ self custom: GLMSmalltalkCodePresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 4/3/2013 17:02'! spec ^ self custom: GLMSpecPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'tg 1/14/2010 02:56'! stackedArrangement ^ self stackedVerticallyArrangement! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'tg 1/12/2010 14:37'! stackedVerticallyArrangement ^ self arrangement: (GLMStackedVerticallyArrangement of: self)! ! !GLMCompositePresentation methodsFor: 'scripting opening' stamp: 'TudorGirba 10/7/2011 20:16'! startOn: anObject self entity: anObject! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'tg 1/14/2010 17:21'! tabbedArrangement ^ self arrangement: GLMTabbedArrangement new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! table ^ self custom: GLMTablePresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! tabulator ^ self custom: GLMTabulator new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! text ^ self custom: GLMTextPresentation new! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 1/2/2012 01:15'! tree ^ self custom: GLMTreePresentation new! ! !GLMCompositePresentation methodsFor: 'announcements' stamp: 'tg 1/31/2010 00:26'! unregisterFromAllAnnouncements super unregisterFromAllAnnouncements. self presentations do: [:each | each unregisterFromAllAnnouncements ]! ! !GLMCompositePresentation methodsFor: 'updating' stamp: 'tg 8/24/2010 21:41'! update self pane ports do: [:each | (self validate: each value on: each) ifFalse: [each resetValue] ]. self presentations do: [ :each | each update ]. self announce: (GLMPresentationUpdated new presentation: self).! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'tg 1/12/2010 14:37'! verticallyStackedArrangement ^ self stackedVerticallyArrangement! ! !GLMCompositePresentation methodsFor: 'enumerating' stamp: 'TudorGirba 7/9/2011 20:06'! withAllPanesAndPresentationsDo: aBlock super withAllPanesAndPresentationsDo: aBlock. self do: [:each | each withAllPanesAndPresentationsDo: aBlock ]! ! !GLMCompositePresentation methodsFor: 'scripting' stamp: 'TudorGirba 11/14/2012 19:53'! wrapper ^ self custom: GLMWrapper new! ! !GLMExamplesBrowser commentStamp: 'TudorGirba 1/4/2012 08:47' prior: 34273576! self new browser openOn: GLMBasicExamples! !GLMExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 02:51'! compose "self new openOn: GLMBasicExamples" self tabulator with: [:browser | browser column: #titles; column: #example span: 4. browser transmit to: #titles; andShow: [ :a | self exampleListIn: a ]. browser transmit to: #example; fromOutsidePort: #entity; from: #titles; andShow: [ :a | self exampleIn: a ] ]! ! !GLMExamplesBrowser methodsFor: 'private'! exampleBrowserForPragma: each in: aClass | exampleBrowser wrapperBrowser | exampleBrowser := aClass new perform: each selector. wrapperBrowser := GLMTabulator new. wrapperBrowser column: #theOuterPane. wrapperBrowser transmit fromOutsideEntityPort; to: #theOuterPane; andShow: [:a | a custom: exampleBrowser ]. ^ wrapperBrowser startOn: (Compiler evaluate: (each argumentAt: 2) logged: false)! ! !GLMExamplesBrowser methodsFor: 'building'! exampleIn: composer composer dynamic title: 'Browser'; display: [ :exampleClass :examplePragma | self exampleBrowserForPragma: examplePragma in: exampleClass ]; act: [ :dynamic | dynamic cachedPresentation presentations first panes first presentations first openTree ] entitled: 'View browser tree'. composer smalltalkCode title: 'Source code'; act: [ :text :exampleClass :examplePragma | Smalltalk tools browser fullOnClass: exampleClass selector: examplePragma selector ] icon: GLMUIThemeExtraIcons glamorousBrowse entitled: 'Browse'; smalltalkClass: [ :exampleClass | exampleClass ]; doItReceiver: [ :exampleClass | exampleClass ]; display: [ :exampleClass :pragma | exampleClass sourceCodeAt: pragma selector ]! ! !GLMExamplesBrowser methodsFor: 'building'! exampleListIn: a ^ a list title: 'Examples'; display: [ :exampleClass | exampleClass allExamples ]; sorted: [ :x :y | (x argumentAt: 1) < (y argumentAt: 1) ]; format: [ :each | each argumentAt: 1 ]! ! !PPBrowser commentStamp: 'TudorGirba 3/4/2011 18:55' prior: 34273682! self open! !PPBrowser class methodsFor: 'accessing' stamp: 'lr 1/30/2013 18:41'! icon ^ (Form extent: 16@16 depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1069534679 2139069360 2139069360 2139069360 2139069360 1551866800 1199545264 1451203504 2139069360 2139069360 2139069360 2139069360 2139069360 260021168 8362928 16777215 2139069360 14177 67123041 620771169 1224750945 1845507937 3372234593 3087021921 4278204257 4278204257 4278204257 4278204257 4278204257 3405789025 452999009 16777215 2139069360 14177 117454689 704657249 1325414241 1728067425 2197829473 3288348513 4278204257 4278204257 3758110561 3691001697 4278204257 4278204257 654325601 16777215 2139069360 14177 201340769 822097761 1409300321 1543518049 1811953505 3523229537 4278204257 4278204257 2231383905 3019913057 4278204257 4278204257 620771169 16777215 2139069360 14177 318781281 939538273 1509963617 1862285153 2717923169 3573561185 4278204257 4278204257 3238016865 3640670049 4278204257 4060100449 452999009 16777215 2139069360 1593849697 1862285153 2248161121 2281715553 2751477601 3003135841 3825219425 4278204257 4278204257 4278204257 4278204257 4278204257 1476409185 100677473 16777215 2139069360 33568609 536885089 1157642081 1644181345 1946171233 2214606689 4278204257 4278204257 3389011809 2281715553 2130720609 268449633 16791393 14177 16777215 2139069360 83900257 637548385 1258305377 1543518049 1543518049 1543518049 4278204257 4278204257 2466264929 201340769 14177 14177 14177 14177 16777215 2139069360 151009121 754988897 1375745889 1543518049 1543518049 1543518049 4278204257 4278204257 2298492769 125803440 16777215 16777215 16777215 16777215 16777215 2139069360 234895201 872429409 1426077537 1543518049 1543518049 2902472545 4278204257 4278204257 603993953 75471792 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: 0@0)! ! !PPBrowser class methodsFor: 'accessing' stamp: 'lr 1/30/2013 18:41'! label ^ 'PetitParser'! ! !PPBrowser class methodsFor: 'private' stamp: 'lr 1/30/2013 18:42'! menuCommandOn: aBuilder (aBuilder item: self label) parent: #Tools; icon: self icon; action: [ self open ]! ! !PPBrowser class methodsFor: 'instance creation' stamp: 'lr 1/30/2013 18:42'! open ^ self openOn: PPCompositeParser! ! !PPBrowser class methodsFor: 'instance creation' stamp: 'TudorGirba 2/5/2013 15:15'! openOn: aClass "Less glamorous versions of Glamour do not work with the new browser, fall back to the old one in this case." (self superclass canUnderstand: #compose) ifFalse: [ ^ PPDrabBrowser new openOn: aClass ]. ^ self new openOn: aClass! ! !PPBrowser methodsFor: 'private building' stamp: 'TudorGirba 11/30/2012 09:09'! addNewSubParserOf: class in: list | refactoring className | className := UIManager default request: 'Parser class name' initialAnswer: '' title: 'Add new parser'. ^ className ifNotNil: [ refactoring := PPAddParserRefactoring name: className asSymbol category: #ParserExample superclass: class. PPRefactoringUtils new performRefactoring: refactoring. list update ]! ! !PPBrowser methodsFor: 'private building' stamp: 'TudorGirba 11/30/2012 09:12'! classesIn: composite composite tree title: 'Parsers'; format: [ :class | class name ]; children: [ :class | class subclasses asSortedCollection: [ :a :b | a name < b name ] ]; display: [ :class | class subclasses asSortedCollection: [ :a :b | a name < b name ] ]; selectionAct: [ :list :class | Smalltalk tools browser fullOnClass: list selection ] on: $b entitled: 'Browse (b)'; selectionAct: [ :list :class | self addNewSubParserOf: list selection in: list ] entitled: 'Add new sub parser'; act: [ :list :class | self addNewSubParserOf: class in: list ] icon: GLMUIThemeExtraIcons glamorousAdd on: $+ entitled: 'Add new parser'! ! !PPBrowser methodsFor: 'building' stamp: 'TudorGirba 12/8/2012 14:33'! compose "self open" self title: self defaultTitle. self tabulator with: [ :tabulator | tabulator column: #classes; column: #parser span: 3. tabulator transmit to: #classes; andShow: [:a | self classesIn: a ]. tabulator transmit to: #parser; from: #classes; andShow: [:a | a custom: PPParserBrowser new noTitle ] ]! ! !PPBrowser methodsFor: 'building' stamp: 'TudorGirba 12/8/2012 14:33'! defaultTitle ^ 'PetitParser Browser'! ! !PPParserBrowser commentStamp: 'TudorGirba 11/25/2012 20:38' prior: 34273764! self new openOn: PPArithmeticParser! !PPParserBrowser class methodsFor: 'as yet unclassified' stamp: 'TudorGirba 11/26/2012 21:09'! openOn: aParserClass ^ self new openOn: aParserClass! ! !PPParserBrowser methodsFor: 'building' stamp: 'JanKurs 11/30/2012 14:53'! buildBrowser "self openOn: PPArithmeticParser" | browser | browser := GLMTabulator new. browser title: [:each | each name]. browser row: [:r | r column: #productions ; column: #workspace span: 2]; row: #inspector. browser transmit to: #productions; andShow: [:a | self productionsIn: a ]. browser transmit to: #workspace; fromOutsidePort: #entity; from: #productions; andShow: [:a | self workspaceIn: a ]. browser transmit to: #inspector; fromOutsidePort: #entity; from: #productions; passivelyFrom: #outer port: #sampleText; andShow: [:a | self inspectorIn: a ]. browser transmit from: #inspector port: #sampleText; toOutsidePort: #sampleText; when: [:arg | arg notNil ]. browser transmit from: #workspace; toOutsidePort: #productionToSelect; transformed: [:parser | parser name ]; when: [:parser | parser name notNil ]. browser transmit fromOutsidePort: #productionToSelect; to: #productions port: #selection. ^ browser! ! !PPParserBrowser methodsFor: 'building' stamp: 'TudorGirba 11/26/2012 21:10'! compose "self openOn: PPArithmeticParser" self title: [:each | each name]. self tabulator with: [ :tabulator | tabulator row: [:r | r column: #productions ; column: #workspace span: 2]; row: #inspector. tabulator transmit to: #productions; andShow: [:a | self productionsIn: a ]. tabulator transmit to: #workspace; fromOutsidePort: #entity; from: #productions; andShow: [:a | self workspaceIn: a ]. tabulator transmit to: #inspector; fromOutsidePort: #entity; from: #productions; passivelyFrom: #outer port: #sampleText; andShow: [:a | self inspectorIn: a ]. tabulator transmit from: #inspector port: #sampleText; toOutsidePort: #sampleText; when: [:arg | arg notNil ]. tabulator transmit from: #workspace; toOutsidePort: #productionToSelect; transformed: [:parser | parser name ]; when: [:parser | parser name notNil ]. tabulator transmit fromOutsidePort: #productionToSelect; to: #productions port: #selection ]! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 12/15/2011 12:53'! exampleIn: composite composite text title: 'Example'; useExplicitNotNil; display: [ :class :productionSelector | (self production: productionSelector from: class) example ]; act: [:text | text update] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Generate another one'! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 12/20/2011 16:26'! firstIn: composite composite list title: 'First'; useExplicitNotNil; display: [ :class :productionSelector | (self production: productionSelector from: class) firstSet ]; format: [ :parser | parser displayName ]! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 12/20/2011 16:28'! followIn: aBrowser aBrowser list title: 'Follow'; useExplicitNotNil; format: [ :parser | parser displayName ]; display: [ :class :productionSelector | | parser | parser := class new. parser followSets at: (parser productionAt: productionSelector) ifAbsent: [ Array with: nil asParser ] ]! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 12/4/2011 00:50'! graphIn: composite composite morph title: 'Graph'; useExplicitNotNil; display: [ :class :selector | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: (self production: selector from: class) morphicProduction. morph ]! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 11/26/2012 20:59'! inspectorIn: composite composite dynamic allowNil; display: [ :class :productionSelector :sampleText | | wrapperBrowser | wrapperBrowser := GLMTabulator new. wrapperBrowser allowNil. wrapperBrowser column: #wrapped. wrapperBrowser transmit to: #wrapped; andShow: [ :a | a custom: (PPParserInspector new noTitle) ]. wrapperBrowser transmit from: #wrapped port: #sampleText; toOutsidePort: #sampleText. wrapperBrowser transmit fromOutsidePort: #sampleText; to: #wrapped port: #sampleText. wrapperBrowser startOn: ([(self production: productionSelector from: class) end] on: Error do: [:e | nil]) . (wrapperBrowser pane port: #sampleText) value: (sampleText ifNil: [ '' ] ifNotNil: [ sampleText ]). wrapperBrowser ] ! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 10/12/2012 16:20'! mapIn: composite self class environment at: #GLMRoassalPresentation ifPresent: [ :cls | composite roassal title: 'Map'; useExplicitNotNil; painting: [ :view :class :selector | (self production: #start from: class) viewAllNamedParsersWithSelection: (Array with: selector) previewing: [:eachParser | self sourceCodeFrom: class selector: eachParser name ] on: view ] ] ! ! !PPParserBrowser methodsFor: 'private utilities' stamp: 'TudorGirba 12/3/2011 23:50'! production: selector from: class | parser | parser := class new. ^ selector isNil ifTrue: [ parser ] ifFalse: [ parser productionAt: selector ]! ! !PPParserBrowser methodsFor: 'private utilities' stamp: 'JanKurs 12/3/2012 12:52'! productionSelectorsFrom: class ^ (((class allInstVarNames copyWithoutAll: class ignoredNames) collect: [ :each | each asSymbol ]) select: [ :each | class includesSelector: each ]) asSortedCollection add: #start; yourself! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 11/28/2012 22:58'! productionsIn: composite "Doru: These menus should be built dynamically: title and enabled status should adapt" "enabled: RBRefactoryChangeManager instance hasRedoableOperations" " , RBRefactoryChangeManager instance redoChange" "enabled: RBRefactoryChangeManager instance hasUndoableOperations" " , RBRefactoryChangeManager instance undoChange " composite list title: [ :class | class name ]; format: [ :class | class asString ]; display: [ :class | self productionSelectorsFrom: class ]; shouldValidate: true; act: [ :list :class | RBRefactoryChangeManager instance redoOperation. list pane browser update ] icon: GLMUIThemeExtraIcons glamorousRedo entitled: 'Redo'; act: [ :list :class | RBRefactoryChangeManager instance undoOperation. list pane browser update ] icon: GLMUIThemeExtraIcons glamorousUndo entitled: 'Undo'; selectionAct: [ :list :class | | oldName refactoring | oldName := list selection. refactoring := PPRefactoringUtils new performRenameProduction: oldName from: class. refactoring changes changes notEmpty ifTrue: [ list update. list selection: refactoring changes changes first newName asSymbol ] ] on: $r entitled: 'Rename (r)'; selectionAct: [ :list :class | PPRefactoringUtils new performRefactoring: (PPRemoveProdcutionRefactoring onClass: class production: list selection). list pane browser update ] on: $x entitled: 'Remove (x)'; selectionAct: [ :list :class | Smalltalk tools browser fullOnClass: class selector: list selection ] on: $b entitled: 'Browse (b)'; selectionAct: [ :list :class | (self production: list selection from: class) explore ] on: $I entitled: 'Explore (I)'! ! !PPParserBrowser methodsFor: 'private utilities' stamp: 'JanKurs 12/3/2012 13:26'! sourceCodeFrom: class selector: production ^ class ultimateSourceCodeAt: (production ifNil: [ #start ]) ifAbsent: [ String new ]! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 11/28/2012 22:59'! sourceIn: composite composite smalltalkCode title: 'Source'; useExplicitNotNil; display: [ :class :production | self sourceCodeFrom: class selector: production ]; smalltalkClass: [ :class | class ]; selectionAct: [ :text :class :production | | selector refactoring | selector := UIManager default request: 'Production name to extract to:' initialAnswer: '' title: 'Extract production'. selector isEmptyOrNil ifFalse: [ selector := selector asSymbol. refactoring := PPExtractProdcutionRefactoring onClass: class production: production interval: text selectionInterval to: selector. PPRefactoringUtils new performRefactoring: refactoring. text pane browser update. (text pane port: #productionToSelect) value: selector ] ] on: $e entitled: 'Extract production'; act: [ :text :class :production | | selector refactoring | refactoring := PPDefineProdcutionRefactoring onClass: class source: text text asString protocols: #(grammar). PPRefactoringUtils new performRefactoring: refactoring. selector := refactoring changes changes last selector. selector = production ifTrue: [text update] ifFalse: [ text pane browser update. (text pane port: #productionToSelect) value: selector ] ] icon: GLMUIThemeExtraIcons glamorousAccept on: $s entitled: 'Accept'! ! !PPParserBrowser methodsFor: 'private building' stamp: 'TudorGirba 12/20/2011 16:24'! workspaceIn: composite self sourceIn: composite. self graphIn: composite. self mapIn: composite. self exampleIn: composite. self firstIn: composite. self followIn: composite.! ! !PPParserInspector commentStamp: 'TudorGirba 12/3/2011 17:25' prior: 34273873! This browser expects an instance of PPParser in the #entity port. self openOn: PPArithmeticParser new.! !PPParserInspector class methodsFor: 'as yet unclassified' stamp: 'JanKurs 11/30/2012 15:00'! openOn: aParserInstance ^ self new openOn: aParserInstance! ! !PPParserInspector methodsFor: 'building' stamp: 'TudorGirba 11/26/2012 21:12'! compose "self new openOn: PPArithmeticParser new" self title: [:each | 'Parser Inspector on ', (each name ifNil: [each class name])]. self tabulator with: [ :browser | browser column: #sample; column: #inspectors. (browser transmit) fromOutsidePort: #entity; fromOutsidePort: #sampleText; to: #sample; andShowIfNone: [ :a | self sampleIn: a ]. (browser transmit) from: #sample port: #text; toOutsidePort: #sampleText. (browser transmit) from: #sample; "result" passivelyFrom: #sample port: #text; "sample text" from: #sample port: #stream; "parser stream" fromOutsidePort: #entity; "parser" to: #inspectors; andShow: [ :a | self inspectorsIn: a ]. browser transmit from: #inspectors; to: #sample port: #selectionInterval; transformed: [:debugResult | debugResult ifNotNil: [debugResult start to: debugResult end] ] ]! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 12/3/2011 21:59'! debuggerIn: composite composite tree title: 'Debugger'; format: [:resultNode | resultNode formattedText ]; display: [ :result :sample :stream :parser | {PPParserDebuggerResult parse: sample with: parser } ]; children: [:resultNode | resultNode children ].! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 12/3/2011 21:50'! inspectorsIn: composite self resultIn: composite. self debuggerIn: composite. self tallyIn: composite. self profileIn: composite. self progressIn: composite! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 12/14/2011 17:48'! profileIn: composite composite table title: 'Profile'; column: 'Parser' evaluated: [ :each | each first displayName ]; column: 'Time (ms)' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ :result :sample :stream :parser | stream asFrequencyTable ]; noSelection; showOnly: 50 ! ! !PPParserInspector methodsFor: 'private building' stamp: 'lr 9/12/2011 18:41'! progressChartIn: composite composite morph title: 'Progress'; display: [ :stream | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: stream asPositionMorph. morph ]! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 12/3/2011 21:59'! progressIn: composite composite morph title: 'Progress'; display: [:result :sample :stream :parser | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: stream asPositionMorph. morph ]! ! !PPParserInspector methodsFor: 'private building' stamp: 'JanKurs 12/5/2012 16:36'! resultIn: composite (composite text) title: 'Result'; display: [ :result :sample :stream :parser | result ]; act: [ :text :result :sample :stream :parser | result inspect ] icon: GLMUIThemeExtraIcons glamorousInspect entitled: 'Inspect'; act: [ :text :result :sample :stream :parser | result explore ] icon: GLMUIThemeExtraIcons glamorousSearch entitled: 'Explore'.! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 11/30/2012 23:51'! sampleIn: composite (composite text) title: 'Sample'; display: [:parser :sample | sample ifNil: [''] ]; allowNil; populate: #selection icon: GLMUIThemeExtraIcons glamorousPlay on: $s entitled: 'Parse (s)' with: [ :presentation :parser | | stream output | stream := PPBrowserStream on: presentation text asString. output := parser parse: stream. output isPetitFailure ifTrue: [ presentation selectionInterval: (output position + 1 to: output position) ]. (presentation pane port: #stream) value: stream. output ]! ! !PPParserInspector methodsFor: 'private building' stamp: 'TudorGirba 12/14/2011 17:48'! tallyIn: composite composite table title: 'Tally'; column: 'Parser' evaluated: [ :each | each first displayName ]; column: 'Count' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [:result :sample :stream :parser | stream asFrequencyTable ]; noSelection; showOnly: 50! ! !GLMDynamicPresentation commentStamp: 'tg 9/20/2009 14:25' prior: 34274047! A GLMDynamicPresentation is a presentation that takes the actual presentation from the display value. Like this, we can have the block of display return a presentation depending on the input. A usage for this behavior is the Glamorous Editor, which takes the text as input and based on this it displays the browser.! !GLMDynamicPresentation methodsFor: 'rendering' stamp: 'TudorGirba 5/25/2013 12:11'! cachedPresentation "currentPresentation applies the transformation dynamically. This means that calling it twice, will retrieve two different objects. To solve the problem, cachedPresentation stores the last currentPresentation, and it can be used for further inspection" ^ cachedPresentation! ! !GLMDynamicPresentation methodsFor: 'rendering' stamp: 'AndreiChis 6/24/2013 13:24'! currentPresentation | composite | composite := GLMCompositePresentation new. self presentationTransformation glamourValue: ( composite asGlamorousMultiValue, self displayValue asGlamorousMultiValue). composite pane: self pane. composite initializePresentation. cachedPresentation := composite. ^ composite " ^ self displayValue pane: self pane"! ! !GLMDynamicPresentation methodsFor: 'initialize-release'! initialize super initialize. presentationTransformation := [ :aComposite :each | aComposite custom: each ]! ! !GLMDynamicPresentation methodsFor: 'scripting'! presentation: aBlock self presentationTransformation: aBlock! ! !GLMDynamicPresentation methodsFor: 'accessing'! presentationTransformation ^ presentationTransformation! ! !GLMDynamicPresentation methodsFor: 'accessing'! presentationTransformation: anObject presentationTransformation := anObject! ! !GLMDynamicPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderDynamicPresentation: self! ! !GLMDynamicPresentation methodsFor: 'scripting'! with: aBlock self presentationTransformation: aBlock! ! !GLMDynamicPresentation methodsFor: 'enumerating' stamp: 'TudorGirba 5/25/2013 12:12'! withAllPanesAndPresentationsDo: aBlock super withAllPanesAndPresentationsDo: aBlock. self cachedPresentation ifNotNil: [ :presentation | presentation withAllPanesAndPresentationsDo: aBlock ]! ! !GLMFlexiblePresentation commentStamp: '' prior: 34274429! A presentation that flexibly changes it behavior depending on the current entity. If the entity is a collection, this class renders as a ListPresentation, otherwise as a TextPresentation.! !GLMFlexiblePresentation methodsFor: 'accessing'! currentPresentation ^ (self displayValue isCollection and: [self displayValue isString not]) ifTrue: [GLMListPresentation new showOnly: 50; pane: self pane] ifFalse: [GLMTextPresentation new pane: self pane]! ! !GLMFlexiblePresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^self currentPresentation renderGlamorouslyOn: aRenderer! ! !GLMFormatedPresentation commentStamp: 'TudorGirba 2/4/2011 17:56' prior: 34274696! GLMFormatedPresentation is an abstract presentation that offers a format block to be used for formatting the rendering of the presentation. The renderer will use the formatDisplayValueOf: method.! !GLMActionListPresentation methodsFor: 'scripting' stamp: 'AndreiChis 8/6/2013 18:48'! beVertical self isHorizontal: false! ! !GLMActionListPresentation methodsFor: 'testing' stamp: 'EstebanLorenzano 4/20/2012 16:19'! hasActions ^false! ! !GLMActionListPresentation methodsFor: 'accessing' stamp: 'AndreiChis 8/6/2013 18:34'! isHorizontal ^ isHorizontal ifNil: [isHorizontal := true]! ! !GLMActionListPresentation methodsFor: 'accessing'! isHorizontal: anObject isHorizontal := anObject! ! !GLMActionListPresentation methodsFor: 'accessing'! isVertical ^ self isHorizontal not! ! !GLMActionListPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderActionListPresentation: self! ! !GLMDiffPresentation commentStamp: 'TudorGirba 7/14/2011 11:49' prior: 34274967! GLMDiffPresentation is meant to show the difference between two input text objects. The convention is that the transformed entity should provide a collection with two elements.! !GLMDiffPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderDiffPresentation: self! ! !GLMDropDownListPresentation methodsFor: 'rendering'! defaultValidate: anObject on: aPort "we only allow objects that are in the display value" (aPort name == #selection) ifFalse: [ ^ true ]. self entity isNil ifTrue: [ ^ false ]. ^ self displayValue includes: anObject ! ! !GLMDropDownListPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderDropDownListPresentation: self! ! !GLMDropDownListPresentation methodsFor: 'accessing'! selectedIndex ^ selectedIndex ifNil:[ selectedIndex := 0 ] ! ! !GLMDropDownListPresentation methodsFor: 'accessing'! selectedIndex: index selectedIndex:= index! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'TudorGirba 9/25/2013 06:29'! format ^ format ifNil: [ format := #asString ]! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! format: anObject format := anObject! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'tg 9/9/2009 00:58'! formatedDisplayValue ^ self format glamourValue: self displayValue! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'tg 9/9/2009 01:03'! formatedDisplayValueOf: anObject ^ self format glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue)! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'tg 9/11/2009 19:56'! icon ^ icon ifNil: [ icon := [nil] ]! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'tg 9/11/2009 19:55'! icon: anObject icon := anObject! ! !GLMFormatedPresentation methodsFor: 'accessing' stamp: 'tg 9/11/2009 19:56'! iconFor: anObject ^ self icon glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue)! ! !GLMLabelPresentation methodsFor: 'rendering' stamp: 'tg 3/30/2010 23:06'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderLabelPresentation: self! ! !GLMListingPresentation commentStamp: 'TudorGirba 2/4/2011 20:41' prior: 34275222! This is the abstract class for a presentation that is supposed to show a list of elements. Thus, the displayValue should be a list. Instance Variables: tagsBlock searchBlock filterBlock amountToShowBlock allowsMultipleSelection tagsFilterBlock allowsDeselection tagsStyle helpMessage ! !GLMListPresentation methodsFor: 'validation'! defaultValidate: anObject on: aPort "we only allow objects that are in the display value" (aPort name == #selection) ifFalse: [ ^ true ]. self entity isNil ifTrue: [ ^ false ]. ^ self isMultiple ifTrue: [ anObject isCollection and: [ anObject allSatisfy: [:each | self displayValue includes: each ] ]] ifFalse: [ self displayValue includes: anObject ]! ! !GLMListPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderListPresentation: self! ! !GLMListingPresentation methodsFor: 'accessing values'! accept: passengerObject droppedOnItem: anItem self dropOnItemBlock glamourValue: (GLMMultiValue with: passengerObject with: anItem with: self). ^ true! ! !GLMListingPresentation methodsFor: 'accessing values'! allow: passengerObject droppedOnItem: anItem ^ self allowDropOnItemBlock glamourValue: (GLMMultiValue with: passengerObject with: anItem with: self)! ! !GLMListingPresentation methodsFor: 'scripting'! allowDeselection self allowsDeselection: true! ! !GLMListingPresentation methodsFor: 'scripting'! allowDropOnItem: aBlock allowDropOnItemBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! allowDropOnItemBlock ^ allowDropOnItemBlock! ! !GLMListingPresentation methodsFor: 'scripting'! allowItemDrag: aBlock allowItemDragBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! allowItemDragBlock ^ allowItemDragBlock! ! !GLMListingPresentation methodsFor: 'accessing'! allowsDeselection ^ allowsDeselection ifNil: [allowsDeselection := false]! ! !GLMListingPresentation methodsFor: 'accessing'! allowsDeselection: anObject allowsDeselection := anObject! ! !GLMListingPresentation methodsFor: 'testing'! allowsFilter ^ filterBlock notNil! ! !GLMListingPresentation methodsFor: 'testing'! allowsInput ^ self allowsFilter or: [ self allowsSearch ]! ! !GLMListingPresentation methodsFor: 'testing'! allowsItemDrag ^ self allowItemDragBlock notNil! ! !GLMListingPresentation methodsFor: 'testing'! allowsSearch ^ searchBlock notNil! ! !GLMListingPresentation methodsFor: 'accessing'! amountToShow ^ amountToShowBlock glamourValue: self entity! ! !GLMListingPresentation methodsFor: 'scripting'! beMultiple allowsMultipleSelection := true! ! !GLMListingPresentation methodsFor: 'scripting'! beSingle allowsMultipleSelection := false! ! !GLMListingPresentation methodsFor: 'accessing'! childrenValueOf: anObject self flag: 'this is rather hackish, but needed to treat list and tree in the same way.'. ^ OrderedCollection new! ! !GLMListingPresentation methodsFor: 'accessing'! childrenValueOf: anObject atLevel: anInteger self flag: 'this is rather hackish, but needed to treat list and tree in the same way.'. ^ OrderedCollection new! ! !GLMListingPresentation methodsFor: 'accessing'! columns self flag: 'this is rather hackish, but needed to treat list and tree in the same way.'. ^ OrderedCollection new! ! !GLMListingPresentation methodsFor: 'accessing values'! displayValue ^ sortBlock ifNil: [super displayValue] ifNotNil: [super displayValue sorted: sortBlock]! ! !GLMListingPresentation methodsFor: 'scripting'! dropOnItem: aBlock dropOnItemBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! dropOnItemBlock ^ dropOnItemBlock ! ! !GLMListingPresentation methodsFor: 'scripting'! filterOn: aBlock filterBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! filterStrategy ^filterBlock! ! !GLMListingPresentation methodsFor: 'accessing'! grayRoundedTags tagsStyle := #grayRoundedButton! ! !GLMListingPresentation methodsFor: 'testing'! hasTags ^ tagsBlock notNil! ! !GLMListingPresentation methodsFor: 'testing'! hasTagsFilter ^ tagsFilterBlock notNil! ! !GLMListingPresentation methodsFor: 'accessing'! helpMessage ^ helpMessage ifNil: [ helpMessage := 'Search Input' ] ! ! !GLMListingPresentation methodsFor: 'accessing'! helpMessage: aString helpMessage := aString. ! ! !GLMListingPresentation methodsFor: 'testing'! isDragSource ^ self dropOnItemBlock notNil! ! !GLMListingPresentation methodsFor: 'testing'! isDropTarget ^ self dropOnItemBlock notNil! ! !GLMListingPresentation methodsFor: 'testing'! isMultiple ^ allowsMultipleSelection ifNil: [ allowsMultipleSelection := false ]! ! !GLMListingPresentation methodsFor: 'testing'! isSingle ^ self isMultiple not! ! !GLMListingPresentation methodsFor: 'scripting'! searchOn: aBlock searchBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! searchStrategy ^ searchBlock! ! !GLMListingPresentation methodsFor: 'accessing'! selectionPath ^ (self pane port: #selectionPath) value! ! !GLMListingPresentation methodsFor: 'accessing'! selectionPath: anObject (self pane port: #selectionPath) value: anObject! ! !GLMListingPresentation methodsFor: 'scripting'! showOnly: aBlock amountToShowBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! sortBlock ^ sortBlock! ! !GLMListingPresentation methodsFor: 'accessing'! sortBlock: anObject sortBlock := anObject! ! !GLMListingPresentation methodsFor: 'scripting'! sorted sortBlock := [:a :b | a < b]! ! !GLMListingPresentation methodsFor: 'scripting'! sorted: aBlock sortBlock := aBlock ! ! !GLMListingPresentation methodsFor: 'scripting'! tags: anObject "Displays a tag along the node with a text and/or an icon, as returned when evaluating anObject. Clicking on such a node's' tag would remove all nodes that don't have this tag (this behavior can be changed by sending the #tagsFilter: message)" tagsBlock := anObject. self hasTagsFilter ifFalse:[ tagsFilterBlock := anObject ]! ! !GLMListingPresentation methodsFor: 'accessing'! tagsBlock ^ tagsBlock! ! !GLMListingPresentation methodsFor: 'accessing'! tagsBlock: anObject tagsBlock := anObject! ! !GLMListingPresentation methodsFor: 'scripting'! tagsFilter: anObject "Changes the default behavior of hiding all nodes that don't have the exact same tag as the one just clicked" tagsFilterBlock := anObject ! ! !GLMListingPresentation methodsFor: 'accessing'! tagsFilterBlock ^ tagsFilterBlock! ! !GLMListingPresentation methodsFor: 'accessing'! tagsFor: anObject | value | self hasTags ifFalse: [ ^ OrderedCollection new ]. value := self tagsBlock glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue). ^ value isString ifTrue: [ OrderedCollection with: value ] ifFalse: [ value asOrderedCollection ]! ! !GLMListingPresentation methodsFor: 'accessing'! tagsFor: anObject to: operation | value hasTags tags | operation == #show ifTrue: [ hasTags := self hasTags. tags := self tagsBlock ] ifFalse: [ hasTags := self hasTagsFilter. tags := self tagsFilterBlock ]. hasTags ifFalse: [ ^ OrderedCollection new ]. value := tags glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue). ^ value isString ifTrue: [ OrderedCollection with: value ] ifFalse: [ value asOrderedCollection ]! ! !GLMListingPresentation methodsFor: 'accessing'! tagsStyle ^tagsStyle ifNil:[ self grayRoundedTags. tagsStyle ]! ! !GLMListingPresentation methodsFor: 'accessing'! textBackgroundColor ^ textBackgroundColor ifNil: [textBackgroundColor := Color transparent]! ! !GLMListingPresentation methodsFor: 'accessing'! textBackgroundColor: aBlockOrAColor textBackgroundColor := aBlockOrAColor! ! !GLMListingPresentation methodsFor: 'accessing'! textBackgroundColorFor: anObject ^ self textBackgroundColor glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue)! ! !GLMListingPresentation methodsFor: 'scripting'! transformDraggedItem: aBlock transformDraggedItemBlock := aBlock! ! !GLMListingPresentation methodsFor: 'accessing'! transformDraggedItemBlock ^ transformDraggedItemBlock! ! !GLMListingPresentation methodsFor: 'accessing values' stamp: 'EstebanLorenzano 4/1/2012 12:40'! transformedDraggedItem: anItem ^ self transformDraggedItemBlock ifNotNil: [ :transform | transform glamourValue: (GLMMultiValue with: anItem with: self)] ifNil: [ anItem ]! ! !GLMListingPresentation methodsFor: 'accessing'! whiteRectangledTags tagsStyle := #whiteRectangledButton! ! !GLMListingPresentation methodsFor: 'scripting'! withSmalltalkSearch self searchOn: [:text :each | Compiler evaluate: ' | entity each | each := self. entity := each.', text for: each logged: false]; helpMessage: 'Quick selection field. Given your INPUT, it executes: self select: [:each | INPUT ]'! ! !GLMTablePresentation methodsFor: 'accessing'! addColumn: aColumn self columns add: aColumn! ! !GLMTablePresentation methodsFor: 'scripting'! column: aBlockOrString evaluated: aBlock self addColumn: (GLMTableColumn new title: aBlockOrString; computation: aBlock)! ! !GLMTablePresentation methodsFor: 'scripting' stamp: 'TudorGirba 6/7/2013 12:52'! column: aBlockOrString evaluated: aBlock width: aNumber self addColumn: (GLMTableColumn new title: aBlockOrString; computation: aBlock; width: aNumber; yourself) ! ! !GLMTablePresentation methodsFor: 'private'! column: aGlamourColumn valueFor: anObject ^ aGlamourColumn computation glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue)! ! !GLMTablePresentation methodsFor: 'accessing'! columns ^ columns ifNil: [ columns := OrderedCollection new ]! ! !GLMTablePresentation methodsFor: 'accessing'! columns: aCollection columns := aCollection ! ! !GLMTablePresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderTablePresentation: self! ! !GLMTablePresentation methodsFor: 'private'! titleValueOfColumn: aColumn ^ aColumn title glamourValue: self entity! ! !GLMTreePresentation methodsFor: 'validation'! allDisplayedDo: aBlock self displayValue do: [ :eachRoot | self withChildrenOf: eachRoot do: aBlock ]! ! !GLMTreePresentation methodsFor: 'accessing'! allExpanded self shouldAllExpand: true! ! !GLMTreePresentation methodsFor: 'accessing'! children ^children! ! !GLMTreePresentation methodsFor: 'accessing'! children: anObject children := anObject! ! !GLMTreePresentation methodsFor: 'accessing'! childrenValueOf: anObject ^ self children glamourValue: (anObject asGlamorousMultiValue, self entity asGlamorousMultiValue)! ! !GLMTreePresentation methodsFor: 'accessing'! childrenValueOf: anObject atLevel: anInteger ^ self children glamourValue: ( anObject asGlamorousMultiValue, self entity asGlamorousMultiValue, anInteger asGlamorousMultiValue, self asGlamorousMultiValue)! ! !GLMTreePresentation methodsFor: 'validation'! defaultValidate: anObject on: aPort "we only allow objects that are in the display value" (aPort name == #selection) ifFalse: [ ^ true ]. self entity isNil ifTrue: [ ^ false ]. self allDisplayedDo: [:each | each = anObject ifTrue: [ ^ true ] ]. ^ false! ! !GLMTreePresentation methodsFor: 'accessing' stamp: 'JanKurs 5/27/2013 14:35'! expandLevel ^ expandLevel! ! !GLMTreePresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderTreePresentation: self! ! !GLMTreePresentation methodsFor: 'accessing'! rootsExpanded self shouldRootsExpand: true! ! !GLMTreePresentation methodsFor: 'accessing'! shouldAllExpand ^ allExpanded ifNil: [false]! ! !GLMTreePresentation methodsFor: 'accessing'! shouldAllExpand: anObject allExpanded := anObject! ! !GLMTreePresentation methodsFor: 'accessing' stamp: 'JanKurs 5/27/2013 14:33'! shouldExpandToLevel ^ expandLevel isNil not! ! !GLMTreePresentation methodsFor: 'accessing' stamp: 'JanKurs 5/27/2013 14:34'! shouldExpandToLevel: level ^ expandLevel := level! ! !GLMTreePresentation methodsFor: 'accessing'! shouldRootsExpand ^ rootsExpanded ifNil: [false]! ! !GLMTreePresentation methodsFor: 'accessing'! shouldRootsExpand: anObject rootsExpanded := anObject! ! !GLMTreePresentation methodsFor: 'validation'! withChildrenOf: anObject do: aBlock aBlock value: anObject. (self childrenValueOf: anObject) do: [ :each | self withChildrenOf: each do: aBlock ]! ! !GLMInputPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderInputPresentation: self! ! !GLMSmalltalkCodePresentation methodsFor: 'accessing'! highlightSmalltalkContext ^ highlightSmalltalkContext isNil ifTrue: [nil] ifFalse: [highlightSmalltalkContext glamourValue: self entity]! ! !GLMSmalltalkCodePresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderSmalltalkCodePresentation: self! ! !GLMSmalltalkCodePresentation methodsFor: 'accessing'! smalltalkClass: aBlock "aBlock takes as parameters the entity objects and its evaluation is expected to produce a Smalltalk class" highlightSmalltalkContext := aBlock.! ! !GLMTextPresentation commentStamp: 'TudorGirba 3/5/2011 21:22' prior: 34275751! A presentation displaying text. Instance Variables: selectedTextBlock highlightSmalltalk highlightSmalltalkContext textBlock ! !GLMTextPresentation methodsFor: 'accessing'! forSmalltalk highlightSmalltalk := true! ! !GLMTextPresentation methodsFor: 'accessing'! forSmalltalk: aBlock "aBlock takes as parameters the entity objects and its evaluation is expected to produce a Smalltalk class" highlightSmalltalk := true. highlightSmalltalkContext := aBlock.! ! !GLMTextPresentation methodsFor: 'accessing'! highlightSmalltalk ^ highlightSmalltalk ifNil: [highlightSmalltalk := false]! ! !GLMTextPresentation methodsFor: 'accessing'! highlightSmalltalkContext ^ highlightSmalltalkContext isNil ifTrue: [nil] ifFalse: [highlightSmalltalkContext glamourValue: self entity]! ! !GLMTextPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderTextPresentation: self! ! !GLMTextualPresentation methodsFor: 'accessing ports'! cursorPosition ^cursorPosition! ! !GLMTextualPresentation methodsFor: 'accessing ports'! cursorPosition: anObject cursorPosition := anObject! ! !GLMTextualPresentation methodsFor: 'accessing' stamp: 'AndreiChis 8/13/2013 15:43'! doItContext "Return a context use for evaluating code in the presentation. Any variable contained in the executed code will be looked up in this context." ^ doItContext glamourValue: self entity! ! !GLMTextualPresentation methodsFor: 'accessing' stamp: 'AndreiChis 8/13/2013 15:42'! doItContext: aOneArgBlock "The block will be passed the current entity and is expected to return a context. Any code evaluated from the presentation will be executed as part of the retuned context." doItContext := aOneArgBlock! ! !GLMTextualPresentation methodsFor: 'accessing'! doItReceiver "Returns the object that should be used when evaluating 'self' within the presentation. 'nil' is the default value" ^ doItReceiver glamourValue: self entity! ! !GLMTextualPresentation methodsFor: 'accessing' stamp: 'AndreiChis 8/13/2013 15:42'! doItReceiver: aOneArgBlock "The block will be passed the current entity and is expected to return an object .This object will then be returned upon evaluation of 'self' within the presentation." doItReceiver := aOneArgBlock! ! !GLMTextualPresentation methodsFor: 'accessing ports'! selectedText ^ (self pane port: #selectedText) value isNil ifTrue: [self selectedTextBlock value] ifFalse: [(self pane port: #selectedText) value]! ! !GLMTextualPresentation methodsFor: 'accessing ports'! selectedText: anObject (self pane port: #selectedText) value: anObject copy! ! !GLMTextualPresentation methodsFor: 'accessing'! selectedTextBlock ^ selectedTextBlock ifNil: [ [''] ]! ! !GLMTextualPresentation methodsFor: 'accessing'! selectedTextBlock: anObject selectedTextBlock := anObject! ! !GLMTextualPresentation methodsFor: 'accessing' stamp: 'AndreiChis 6/24/2013 10:12'! selectionInterval ^ (self pane port: #selectionInterval) value ! ! !GLMTextualPresentation methodsFor: 'accessing'! selectionInterval: anInterval (self pane port: #selectionInterval) value: anInterval! ! !GLMTextualPresentation methodsFor: 'accessing ports'! text ^ (self pane port: #text) value isNil ifTrue: [self textBlock value] ifFalse: [(self pane port: #text) value]! ! !GLMTextualPresentation methodsFor: 'accessing ports'! text: aString (self pane port: #text) value: aString copy! ! !GLMTextualPresentation methodsFor: 'accessing'! textBlock ^ textBlock! ! !GLMTextualPresentation methodsFor: 'accessing'! textBlock: anObject textBlock := anObject! ! !GLMTextualPresentation methodsFor: 'accessing'! variableBindings ^ (variableBindingsBlock glamourValue: self entity) ifNil: [OrderedCollection new]! ! !GLMTextualPresentation methodsFor: 'accessing'! variableBindings: aBlock ^ variableBindingsBlock := aBlock! ! !GLMMorphPresentation commentStamp: 'TudorGirba 2/4/2011 21:13' prior: 34276019! This presentation offers a means to embed a Morph. It makes sense only for the Morph Renderer.! !GLMMorphPresentation methodsFor: 'rendering'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderMorphPresentation: self! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 4/1/2010 07:15'! acceptsSelection "this flag is used to specify whether the presentation is allowed to populate the selection port or not" ^ acceptsSelection ifNil: [acceptsSelection := true]! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 12/29/2009 02:16'! acceptsSelection: aBoolean acceptsSelection := aBoolean! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:54'! act: aBlock entitled: aString self addAction: ((GLMGenericAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:54'! act: aBlock entitled: aString categorized: anotherString self addAction: ((GLMGenericAction new) action: aBlock; title: aString; category: anotherString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:53'! act: aBlock icon: anIcon entitled: aString self addAction: ((GLMGenericAction new) action: aBlock; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 3/5/2011 23:46'! act: aBlock icon: anIcon on: aCharacter entitled: aString self addAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:53'! act: aBlock on: aCharacter self addAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:53'! act: aBlock on: aCharacter entitled: aString self addAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:54'! act: aBlock on: aCharacter entitled: aString categorized: anotherString self addAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; title: aString; category: anotherString; yourself)! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 2/11/2011 23:04'! actions "These are actions that make sense for the entire presentation." actions ifNil: [actions := OrderedCollection new]. ^ actions! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 11/27/2010 12:37'! actions: aBlock self deprecated: 'use dynamicActionsOnSelection: for contextual actions, and dynamicActions for presentation-wide actions'. ^ self dynamicActionsOnSelection: aBlock ! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! addAction: anAction self actions addLast: anAction! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! addDefaultStatusbarTransmissionFrom: aPane | defaultTransmission | defaultTransmission := GLMTransmission new ensureReplacePresentationsStrategy; addActiveOrigin: (aPane port: #status); destination: (self statusbarPane port: #entity); addPresentation: self statusbarPresentation; yourself. self addTransmission: defaultTransmission.! ! !GLMPresentation methodsFor: 'accessing' stamp: 'cyrilledelaunay 8/9/2011 11:18'! addOpenBrowserAction: anAction self openBrowserActions addLast: anAction! ! !GLMPresentation methodsFor: 'transmitting' stamp: 'DamienCassou 7/19/2011 20:36'! addRawSelectionTransmissionTo: aPortSymbol ^ rawSelectionTransmissions add: ((GLMTransmission new) addActiveOrigin: ((GLMPresentationBoundPort new) name: #rawSelection; presentation: self; yourself); destination: ((GLMPresentationBoundPort new) name: aPortSymbol; presentation: self; yourself))! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/19/2010 18:15'! addSelectionAction: anAction self selectionActions add: anAction! ! !GLMPresentation methodsFor: 'accessing' stamp: 'cyrilledelaunay 8/9/2011 11:18'! addSelectionOpenBrowserAction: anAction self selectionOpenBrowserActions add: anAction! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! addStatusbar self hasStatusbar: true ! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 8/4/2009 15:19'! allActions ^ self actions, self dynamicActions! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 3/25/2013 07:27'! allActionsWithShortcuts ^ (self actions, self selectionActions) select: [ :action | action hasShortcut ]! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/19/2010 18:15'! allSelectionActions ^ self selectionActions, self dynamicActionsOnSelection! ! !GLMPresentation methodsFor: 'scripting' stamp: 'VeronicaUquillas 2/18/2011 15:20'! allowAllNil ^ self useExplicitAllNil! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/18/2009 15:34'! allowNil ^ self useExplicitNotNil! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/6/2009 20:08'! color ^ color! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/6/2009 20:08'! color: aSymbolOrColor color := aSymbolOrColor! ! !GLMPresentation methodsFor: 'accessing values' stamp: 'tg 11/6/2009 20:08'! colorValue ^ self color notNil ifTrue: [ self color glamourValue: self entity ] ifFalse: [ self color ] " self color isSymbol ifTrue: [ Color perform: self color ] ifFalse: [ self color ]"! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! condition ^condition ifNil: [condition := [true]]! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! condition: anObject condition := anObject! ! !GLMPresentation methodsFor: 'copying' stamp: 'TudorGirba 7/11/2011 11:18'! copy "we are overriding the copy method simply to retain the tree of all prototype presentations. this is useful for debugging." | copy | self flag: 'perhaps this should be replaced with smarter analysys mechanisms'. copy := super copy. copy parentPrototype: self. ^ copy! ! !GLMPresentation methodsFor: 'accessing validation' stamp: 'tg 11/15/2009 16:14'! customValidation ^ customValidation! ! !GLMPresentation methodsFor: 'accessing validation' stamp: 'tg 11/15/2009 23:52'! customValidation: aBlock customValidation := aBlock. shouldValidate := true.! ! !GLMPresentation methodsFor: 'validation' stamp: 'TudorGirba 3/5/2011 21:20'! defaultValidate: anObject on: aPort "by default any object is allowed in any port" "override this method in subclasses to specify stronger constraints" ^ true! ! !GLMPresentation methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! display: aBlock self transformation: aBlock! ! !GLMPresentation methodsFor: 'accessing values' stamp: 'tg 8/1/2009 16:49'! displayValue ^ self transformation glamourValue: self entity! ! !GLMPresentation methodsFor: 'validation' stamp: 'tg 11/15/2009 23:46'! doValidate: anObject on: aPort ^ self customValidation isNil ifFalse: [ self customValidation glamourValue: ( anObject asGlamorousMultiValue, aPort name asGlamorousMultiValue, self entity asGlamorousMultiValue) ] ifTrue: [ self defaultValidate: anObject on: aPort ]! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 2/11/2011 23:04'! dynamicActions "These are actions that make sense for the entire presentation. They are dynamic in the sense that they will be evaluated lazily by the renderer" dynamicActionsBlock isNil ifTrue: [ ^ OrderedCollection new ]. ^ dynamicActionsBlock glamourValue: self! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/19/2010 18:27'! dynamicActions: aBlock dynamicActionsBlock := aBlock! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 2/11/2011 23:04'! dynamicActionsOnSelection "These are actions that make sense only in the context of values held in the selection port. They are dynamic in the sense that they will be evaluated lazily by the renderer" selectionDynamicActionsBlock isNil ifTrue: [ ^ OrderedCollection new ]. ^ selectionDynamicActionsBlock glamourValue: self! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/14/2010 18:19'! dynamicActionsOnSelection: aBlock selectionDynamicActionsBlock := aBlock! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'tg 12/29/2009 00:31'! entity ^ (self pane port: #entity) value! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'tg 12/29/2009 00:31'! entity: anObject (self pane port: #entity) value: anObject! ! !GLMPresentation methodsFor: 'testing' stamp: 'TudorGirba 1/31/2011 02:08'! hasActions ^ self allActions notEmpty! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! hasStatusbar ^ statusPane notNil! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! hasStatusbar: aBoolean aBoolean ifTrue: [ statusPane := self addPane: (GLMPane new name: self class defaultStatusbarPane) ] ! ! !GLMPresentation methodsFor: 'testing' stamp: 'tg 1/13/2010 22:28'! hasTitle ^ title notNil! ! !GLMPresentation methodsFor: 'testing' stamp: 'tg 9/30/2009 23:51'! hasTitleIcon ^ self titleIcon notNil! ! !GLMPresentation methodsFor: 'initialize-release' stamp: 'TudorGirba 5/20/2012 23:19'! initialize super initialize. updateActions := OrderedCollection new. rawSelectionTransmissions := IdentitySet new. self addRawSelectionTransmissionTo: #selection! ! !GLMPresentation methodsFor: 'accessing' stamp: 'AndreiChis 6/23/2013 21:46'! initialize: aBlock "aBlock is called when the presentation is placed on a pane as a result of a transmission. It can be used to initialize multiple ports." initializationBlock := aBlock! ! !GLMPresentation methodsFor: 'initialize-release' stamp: 'AndreiChis 6/23/2013 21:40'! initializePresentation initializationBlock isNil ifFalse: [ initializationBlock value: self]! ! !GLMPresentation methodsFor: 'events' stamp: 'tg 2/22/2010 13:11'! innerPortEvent: aPortEvent "Regular presentations do not have inner ports, so the default behaviour is to do nothing"! ! !GLMPresentation methodsFor: 'testing' stamp: 'AndreiChis 8/11/2013 18:40'! matches "answer true iff the presentation matches the current context so that it can be displayed" ^ (self usesImplicitAllNil ifTrue:[ GLMAllNilCondition new glamourValue: self entity ] ifFalse:[ self usesImplicitNotNil ifTrue: [GLMAllNotNilCondition new glamourValue: self entity] ifFalse: [GLMSomeNotNilCondition new glamourValue: self entity] ] ) and: [ (self condition glamourValue: self entity) = true]! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:14'! morphicAct: aBlock entitled: aString self addAction: ((GLMMorphicAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:14'! morphicAct: aBlock icon: anIcon entitled: aString self addAction: ((GLMMorphicAction new) action: aBlock; title: aString; icon: anIcon; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:14'! morphicAct: aBlock on: aCharacter entitled: aString self addAction: ((GLMMorphicAction new) action: aBlock; shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:14'! morphicAct: aBlock on: aCharacter icon: anIcon entitled: aString self addAction: ((GLMMorphicAction new) action: aBlock; shortcut: aCharacter; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:14'! morphicPopulate: aPortSymbol icon: anIcon on: aCharacter entitled: aString with: aBlock self addAction: ((GLMMorphicAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); shortcut: aCharacter; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:15'! morphicSelectionAct: aBlock entitled: aString self addSelectionAction: ((GLMMorphicAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:15'! morphicSelectionAct: aBlock icon: anIcon entitled: aString self addSelectionAction: ((GLMMorphicAction new) action: aBlock; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: '*glamour-morphic-renderer' stamp: 'AndreiChis 12/3/2012 21:15'! morphicSelectionAct: aBlock icon: anIcon on: aCharacter entitled: aString self addSelectionAction: ((GLMMorphicAction new) action: aBlock; shortcut: aCharacter; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'AndreiChis 10/31/2012 09:33'! noActions actions := nil. dynamicActionsBlock := nil.! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 12/29/2009 02:16'! noSelection self acceptsSelection: false! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 9/27/2012 07:08'! noTitle title := nil. titleIcon := nil! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 9/27/2012 22:24'! noTitleIcon titleIcon := nil! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:53'! open: aBlock on: aCharacter entitled: aString self addAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: 'events' stamp: 'tg 5/24/2010 16:53'! outerPortEvent: aPortEvent self announce: (GLMContextChanged new presentation: self; property: aPortEvent portName; value: aPortEvent value; oldValue: aPortEvent oldValue; yourself)! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 7/14/2011 15:39'! pane ^ pane ifNil: [ pane := (GLMPane named: 'root' in: GLMNoBrowser new) addPresentationSilently: self; yourself]! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! pane: aPane pane := aPane! ! !GLMPresentation methodsFor: 'copying' stamp: 'tg 1/11/2010 22:33'! parentPrototype ^ parentPrototype! ! !GLMPresentation methodsFor: 'copying' stamp: 'TudorGirba 2/11/2011 22:59'! parentPrototype: aPresentation "used to keep track of the (prototype) presentation from which the current one was copied" parentPrototype := aPresentation! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:54'! populate: aPortSymbol icon: anIcon entitled: aString with: aBlock self addAction: ((GLMGenericAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 2/4/2011 22:05'! populate: aPortSymbol icon: anIcon on: aCharacter entitled: aString with: aBlock self addAction: ((GLMGenericAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); shortcut: aCharacter; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/19/2010 18:13'! populate: aPortSymbol on: aCharacter entitled: aString with: aBlock self addAction: ((GLMGenericAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 9/25/2010 17:54'! populate: aPortSymbol on: aCharacter with: aBlock self addAction: ((GLMGenericAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); shortcut: aCharacter; yourself)! ! !GLMPresentation methodsFor: 'copying' stamp: 'DamienCassou 7/19/2011 20:06'! postCopy super postCopy. pane := nil. self flag: 'self unregisterFromAllAnnouncements.'. updateActions := updateActions collect: [ :each | (each copy) presentation: self; yourself ]. rawSelectionTransmissions := rawSelectionTransmissions collect: [:each | each copy]. rawSelectionTransmissions do: [:transmission | transmission originReferences do: [:portRef | portRef port presentation: self]]. rawSelectionTransmissions do: [:transmission | transmission destination presentation: self]! ! !GLMPresentation methodsFor: 'printing' stamp: 'DamienCassou 7/3/2011 20:02'! printOn: aStream super printOn: aStream. aStream nextPutAll: '(id='; nextPutAll: self identityHash printString; nextPutAll: ' title='; nextPutAll: self titleValue asString; nextPutAll: ' pane='; nextPutAll: self pane printString; nextPutAll: ')'! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'TudorGirba 9/24/2012 08:10'! rawSelection ^ (self pane port: #rawSelection) value! ! !GLMPresentation methodsFor: 'transmitting' stamp: 'DamienCassou 7/19/2011 20:48'! rawSelectionTransmissionFor: aPortSymbol ifNone: ifNoneBlock ^ rawSelectionTransmissions detect: [ :transmission | transmission destination port name = aPortSymbol ] ifNone: ifNoneBlock! ! !GLMPresentation methodsFor: 'updating' stamp: 'TudorGirba 7/10/2011 12:49'! registerAnnouncements "this method is called from the rendering code" self flag: 'The announcements should potentially be interested in any ports, not just in entity'. updateActions do: [:each | each registerInPresentation ].! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 1/30/2010 23:22'! registeredAnnouncers ^ registeredAnnouncers ifNil: [registeredAnnouncers := OrderedCollection new]! ! !GLMPresentation methodsFor: 'rendering' stamp: 'tg 11/8/2009 00:24'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^aRenderer renderPresentation: self! ! !GLMPresentation methodsFor: 'copying' stamp: 'tg 1/11/2010 22:32'! rootPrototype ^ self parentPrototype isNil ifTrue: [ self ] ifFalse: [ self parentPrototype rootPrototype ] ! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'tg 12/29/2009 00:31'! selection ^ (self pane port: #selection) value! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'DamienCassou 7/19/2011 21:09'! selection: anObject "Tell the pane about the new selection. This method is called when the user changes a view's selection' (e.g., he clicks on an element in a list morph)." self acceptsSelection ifFalse: [^ self]. (self pane port: #rawSelection) value: anObject. rawSelectionTransmissions do: #transmit! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/20/2010 20:15'! selectionAct: aBlock entitled: aString self addSelectionAction: ((GLMGenericAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/20/2010 20:14'! selectionAct: aBlock entitled: aString categorized: anotherString self addSelectionAction: ((GLMGenericAction new) action: aBlock; title: aString; category: anotherString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/20/2010 20:16'! selectionAct: aBlock icon: anIcon entitled: aString self addSelectionAction: ((GLMGenericAction new) action: aBlock; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/20/2010 20:13'! selectionAct: aBlock on: aCharacter self addSelectionAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/19/2010 18:16'! selectionAct: aBlock on: aCharacter entitled: aString self addSelectionAction: ((GLMGenericAction new) action: aBlock; shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 2/11/2011 23:04'! selectionActions "These are actions that make sense only in the context of values held in the selection port." ^ selectionActions ifNil: [ selectionActions := OrderedCollection new ]! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 11/19/2010 18:16'! selectionActions: anObject selectionActions := anObject! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 11/19/2010 18:13'! selectionPopulate: aPortSymbol on: aCharacter entitled: aString with: aBlock self addSelectionAction: ((GLMGenericAction new) action: ((GLMPortUpdater new) portSymbol: aPortSymbol; valueBlock: aBlock; yourself); shortcut: aCharacter; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 12/16/2011 17:40'! selectionSpawn: aBlock entitled: aString "These are actions that return a glamour browser to open at the end." self addSelectionAction: ((GLMSpawnBrowserAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: 'transmitting' stamp: 'DamienCassou 7/19/2011 21:16'! selectionTransformation "this is used for transforming the object before updating the selection" ^ self selectionTransmission transformation ifNil: [#yourself]! ! !GLMPresentation methodsFor: 'transmitting' stamp: 'DamienCassou 7/19/2011 20:11'! selectionTransformation: anObject self selectionTransmission transformation: anObject ! ! !GLMPresentation methodsFor: 'transmitting' stamp: 'DamienCassou 7/19/2011 20:50'! selectionTransmission ^ self rawSelectionTransmissionFor: #selection ifNone: [nil]! ! !GLMPresentation methodsFor: 'scripting' stamp: 'tg 8/25/2009 16:01'! send: aBlock self selectionTransformation: aBlock! ! !GLMPresentation methodsFor: 'scripting' stamp: 'DamienCassou 7/19/2011 20:49'! send: aBlock as: aPortSymbol (self rawSelectionTransmissionFor: aPortSymbol ifNone: [ self addRawSelectionTransmissionTo: aPortSymbol ]) transformation: aBlock! ! !GLMPresentation methodsFor: 'accessing validation' stamp: 'tg 11/15/2009 23:47'! shouldValidate ^ shouldValidate ifNil: [shouldValidate := false]! ! !GLMPresentation methodsFor: 'accessing validation' stamp: 'tg 11/15/2009 23:50'! shouldValidate: aBoolean shouldValidate := aBoolean ! ! !GLMPresentation methodsFor: 'accessing' stamp: 'AndreiChis 5/24/2013 11:44'! sourceContext ^ sourceLink! ! !GLMPresentation methodsFor: 'accessing' stamp: 'AndreiChis 5/24/2013 11:41'! sourceContext: aContext sourceLink := aContext! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 12/16/2011 17:40'! spawn: aBlock entitled: aString "These are actions that return a glamour browser to open at the end." self addAction: ((GLMSpawnBrowserAction new) action: aBlock; title: aString; yourself)! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 12/16/2011 17:40'! spawn: aBlock icon: anIcon entitled: aString self addAction: ((GLMSpawnBrowserAction new) action: aBlock; icon: anIcon; title: aString; yourself)! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'DamienCassou 7/19/2011 21:16'! status: anObject self flag: 'what kind of transformation should we want here?'. (self pane port: #status) value: (self selectionTransformation glamourValue: anObject)! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! statusbarPane ^ statusPane! ! !GLMPresentation methodsFor: 'statusbar' stamp: 'TudorGirba 10/8/2011 18:47'! statusbarPresentation ^ GLMLabelPresentation new! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'tg 12/29/2009 00:31'! strongSelection ^ (self pane port: #strongSelection) value! ! !GLMPresentation methodsFor: 'accessing ports' stamp: 'DamienCassou 7/19/2011 21:16'! strongSelection: anObject (self pane port: #strongSelection) value: (self selectionTransformation glamourValue: anObject)! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 1/14/2010 02:47'! title ^ title! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! title: aStringOrBlock title := aStringOrBlock! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 9/30/2009 23:51'! titleIcon ^ titleIcon! ! !GLMPresentation methodsFor: 'accessing' stamp: 'tg 9/30/2009 23:51'! titleIcon: anObject titleIcon := anObject! ! !GLMPresentation methodsFor: 'accessing values' stamp: 'tg 11/1/2009 22:16'! titleIconValue ^ self titleIcon notNil ifTrue: [ self titleIcon glamourValue: self entity ] ifFalse: [ self titleIcon ]! ! !GLMPresentation methodsFor: 'accessing values' stamp: 'tg 1/14/2010 02:47'! titleValue ^ self title glamourValue: self entity! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! transformation ^transformation ifNil: [transformation := #yourself]! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! transformation: aBlock transformation := aBlock! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 5/3/2010 00:15'! unregisterFromAllAnnouncements "this method should be called every time the presentation is not needed" updateActions do: [ :each | each unregisterFromAllAnnouncements ]! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 8/24/2010 21:40'! update self pane ports do: [:each | (self validate: each value on: each) ifFalse: [each resetValue] ]. self announce: (GLMPresentationUpdated new presentation: self)! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 5/3/2010 01:33'! updateOn: anAnnouncement from: aBlockOrSymbol updateActions add: (GLMSingleUpdateAction new presentation: self; announcement: anAnnouncement; transformation: aBlockOrSymbol; yourself)! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 5/3/2010 01:33'! updateOn: anAnnouncement from: aBlockOrSymbol when: aConditionBlock updateActions add: (GLMSingleUpdateAction new presentation: self; announcement: anAnnouncement; transformation: aBlockOrSymbol; condition: aConditionBlock; yourself)! ! !GLMPresentation methodsFor: 'updating' stamp: 'tg 5/3/2010 01:33'! updateOn: anAnnouncement fromAll: aBlockOrSymbol updateActions add: (GLMMultipleUpdateAction new presentation: self; announcement: anAnnouncement; transformation: aBlockOrSymbol; yourself)! ! !GLMPresentation methodsFor: 'accessing' stamp: 'VeronicaUquillas 2/18/2011 15:14'! useExplicitAllNil implicitAllNil := true! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! useExplicitNotNil implicitNotNil := false! ! !GLMPresentation methodsFor: 'accessing' stamp: 'VeronicaUquillas 2/18/2011 15:15'! useImplicitAllNil implicitAllNil := true! ! !GLMPresentation methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! useImplicitNotNil implicitNotNil := true! ! !GLMPresentation methodsFor: 'testing' stamp: ' 4/5/09 22:18'! usesExplicitNotNil ^self usesImplicitNotNil not! ! !GLMPresentation methodsFor: 'testing' stamp: 'VeronicaUquillas 2/18/2011 15:25'! usesImplicitAllNil ^implicitAllNil ifNil: [implicitAllNil := false ]! ! !GLMPresentation methodsFor: 'testing' stamp: ' 4/5/09 22:18'! usesImplicitNotNil ^implicitNotNil ifNil: [implicitNotNil := true]! ! !GLMPresentation methodsFor: 'validation' stamp: 'TudorGirba 2/11/2011 22:45'! validate: anObject on: aPort "This gets triggered when aPort wants to be changed. The presentation has a chance to veto the value." self shouldValidate ifFalse: [ ^ true ]. ^ self doValidate: anObject on: aPort.! ! !GLMPresentation methodsFor: '*glamour-tools' stamp: 'JurajKubelka 5/28/2013 13:19'! viewNested | view | view := ROMondrianViewBuilder new. self viewNestedOn: view. ^ view open setLabel: 'Nested'.! ! !GLMPresentation methodsFor: '*glamour-tools' stamp: 'TudorGirba 7/10/2011 00:50'! viewNestedOn: view view shape label text: [:each | each class name removePrefix: 'GLM']. view node: self! ! !GLMPresentation methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2012 23:18'! watcherPane ^ nil! ! !GLMPresentation methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! when: aBlock self condition: aBlock! ! !GLMPresentation methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! whenKindOf: aClass self when: [:each | each isKindOf: aClass]! ! !GLMPresentation methodsFor: 'scripting' stamp: 'TudorGirba 7/29/2012 08:50'! with: aBlock aBlock value: self! ! !GLMPresentation methodsFor: 'enumerating' stamp: 'TudorGirba 7/10/2011 01:03'! withAllPanes | result | result := OrderedCollection new. self withAllPanesAndPresentationsDo: [:each | (each isKindOf: GLMPane) ifTrue: [ result add: each ]]. ^ result! ! !GLMPresentation methodsFor: 'enumeration' stamp: 'TudorGirba 7/9/2011 20:00'! withAllPanesAndPresentationsDo: aBlock ^ aBlock value: self! ! !GLMPresentation methodsFor: 'enumerating' stamp: 'TudorGirba 7/9/2011 22:28'! withAllPresentations | result | result := OrderedCollection new. self withAllPanesAndPresentationsDo: [:each | (each isKindOf: GLMPresentation) ifTrue: [ result add: each ]]. ^ result! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 5/7/2012 12:09'! bitmap ^ self view bitmap ! ! !GLMRoassalPresentation methodsFor: 'scripting' stamp: 'TudorGirba 10/13/2013 21:32'! defaultActions self act: [ :roassal | ROExportPNGCommand new executeOn: roassal view raw ] entitled: 'Export as PNG'; act: [ :roassal | ROExportSVGCommand new executeOn: roassal view raw ] entitled: 'Export as SVG'; act: [ :roassal | ROZoomOutMove new on: roassal view raw ] icon: GLMUIThemeExtraIcons glamorousZoomOut entitled: 'Zoom out'; act: [ :roassal | ROZoomInMove new on: roassal view raw ] icon: GLMUIThemeExtraIcons glamorousZoomIn entitled: 'Zoom in'! ! !GLMRoassalPresentation methodsFor: 'initialize-release' stamp: 'TudorGirba 6/5/2013 23:11'! initialize super initialize. shouldPopulateSelection := true. self defaultActions! ! !GLMRoassalPresentation methodsFor: 'scripting' stamp: 'TudorGirba 5/7/2012 14:10'! painting: anObject paintingBlock := anObject! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 5/7/2012 14:10'! paintingBlock ^ paintingBlock! ! !GLMRoassalPresentation methodsFor: 'rendering' stamp: 'TudorGirba 5/7/2012 14:13'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderRoassalPresentation: self! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 7/6/2013 23:13'! renderOn: aView self flag: 'find a smarter solution that does not depend on isKindOf:'. self paintingBlock glamourValue: ( (self entity isKindOf: GLMMultiValue) ifTrue: [(GLMMultiValue with: aView) , self entity , (GLMMultiValue with: self)] ifFalse: [GLMMultiValue with: aView with: self entity with: self]). self flag: 'This should be the responsibility of the the view'. aView applyLayout. self shouldPopulateSelection ifTrue: [ aView raw allElementsDo: [:each | each on: ROMouseClick do: [:event | self selection: each model ]] ]. self view: aView! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 9/9/2012 21:09'! shouldPopulateSelection "this flag tells the presentation whether clicking on some element inside the view should populate the selection port from the pane containing the presentation" ^ shouldPopulateSelection! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 9/9/2012 20:16'! shouldPopulateSelection: anObject shouldPopulateSelection := anObject! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 6/5/2012 17:11'! view ^ view ifNil: [view := ROMondrianViewBuilder new]! ! !GLMRoassalPresentation methodsFor: 'accessing' stamp: 'TudorGirba 5/7/2012 14:11'! view: anObject view := anObject! ! !GLMSpecPresentation methodsFor: 'as yet unclassified' stamp: 'TudorGirba 4/3/2013 16:48'! renderGlamorouslyOn: aRenderer self registerAnnouncements. ^ aRenderer renderSpecPresentation: self! ! !GLMTransmission commentStamp: 'DamienCassou 7/19/2011 16:53' prior: 34276187! A GLMTransmission models the connection between multiple origin ports and one destination port. Whenever an origin port changes the value, the corresponding transmissions are triggered by the browser. The result of triggering a transmission is the setting of the value in the destination port. The transmissionStrategy can add further different semantics to this behavior. A transmission takes place in a context. The context is started every time a new value is set from outside. Afterwards, the context is preserved internally. This is important for braking possible loops of transmission propagation. There are two kind of origins for a transmission, active and passive ones. A change of value in an active origin will trigger the transmissions originating from it. A change of value in a passive origin will not trigger the transmission. However, a value in a passive origin is still part of the transmission value.! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 12:24'! activeOrigins ^(self originReferences select: [:each | each isActive]) collect: [:each | each port]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:07'! addActiveOrigin: aPort ^ self originReferences add: ((GLMOriginPortReference new) port: aPort; beActive; yourself)! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:07'! addPassiveOrigin: aPort ^ self originReferences add: ((GLMOriginPortReference new) port: aPort; bePassive; yourself)! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:53'! addPresentation: aPresentation self transmissionStrategy addPresentation: aPresentation! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 17:07'! addPresentations: aCollection self transmissionStrategy addPresentations: aCollection! ! !GLMTransmission methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 12:57'! andShow: aBlock "This method accepts a block with one argument. The block will be evaluated with an instance of GLMCompositePresentation. The block should construct the presentations that go in the composite presentation. The composite presentation will be the one that will get installed in the target pane once the transmission triggers. This method is meant to be used in a Glamour script. " self ensureReplacePresentationsStrategy. self transmissionStrategy presentationsFactory: aBlock. self origins isEmpty ifTrue: [ self from: #outer port: #entity ]! ! !GLMTransmission methodsFor: 'scripting' stamp: 'AndreiChis 5/29/2013 12:59'! andShowIfNone: aBlock "This method accepts a block with one argument. The block will be evaluated with an instance of GLMCompositePresentation. The block should construct the presentations that go in the composite presentation. The composite presentation will be the one that will get installed in the target pane once the transmission triggers. The particularity of this method is that the presentation will get installed in the target pane only if the target pane has no presentation already. This method is meant to be used in a Glamour script. " self ensurePresentIfNoneStrategy. self transmissionStrategy presentationsFactory: aBlock. self origins isEmpty ifTrue: [ self from: #outer port: #entity ]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/5/2010 14:52'! browser ^ browser! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/5/2010 14:52'! browser: anObject browser := anObject! ! !GLMTransmission methodsFor: 'copying' stamp: 'tg 12/30/2009 02:06'! changePortsAccordingToPaneMapping: newPanesMapping "newPanesMapping is a dictionary with keys given by old panes and values by new panes" self destination: ((newPanesMapping at: self destination pane) port: self destination name). ! ! !GLMTransmission methodsFor: 'copying' stamp: 'lr 6/4/2010 14:04'! changePortsAccordingToPaneMapping: newPanesMapping fromOldBrowser: aBrowser toNewBrowser: anotherBrowser | newPort | "newPanesMapping is a dictionary with keys given by old panes and values by new panes" self destination: (self destination copyAccordingToPaneMapping: newPanesMapping inNewBrowser: anotherBrowser). self originReferences do: [:each | newPort := each port copyAccordingToPaneMapping: newPanesMapping inNewBrowser: anotherBrowser. each port: newPort ]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/31/2010 01:39'! condition ^ condition! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/31/2010 01:22'! condition: anObject condition := anObject! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'jre 9/18/2009 19:17'! context context ifNil: [context := OrderedCollection new]. ^context! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'jre 9/18/2009 19:46'! context: aContext context := aContext! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 12/30/2009 02:07'! destination ^destination! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 12/30/2009 02:07'! destination: aPort destination := aPort! ! !GLMTransmission methodsFor: 'accessing' stamp: 'DamienCassou 7/9/2011 20:20'! ensurePresentIfNoneStrategy self transmissionStrategy class = GLMPresentIfNoneStrategy ifFalse: [ self transmissionStrategy: (GLMPresentIfNoneStrategy of: self) ]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'DamienCassou 7/9/2011 20:19'! ensureReplacePresentationsStrategy self transmissionStrategy class = GLMReplacePresentationsStrategy ifFalse: [ self transmissionStrategy: (GLMReplacePresentationsStrategy of: self) ]! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 5/1/2011 01:56'! from: aPort "Ideally this method would be implemented as ^ self from: aPaneSymbol port: #selection. The problem is that beforehand we only had from: which could receive either a symbol for the pane, or an association for the port. This was bad, and now Glamour offers from:port:, but there are still legacy cases of from: being called with an association." ^ self addActiveOrigin: (self browser resolveOriginPort: aPort)! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 11/3/2010 13:37'! from: aPaneSymbol port: aPortSymbol ^ self from: (GLMPortIdentifier pane: aPaneSymbol port: aPortSymbol)! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 2/23/2011 23:53'! from: aPaneSymbol port: aPortSymbol transformed: aBlock ^ (self from: (GLMPortIdentifier pane: aPaneSymbol port: aPortSymbol)) transformation: aBlock! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 1/14/2010 23:26'! from: aPort transformed: aBlock ^ (self addActiveOrigin: (self browser resolveOriginPort: aPort)) transformation: aBlock! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 5/20/2012 00:55'! fromOutside: aPortSymbol self deprecated: 'Use fromOutsidePort: instead'. ^ self fromOutsidePort: aPortSymbol! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 10/2/2011 21:39'! fromOutsideEntityPort ^ self fromOutsidePort: #entity! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 10/2/2011 21:40'! fromOutsideEntityPortTransformed: aBlock ^ self fromOutsidePort: #entity transformed: aBlock! ! !GLMTransmission methodsFor: 'scripting' stamp: 'DamienCassou 7/10/2011 10:53'! fromOutsidePort: aPortSymbol ^ self from: #outer port: aPortSymbol! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 10/2/2011 21:40'! fromOutsidePort: aPortSymbol transformed: aBlock ^ self from: #outer port: aPortSymbol transformed: aBlock! ! !GLMTransmission methodsFor: 'initialize-release' stamp: 'tg 5/24/2010 17:19'! initialize super initialize. transmissionStrategy := GLMNoStrategy new. condition := true! ! !GLMTransmission methodsFor: 'testing' stamp: 'AndreiChis 8/11/2013 18:40'! meetsCondition | originValues | originValues := self originReferences size = 1 ifTrue: [ self originReferences first value ] ifFalse: [ GLMMultiValue withAll: (self originReferences collect: [:each | each value]) ]. ^ self condition glamourValue: originValues! ! !GLMTransmission methodsFor: 'private accessing' stamp: 'DamienCassou 7/9/2011 22:43'! originReferences "Returns the set of ports (instances of PortReference) the transmission receives its data from" ^ origins ifNil: [origins := OrderedCollection new]! ! !GLMTransmission methodsFor: 'testing' stamp: 'tg 1/31/2010 01:28'! originatesAt: aPort ^ (self activeOrigins includes: aPort) and: [self meetsCondition]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 12:20'! origins ^ self originReferences collect: [:each | each port]! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 12:23'! passiveOrigins ^(self originReferences select: [:each | each isPassive]) collect: [:each | each port]! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 2/20/2010 18:21'! passivelyFrom: aPort ^ self addPassiveOrigin: (self browser resolveOriginPort: aPort)! ! !GLMTransmission methodsFor: 'scripting' stamp: 'DamienCassou 7/21/2011 10:48'! passivelyFrom: aPaneSymbol port: aPortSymbol ^ self passivelyFrom: (GLMPortIdentifier pane: aPaneSymbol port: aPortSymbol)! ! !GLMTransmission methodsFor: 'copying' stamp: 'AndreiChis 5/29/2013 13:38'! postCopy origins := self originReferences collect: [:each | each copy ]. destination := destination copy. transmissionStrategy := transmissionStrategy copy. transmissionStrategy transmission: self! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 17:11'! presentations ^ self transmissionStrategy presentations! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/15/2010 02:50'! presentations: aCompositePresentation self transmissionStrategy presentations: aCompositePresentation! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'TudorGirba 4/18/2011 19:52'! printOn: aStream aStream nextPutAll: self class name; nextPutAll: ' (origins='; nextPutAll: self origins printString; nextPutAll: ' destination='; nextPutAll: self destination printString; nextPut: $) ! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 5/1/2011 01:57'! to: aPort "Ideally this method would be implemented as ^ self to: aPaneSymbol port: #entiity. The problem is that beforehand we only had from: which could receive either a symbol for the pane, or an association for the port. This was bad, and now Glamour offers to:port:, but there are still legacy cases of to: being called with an association." ^ self destination: (self browser resolveDestinationPort: aPort)! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 11/3/2010 13:36'! to: aPaneSymbol port: aPortSymbol ^ self to: (GLMPortIdentifier pane: aPaneSymbol port: aPortSymbol)! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 5/20/2012 00:55'! toOutside: aPortSymbol self deprecated: 'Use toOutsidePort: instead'. ^ self toOutsidePort: aPortSymbol! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 12/2/2010 20:09'! toOutsidePort: aPortSymbol ^ self to: #outer->aPortSymbol! ! !GLMTransmission methodsFor: 'scripting' stamp: 'TudorGirba 5/20/2012 00:51'! toWatcher "" ^ self destination: (self browser watcherPane port: #entity)! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:25'! transformation ^ transformation! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:14'! transformation: anObject transformation := anObject! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 1/31/2010 01:52'! transformed: aBlock self transformation: aBlock! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:43'! transmissionStrategy ^ transmissionStrategy! ! !GLMTransmission methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:44'! transmissionStrategy: anObject transmissionStrategy := anObject! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'tg 1/14/2010 13:09'! transmit self transmitIn: GLMTransmissionContext new! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'TudorGirba 4/22/2012 23:09'! transmitIn: aContext self flag: 'The transmitIt: and receive:in: both end up calling notingPresentationChangeDo:. So they should be handled by a surrounding notingPresentationChangeDo:. However, by doing that it seems that we break the morphic updating. No idea why'. self destination notingPresentationChangeDo: [ self transmissionStrategy transmitIn: aContext. self destination receive: self in: aContext ]. self browser notNil ifTrue: [ self browser announce: GLMTransmissionTriggered new ]! ! !GLMTransmission methodsFor: 'transmitting' stamp: 'AndreiChis 8/11/2013 18:40'! value | originalValue | originalValue := self originReferences size = 1 ifTrue: [ self originReferences first value ] ifFalse: [ GLMMultiValue withAll: (self originReferences collect: [:each | each value]) ]. ^ self transformation isNil ifTrue: [ originalValue ] ifFalse: [ self transformation glamourValue: originalValue ]! ! !GLMTransmission methodsFor: 'scripting' stamp: 'tg 1/31/2010 01:44'! when: aBlock self condition: aBlock! ! !GLMTransmission methodsFor: 'scripting' stamp: 'DamienCassou 7/20/2011 07:42'! whenKindOf: aClass self when: [:each | each isKindOf: aClass]! ! !GLMButtonModel methodsFor: 'actions' stamp: 'tg 11/8/2009 21:25'! buttonLabel ^ self glamourAction title! ! !GLMButtonModel methodsFor: 'actions' stamp: 'tg 11/8/2009 21:35'! execute self glamourAction actOn: self glamourPresentation! ! !GLMButtonModel methodsFor: 'accessing' stamp: 'tg 11/8/2009 21:24'! glamourAction ^ glamourAction! ! !GLMButtonModel methodsFor: 'accessing' stamp: 'tg 11/8/2009 21:24'! glamourAction: anObject glamourAction := anObject! ! !GLMMorphicModel methodsFor: 'callbacks' stamp: 'TudorGirba 11/25/2010 13:20'! allKeystrokeActions ^ (self glamourPresentation allActions, self glamourPresentation allSelectionActions) select: [ :action | action hasShortcut ]! ! !GLMMorphicModel methodsFor: 'callbacks' stamp: 'tg 11/19/2010 18:18'! allMenuActions ^ self glamourPresentation allSelectionActions select: [:action | action hasTitle ]! ! !GLMMorphicModel methodsFor: 'callbacks' stamp: 'jre 7/31/2009 09:48'! executeMenuAction: anAction self announce: (GLMMenuItemSelected action: anAction)! ! !GLMMorphicModel methodsFor: 'accessing' stamp: 'tg 8/4/2009 14:23'! glamourPresentation ^ glamourPresentation! ! !GLMMorphicModel methodsFor: 'accessing' stamp: 'tg 8/4/2009 14:23'! glamourPresentation: anObject glamourPresentation := anObject! ! !GLMMorphicModel methodsFor: 'initialization' stamp: 'tg 8/4/2009 15:26'! initialize super initialize.! ! !GLMMorphicModel methodsFor: 'callbacks' stamp: 'TudorGirba 3/24/2013 12:56'! keystroke: anEvent from: aMorph | action | action := self allKeystrokeActions detect: [:a | a shortcut = anEvent keyCharacter] ifNone: [nil]. action ifNotNil: [ self announce: (GLMKeyStroke action: action). ^ true ]. ^ false! ! !GLMMorphicModel methodsFor: 'callbacks' stamp: 'cyrilledelaunay 8/9/2011 14:17'! menu: aMenuMorph | subMenus targetMenuMorph subMenu | subMenus := Dictionary new. self allMenuActions do: [ :action | targetMenuMorph := action category notNil ifTrue: [ subMenus at: action category ifAbsentPut: [ subMenu := MenuMorph new. aMenuMorph add: action category subMenu: subMenu. subMenu ] ] ifFalse: [ aMenuMorph ]. targetMenuMorph add: action title target: self selector: #executeMenuAction: argument: action ]. ^ aMenuMorph! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'TudorGirba 6/2/2013 22:03'! announcer ^ announcer ifNil: [ announcer := Announcer new weak ]! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'TudorGirba 6/2/2013 22:03'! announcer: anObject announcer := anObject! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'TudorGirba 6/2/2013 22:02'! getText ^ self glamourPresentation displayValue! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'AlainPlantec 9/18/2013 21:56'! primarySelectionInterval ^ primarySelectionInterval! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'AlainPlantec 9/18/2013 21:57'! primarySelectionInterval: anInterval primarySelectionInterval := anInterval! ! !GLMRubricTextModel methodsFor: 'accessing' stamp: 'AlainPlantec 8/2/2013 14:47'! setText: aText from: aRubScrolledTextMorph self glamourPresentation text: aText. ^true! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! addVariableBinding: anAssociation self variableBindings at: anAssociation key put: anAssociation value! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! bindingOf: aSymbol ^ self variableBindings associationAt: aSymbol ifAbsent: [nil]! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'AndreiChis 8/13/2013 15:40'! doItContext ^ self glamourPresentation doItContext ! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! doItReceiver ^ self glamourPresentation doItReceiver ! ! !GLMSmalltalkCodeModel methodsFor: 'completion' stamp: 'TudorGirba 9/20/2011 23:33'! guessTypeForName: aString ^ nil! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! hasBindingOf: aSymbol ^ self variableBindings includesKey: aSymbol! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! hasBindingThatBeginsWith: aString ^ self variableBindings keys anySatisfy: [:each | each beginsWith: aString]! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! highlightSmalltalk ^ highlightSmalltalk! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! highlightSmalltalk: anObject highlightSmalltalk := anObject! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! highlightSmalltalkContext ^ highlightSmalltalkContext! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! highlightSmalltalkContext: anObject highlightSmalltalkContext := anObject! ! !GLMSmalltalkCodeModel methodsFor: 'completion' stamp: 'EstebanLorenzano 4/18/2012 09:57'! isCodeCompletionAllowed ^true! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! selectedClassOrMetaClass ^ self highlightSmalltalkContext! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! shoutAboutToStyle: aPluggableShoutMorph self highlightSmalltalk ifFalse: [^ false]. self highlightSmalltalkContext notNil ifTrue: [ aPluggableShoutMorph classOrMetaClass: self highlightSmalltalkContext]. ^ true! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! variableBindings ^ variableBindings ifNil: [variableBindings := Dictionary new]! ! !GLMSmalltalkCodeModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! variableBindings: anObject variableBindings := anObject! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'TudorGirba 2/14/2012 08:42'! accept: aText notifying: anObject aText asString trimBoth ifEmpty: [^self]. self text: aText. self changed: #text! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'TudorGirba 3/24/2013 12:56'! keystroke: anEvent from: aMorph anEvent anyModifierKeyPressed ifTrue: [ ^ super keystroke: anEvent from: aMorph ]. self glamourPresentation text: self text. ^ false! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'tg 8/4/2009 15:31'! menu: aMorphMenu shifted: b ^ self menu: aMorphMenu! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'tg 5/14/2009 22:10'! selectSilently: anIndex self changed: #selection! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'tg 8/22/2010 13:14'! selection ^ self glamourPresentation selectionInterval ifNil: [1 to: 0]! ! !GLMTextModel methodsFor: 'callbacks' stamp: 'david_roethlisberger 2/27/2009 11:50'! text ^text! ! !GLMTextModel methodsFor: 'accessing' stamp: 'TudorGirba 9/20/2011 23:33'! text: aTextOrString text := aTextOrString. self glamourPresentation ifNotNil: [ :presentation | presentation text: text ]! ! !ROAnnouncer commentStamp: '' prior: 34277163! A ROAnnouncer is an object that receive and emit events. Each roassal element has an roannouncer. ! !ROAnnouncer methodsFor: 'announce' stamp: 'AlexandreBergel 9/2/2012 20:25'! announce: event (self isForwarded: event) ifTrue: [ self sendToParent: event ] ifFalse: [ super announce: event ] ! ! !ROAnnouncer methodsFor: 'forwarding'! forward self forward: ROEvent! ! !ROAnnouncer methodsFor: 'forwarding'! forward: anEventClass forwarding ifNil: [ forwarding := IdentitySet new ]. forwarding add: anEventClass! ! !ROAnnouncer methodsFor: 'testing' stamp: 'AlexandreBergel 9/2/2012 20:24'! isForwarded: anEventClass anEventClass isBehavior ifFalse: [ ^ self isForwarded: anEventClass class ]. forwarding ifNil: [ ^ false ]. ^ forwarding anySatisfy: [ :c | (c == anEventClass) or: [ anEventClass inheritsFrom: c ] ] ! ! !ROAnnouncer methodsFor: 'testing'! isForwarder ^ forwarding notNil and: [ forwarding notEmpty ]! ! !ROAnnouncer methodsFor: 'announce'! sendToParent: event "Do nothing if an event class" event isBehavior ifTrue: [ ^ self ]. event hasElement ifTrue: [ event element parentAnnounce: event ]! ! !ROAnnouncer methodsFor: '*roassalmorphic' stamp: 'AlexandreBergel 9/2/2012 21:11'! unsubscribeForEvent: aEventClass ^ registry unsubscribeForEvent: aEventClass! ! !CECollectionExtensionTest methodsFor: 'collect as set' stamp: 'stephane.ducasse 10/14/2008 22:15'! testCollectAsSet "self debug: #testCollectAsSet" self assert: ((#() collectAsSet: [:each | each odd]) = Set new). self assert: (#(1 2 3 4 5 6) collectAsSet: [:each | each odd]) = (Set with: true with: false). self assert: (#(1 3 5 7 9 11) collectAsSet: [:each | each odd]) = (Set with: true). self assert: (#(1 2 3 4 5 4 3 2 1) collectAsSet: [:each | each]) = (1 to: 5) asSet. ! ! !CECollectionExtensionTest methodsFor: 'collect as set' stamp: 'stephane.ducasse 10/14/2008 22:08'! testCollectAsSetUsingSymbol "self debug: #testCollectAsSetUsingSymbol" self assert: ((#() collectAsSet: #odd) = Set new). self assert: (#(1 2 3 4 5 6) collectAsSet: #odd) = (Set with: true with: false). self assert: (#(1 3 5 7 9 11) collectAsSet: #odd) = (Set with: true).! ! !CECollectionExtensionTest methodsFor: 'flatten' stamp: 'simondenier 2/4/2011 22:53'! testDeepFlatten self assert: #(1 2 3) equals: #((1) (2) (3)) deepFlatten. self assert: #(1 2 3 1 2) equals: #((1 2) (3 1 2)) deepFlatten. ! ! !CECollectionExtensionTest methodsFor: 'flatten' stamp: 'simondenier 2/4/2011 23:01'! testDeepFlattenIsRecursive self assert: #(1 2 4 5 3) equals: #((1 2) ((4 5) 3)) deepFlatten.! ! !CECollectionExtensionTest methodsFor: 'flatten' stamp: 'simondenier 2/4/2011 23:04'! testDeepFlattenOnFlatCollection self assert: #(1 2 4) equals: #(1 2 4) deepFlatten. self assert: #(5 3) equals: #(5 ((3))) deepFlatten.! ! !CECollectionExtensionTest methodsFor: 'flatten' stamp: 'simondenier 2/4/2011 23:03'! testDeepFlattenOnString "don't flatten strings" self assert: #(a b c d e) equals: #((a b) ((c d) e)) deepFlatten. self assert: #('foo' 'bar' 'zorg') equals: #(('foo' ('bar')) 'zorg') deepFlatten! ! !CECollectionExtensionTest methodsFor: 'as yet unclassified' stamp: 'tg 7/10/2010 16:29'! testDetectIfOne | element result | result := #(1 2 3) detect: [:each | each = 2] ifOne: [:theOne | element := theOne ]. self assert: element = 2. self assert: result = 2. element := nil. result := #(1 2 3) detect: [:each | each = 4] ifOne: [:theOne | element := theOne ]. self assert: element isNil. self assert: result isNil.! ! !CECollectionExtensionTest methodsFor: 'as yet unclassified' stamp: 'tg 7/10/2010 16:27'! testDetectIfOneIfNone | element | #(1 2 3) detect: [:each | each = 2] ifOne: [:theOne | element := theOne ] ifNone: [element := nil]. self assert: element = 2. #(1 2 3) detect: [:each | each = 4] ifOne: [:theOne | element := theOne ] ifNone: [element := nil]. self assert: element isNil. ! ! !CECollectionExtensionTest methodsFor: 'flat collect' stamp: 'stephane.ducasse 10/14/2008 23:06'! testFlatCollect "self debug: #testFlatCollect" ! ! !CECollectionExtensionTest methodsFor: 'flat collect' stamp: 'simon.denier 6/4/2010 17:50'! testFlatCollectArray "self debug: #testFlatCollectArray" self assert: ((#((1 2) (3 4) (5 3)) flatCollect: [ :each | each ]) = #(1 2 3 4 5 3)). self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each | each]) = #(1 2 2 3 1 3 4)). self assert: ((#((1 2) (2 3) () ()) flatCollect: [:each | each]) = #(1 2 2 3)). self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each| Array with: each]) = #(#(1 2) #(2 3) #(1 3 4))). self assert: ((#((1 2) (2 3) (1 3 4)) flatCollect: [:each| Set with: each]) = #(#(1 2) #(2 3) #(1 3 4))). ! ! !CECollectionExtensionTest methodsFor: 'flat collect' stamp: 'simon.denier 6/4/2010 17:51'! testFlatCollectSet "self debug: #testFlatCollectSet" self assert: ((#((1 2) (1 2) (1 3 4)) asSet flatCollect: [:each | each]) = #(1 1 2 3 4) asSet). self assert: ((#() asSet flatCollect: [:each]) = #() asSet). self assert: ((#((1 2) () (1 3 4)) asSet flatCollect: [:each | each]) = #(1 1 2 3 4) asSet). self assert: ((#((1 2) #((99)) (1 3 4)) asSet flatCollect: [:each | each]) = #(1 1 2 3 4 (99)) asSet). self assert: ((#((1 2) #(()) (1 3 4)) asSet flatCollect: [:each | each]) = #(1 1 2 3 4 ()) asSet).! ! !CECollectionExtensionTest methodsFor: 'flatten' stamp: 'simondenier 2/4/2011 22:51'! testFlatten self assert: #(1 2 3) equals: #((1) (2) (3)) flatten. self assert: #(1 2 3 1 2) equals: #((1 2) (3 1 2)) flatten. self assert: #(a b (c d)) equals: #((a b) ((c d))) flatten. self should: [ #((1 2) 3) flatten ] raise: Error.! ! !CECollectionExtensionTest methodsFor: 'groupedBy' stamp: 'stephane.ducasse 10/14/2008 22:25'! testGroupedBy "self debug: #testGroupedBy" | res | res := #(1 2 3 4 5) asOrderedCollection groupedBy: [:each | each odd]. self assert: (res at: true) = #(1 3 5) asOrderedCollection. self assert: (res at: false) = #(2 4) asOrderedCollection! ! !CECollectionExtensionTest methodsFor: 'groupedBy' stamp: 'stephane.ducasse 10/14/2008 22:23'! testGroupedByArray "self debug: #testGroupedByArray" | res | res := #(1 2 3 4 5) groupedBy: [:each | each odd]. self assert: (res at: true) = #(1 3 5). self assert: (res at: false) = #(2 4)! ! !CECollectionExtensionTest methodsFor: 'groupedBy' stamp: 'stephane.ducasse 10/14/2008 22:24'! testGroupedBySet "self debug: #testGroupedBySet" | res | res := #(1 2 3 4 5 3 4 5) asSet groupedBy: [:each | each odd]. self assert: (res at: true) = #(1 3 5) asSet. self assert: (res at: false) = #(2 4) asSet! ! !CECollectionExtensionTest methodsFor: 'symbol - value' stamp: 'stephane.ducasse 10/14/2008 22:10'! testSymbolInPlaceOfBlock "self debug: #testSymbolInPlaceOfBlock" self assert: (#(1 2 3 4) collect: #odd) = #(true false true false). self assert: (#(1 2 3 4) select: #odd) = #(1 3).! ! !CESequenceableCollectionExtensionTest methodsFor: 'tests' stamp: 'TudorGirba 2/25/2012 18:19'! testPairsSimilarityWith self assert: ('1234' pairsSimilarityWith: '2234') equals: (2/3). self assert: ('1234' pairsSimilarityWith: '123') equals: (4/5). self assert: ('1234' pairsSimilarityWith: '5678') equals: 0! ! !CEStringExtensionTest methodsFor: 'tests' stamp: 'TudorGirba 7/19/2011 19:59'! testIntervalFromStartLineStartColumnToEndLineEndColumn | string | string := '123 56 89'. self assert: (string intervalFromStartLine: 1 startColumn: 1 toEndLine: 1 endColumn: 2) = (1 to: 2). self assert: (string intervalFromStartLine: 2 startColumn: 2 toEndLine: 3 endColumn: 2) = (6 to: 9)! ! !CEStringExtensionTest methodsFor: 'tests' stamp: 'TudorGirba 11/23/2011 16:14'! testIntervalOfLine | string | string := '123 56 89'. self assert: (string intervalOfLine: 1) = (1 to: 4). self assert: (string intervalOfLine: 2) = (5 to: 7). self assert: (string intervalOfLine: 3) = (8 to: 9)! ! !CEStringExtensionTest methodsFor: 'tests' stamp: 'TudorGirba 1/19/2012 14:08'! testIntervalOfLineCorrespondingToIndex | string | string := '123 56 89'. self assert: (string intervalOfLineCorrespondingToIndex: 1) = (1 to: 4). self assert: (string intervalOfLineCorrespondingToIndex: 7) = (5 to: 7). self assert: (string intervalOfLineCorrespondingToIndex: 9) = (8 to: 9)! ! !CEStringExtensionTest methodsFor: 'tests' stamp: 'tg 6/27/2010 13:06'! testPiecesCutWhereCamelCase self assert: ('' piecesCutWhereCamelCase) isEmpty. self assert: ('fBar' piecesCutWhereCamelCase) asArray = #('f' 'Bar'). self assert: ('fooBar' piecesCutWhereCamelCase) asArray = #('foo' 'Bar'). self assert: ('FOOBar') piecesCutWhereCamelCase asArray = #('FOO' 'Bar'). self assert: ('fooBar1' piecesCutWhereCamelCase) asArray = #('foo' 'Bar' '1'). self assert: ('FOOBar12AndSomething') piecesCutWhereCamelCase asArray = #('FOO' 'Bar' '12' 'And' 'Something').! ! !GLMMorphicSpotterTest methodsFor: 'as yet unclassified' stamp: 'DamienCassou 12/3/2012 18:15'! creation | composite classRequest methodRequest thirdRequest | composite := GLMSpotterRequest new. classRequest := GLMSingleSpotterRequest new prompt: 'Find Class'; searchBlock: [ :string | Smalltalk allClassesAndTraits select: [:each | string, '*' match: each name] ]; labelBlock: [ :class | class name ]"; iconBlock: [ :class | class browserIcon ]". methodRequest := GLMSingleSpotterRequest new prompt: 'Object Selectors'; searchBlock: [ :string | Object selectors select: [:e| string, '*' match: e asString] ]; labelBlock: [ :e | e ]. thirdRequest := GLMSingleSpotterRequest new prompt: 'Other Selectors'; searchBlock: [ :string | Class selectors select: [:e| string, '*' match: e asString] ]; labelBlock: [ :e | e ]. (composite add: classRequest; add: methodRequest; add: thirdRequest; signal) inspect.! ! !PPAbstractParserTest class methodsFor: 'testing' stamp: 'lr 1/12/2011 21:23'! isAbstract ^ self name = #PPAbstractParserTest! ! !PPAbstractParserTest class methodsFor: 'accessing' stamp: 'lr 6/12/2010 08:22'! packageNamesUnderTest ^ #('PetitParser' 'PetitTests')! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'DamienPollet 8/11/2011 01:50'! assert: aParser fail: aCollection ^ self assert: aParser fail: aCollection end: 0! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'DamienPollet 8/11/2011 01:49'! assert: aParser fail: aCollection end: anInteger | stream result | self assert: aParser isPetitParser description: 'Parser invalid'. stream := aCollection asPetitStream. result := aParser parse: stream. self assert: result isPetitFailure description: 'Parser did not fail'. self assert: stream position = anInteger description: 'Parser failed at wrong position'. ^ result! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'DamienPollet 8/11/2011 01:49'! assert: aParser parse: aCollection ^ self assert: aParser parse: aCollection to: nil end: aCollection size ! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'DamienPollet 8/11/2011 01:49'! assert: aParser parse: aCollection end: anInteger ^ self assert: aParser parse: aCollection to: nil end: anInteger! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'DamienPollet 8/11/2011 01:49'! assert: aParser parse: aCollection to: anObject ^ self assert: aParser parse: aCollection to: anObject end: aCollection size ! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'Nicolasanquetil 5/3/2013 15:05'! assert: aParser parse: aCollection to: aTargetObject end: anInteger | stream result | self assert: aParser isPetitParser description: 'Parser invalid'. stream := aCollection asPetitStream. result := aParser parse: stream. aTargetObject isNil ifTrue: [ self deny: result isPetitFailure ] ifFalse: [ self assert: result equals: aTargetObject ]. self assert: stream position = anInteger description: 'Parser accepted at wrong position'. ^ result! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'lr 2/26/2013 00:43'! assert: aParser parse: aCollection toToken: aStartInteger stop: aStopInteger ^ self assert: aParser parse: aCollection toToken: aStartInteger stop: aStopInteger end: aCollection size! ! !PPAbstractParserTest methodsFor: 'utilities' stamp: 'Nicolasanquetil 5/3/2013 15:13'! assert: aParser parse: aParserObject toToken: aStartInteger stop: aStopInteger end: anEndInteger | token | token := self assert: aParser parse: aParserObject to: nil end: anEndInteger. self assert: (token isKindOf: PPToken). self assert: token start equals: aStartInteger. self assert: token stop equals: aStopInteger. ^ token! ! !PPAnalyzerTest class methodsFor: 'accessing' stamp: 'lr 11/19/2009 21:51'! packageNamesUnderTest ^ #('PetitAnalyzer')! ! !PPAnalyzerTest methodsFor: 'utilities' stamp: 'lr 2/7/2010 20:54'! assert: aCollection includes: aString epsilon: aBoolean | parsers checker stream | parsers := aCollection collect: [ :each | each end ]. checker := [ :string | parsers anySatisfy: [ :parser | (parser parse: string asPetitStream) isPetitFailure not ] ]. stream := WriteStream on: String new. 32 to: 127 do: [ :index | (checker value: (String with: (Character value: index))) ifTrue: [ stream nextPut: (Character value: index) ] ]. self assert: stream contents = aString description: 'Expected ' , aString printString , ', but got ' , stream contents printString. self assert: (checker value: '') = aBoolean description: 'Expected epsilon to ' , (aBoolean ifTrue: [ 'be' ] ifFalse: [ 'not be' ]) , ' included'! ! !PPAnalyzerTest methodsFor: 'accessing' stamp: 'lr 11/20/2009 15:29'! grammarA "Güting, Erwig, Übersetzerbau, Springer (p.63)" | grammar | grammar := Dictionary new. " terminals " grammar at: #a put: $a asParser. grammar at: #b put: $b asParser. grammar at: #c put: $c asParser. grammar at: #d put: $d asParser. grammar at: #e put: nil asParser. " non terminals " grammar at: #B put: (grammar at: #b) / (grammar at: #e). grammar at: #A put: (grammar at: #a) / (grammar at: #B). grammar at: #S put: (grammar at: #A) , (grammar at: #B) , (grammar at: #c) , (grammar at: #d). ^ grammar ! ! !PPAnalyzerTest methodsFor: 'accessing' stamp: 'lr 11/19/2009 23:42'! grammarB "The canonical grammar to exercise first- and follow-set calculation, probably originally from the dragon-book." | grammar | grammar := Dictionary new. #(E Ep T Tp F) do: [ :each | grammar at: each put: (PPUnresolvedParser named: each) ]. (grammar at: #E) def: (grammar at: #T) , (grammar at: #Ep). (grammar at: #Ep) def: ($+ asParser , (grammar at: #T) , (grammar at: #Ep)) optional. (grammar at: #T) def: (grammar at: #F) , (grammar at: #Tp). (grammar at: #Tp) def: ($* asParser , (grammar at: #F) , (grammar at: #Tp)) optional. (grammar at: #F) def: ($( asParser , (grammar at: #E) , $) asParser) / $i asParser. #(E Ep T Tp F) do: [ :each | (grammar at: each) name: each ]. ^ grammar! ! !PPAnalyzerTest methodsFor: 'accessing' stamp: 'DiegoLont 9/2/2013 12:16'! grammarC "A highly recrusive grammar." | grammar | grammar := PPUnresolvedParser new. grammar def: (grammar , $+ asParser , grammar) / $1 asParser. ^grammar! ! !PPAnalyzerTest methodsFor: 'accessing' stamp: 'DiegoLont 9/2/2013 12:37'! grammarD "A highly ambiguous grammar from: Saichaitanya Jampana. Exploring the problem of ambiguity in context-free grammars. Master's thesis, Oklahoma State University, July 2005." | grammar | grammar := Dictionary new. #(S A a B b) do: [ :each | grammar at: each put: (PPUnresolvedParser named: each) ]. (grammar at: #a) def: $a asParser. (grammar at: #b) def: $b asParser. (grammar at: #S) def: (grammar at: #A) , (grammar at: #B) / (grammar at: #a). (grammar at: #A) def: (grammar at: #S) , (grammar at: #B) / (grammar at: #b). (grammar at: #B) def: (grammar at: #B) , (grammar at: #A) / (grammar at: #a). ^ grammar! ! !PPAnalyzerTest methodsFor: 'accessing' stamp: 'lr 11/19/2009 23:52'! grammarE "The most stupid parser, it just references itself and never consumes anything. All algorithms should survive such an attack." | parser | parser := PPDelegateParser new. parser setParser: parser. ^ parser! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testAllNamedParsers | p1 p2 p3 | p1 := #digit asParser name: 'a'. p2 := (#digit asParser name: 'b') star. p3 := (#digit asParser name: 'c') token end. self assert: p1 allNamedParsers size equals: 1. self assert: p1 allNamedParsers first name equals: 'a'. self assert: p2 allNamedParsers size equals: 1. self assert: p2 allNamedParsers first name equals: 'b'. self assert: p3 allNamedParsers size equals: 1. self assert: p3 allNamedParsers first name equals: 'c'! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:06'! testAllParsers | p1 p2 p3 | p1 := #lowercase asParser. p2 := p1 ==> #asUppercase. p3 := PPUnresolvedParser new. p3 def: p2 / p3. self assert: p1 allParsers size equals: 1. self assert: p2 allParsers size equals: 2. self assert: p3 allParsers size equals: 3! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'lr 11/20/2009 00:00'! testCycleSetGrammarA self grammarA do: [ :each | self assert: each cycleSet isEmpty ]! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'lr 11/20/2009 00:01'! testCycleSetGrammarB self grammarB do: [ :each | self assert: each cycleSet isEmpty ]! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testCycleSetGrammarC | grammar cycleSet | grammar := self grammarC. cycleSet := grammar cycleSet. self assert: cycleSet size equals: 2. self assert: (cycleSet includes: grammar)! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testCycleSetGrammarD | grammar cycleSet | grammar := self grammarD. cycleSet := (grammar at: #S) cycleSet. self assert: cycleSet size equals: 4. self assert: (cycleSet includes: (grammar at: #A)). self assert: (cycleSet includes: (grammar at: #S)). cycleSet := (grammar at: #A) cycleSet. self assert: cycleSet size equals: 4. self assert: (cycleSet includes: (grammar at: #A)). self assert: (cycleSet includes: (grammar at: #S)). cycleSet := (grammar at: #B) cycleSet. self assert: cycleSet size equals: 2. self assert: (cycleSet includes: (grammar at: #B))! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'Nicolasanquetil 5/3/2013 15:07'! testCycleSetGrammarE | grammar cycleSet | grammar := self grammarE. cycleSet := grammar cycleSet. self assert: cycleSet size equals: 1. self assert: (cycleSet includes: grammar)! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testCycleSetInChoice | parser cycleSet | parser := PPUnresolvedParser new. parser def: parser / $a asParser. cycleSet := parser cycleSet. self assert: cycleSet size equals: 1. self assert: (cycleSet includes: parser). parser := PPUnresolvedParser new. parser def: $a asParser / parser. cycleSet := parser cycleSet. self assert: cycleSet size equals: 1. self assert: (cycleSet includes: parser)! ! !PPAnalyzerTest methodsFor: 'testing-cycleset' stamp: 'Nicolasanquetil 5/3/2013 14:58'! testCycleSetInSequence | parser cycleSet | parser := PPUnresolvedParser new. parser def: parser , $a asParser. cycleSet := parser cycleSet. self assert: cycleSet size equals: 1. self assert: (cycleSet includes: parser). parser := PPUnresolvedParser new. parser def: nil asParser , parser. cycleSet := parser cycleSet. self assert: cycleSet size equals: 1. self assert: (cycleSet includes: parser). parser := PPUnresolvedParser new. parser def: $a asParser , parser. cycleSet := parser cycleSet. self assert: cycleSet isEmpty! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 12:19'! testDelegateReplace | one other delegate | one := $a asParser. other := $b asParser. delegate := one token. self assert: delegate children first == one. self deny: delegate children first == other. delegate replace: other with: one. self assert: delegate children first == one. self deny: delegate children first == other. delegate replace: one with: other. self deny: delegate children first == one. self assert: delegate children first == other! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 7/17/2011 12:22'! testFirstSetExpression | grammar | grammar := PPArithmeticParser new. self assert: grammar start firstSet includes: '(-0123456789' epsilon: false. self assert: grammar addition firstSet includes: '(-0123456789' epsilon: false. self assert: grammar factors firstSet includes: '(-0123456789' epsilon: false. self assert: grammar multiplication firstSet includes: '(-0123456789' epsilon: false. self assert: grammar number firstSet includes: '-0123456789' epsilon: false. self assert: grammar parentheses firstSet includes: '(' epsilon: false. self assert: grammar power firstSet includes: '(-0123456789' epsilon: false. self assert: grammar primary firstSet includes: '(-0123456789' epsilon: false. self assert: grammar terms firstSet includes: '(-0123456789' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 11/12/2009 17:53'! testFirstSetGrammarA | grammar | grammar := self grammarA. self assert: (grammar at: #a) firstSet includes: 'a' epsilon: false. self assert: (grammar at: #b) firstSet includes: 'b' epsilon: false. self assert: (grammar at: #c) firstSet includes: 'c' epsilon: false. self assert: (grammar at: #d) firstSet includes: 'd' epsilon: false. self assert: (grammar at: #e) firstSet includes: '' epsilon: true. self assert: (grammar at: #S) firstSet includes: 'abc' epsilon: false. self assert: (grammar at: #A) firstSet includes: 'ab' epsilon: true. self assert: (grammar at: #B) firstSet includes: 'b' epsilon: true! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 11/12/2009 17:53'! testFirstSetGrammarB | grammar | grammar := self grammarB. self assert: (grammar at: #E) firstSet includes: '(i' epsilon: false. self assert: (grammar at: #Ep) firstSet includes: '+' epsilon: true. self assert: (grammar at: #T) firstSet includes: '(i' epsilon: false. self assert: (grammar at: #Tp) firstSet includes: '*' epsilon: true. self assert: (grammar at: #F) firstSet includes: '(i' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 11/12/2009 17:53'! testFirstSetGrammarC | grammar | grammar := self grammarC. self assert: grammar firstSet includes: '1' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'TestRunner 11/12/2009 17:55'! testFirstSetGrammarD | grammar | grammar := self grammarD. self assert: (grammar at: #S) firstSet includes: 'ab' epsilon: false. self assert: (grammar at: #A) firstSet includes: 'ab' epsilon: false. self assert: (grammar at: #B) firstSet includes: 'a' epsilon: false. self assert: (grammar at: #a) firstSet includes: 'a' epsilon: false. self assert: (grammar at: #b) firstSet includes: 'b' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 11/19/2009 23:55'! testFirstSetGrammarE self assert: self grammarE firstSet includes: '' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-firstset' stamp: 'lr 10/22/2009 18:10'! testFirstSetLambda | grammar | grammar := PPLambdaParser new. self assert: grammar start firstSet includes: '(ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz' epsilon: false. self assert: grammar abstraction firstSet includes: '\' epsilon: false. self assert: grammar application firstSet includes: '(' epsilon: false. self assert: grammar expression firstSet includes: '(ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz' epsilon: false. self assert: grammar variable firstSet includes: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-followset' stamp: 'lr 10/22/2009 19:53'! testFollowSetExampleA | grammar followSets | grammar := self grammarA. followSets := (grammar at: #S) followSets. self assert: (followSets at: (grammar at: #a)) includes: 'bc' epsilon: false. self assert: (followSets at: (grammar at: #b)) includes: 'bc' epsilon: false. self assert: (followSets at: (grammar at: #c)) includes: 'd' epsilon: false. self assert: (followSets at: (grammar at: #d)) includes: '' epsilon: true. self assert: (followSets at: (grammar at: #e)) includes: 'bc' epsilon: false. self assert: (followSets at: (grammar at: #S)) includes: '' epsilon: true. self assert: (followSets at: (grammar at: #A)) includes: 'bc' epsilon: false. self assert: (followSets at: (grammar at: #B)) includes: 'bc' epsilon: false! ! !PPAnalyzerTest methodsFor: 'testing-followset' stamp: 'lr 10/22/2009 19:06'! testFollowSetExampleB | grammar followSets | grammar := self grammarB. followSets := (grammar at: #E) followSets. self assert: (followSets at: (grammar at: #E)) includes: ')' epsilon: true. self assert: (followSets at: (grammar at: #Ep)) includes: ')' epsilon: true. self assert: (followSets at: (grammar at: #T)) includes: ')+' epsilon: true. self assert: (followSets at: (grammar at: #Tp)) includes: ')+' epsilon: true. self assert: (followSets at: (grammar at: #F)) includes: ')*+' epsilon: true! ! !PPAnalyzerTest methodsFor: 'testing-followset' stamp: 'lr 10/22/2009 19:10'! testFollowSetExampleC self assert: self grammarC followSet includes: '+' epsilon: true! ! !PPAnalyzerTest methodsFor: 'testing-followset' stamp: 'lr 11/12/2009 18:00'! testFollowSetExampleD | grammar followSets | grammar := self grammarD. followSets := (grammar at: #S) followSets. self assert: (followSets at: (grammar at: #S)) includes: 'a' epsilon: true. self assert: (followSets at: (grammar at: #A)) includes: 'ab' epsilon: true. self assert: (followSets at: (grammar at: #B)) includes: 'ab' epsilon: true. self assert: (followSets at: (grammar at: #a)) includes: 'ab' epsilon: true. self assert: (followSets at: (grammar at: #b)) includes: 'ab' epsilon: true! ! !PPAnalyzerTest methodsFor: 'testing-followset' stamp: 'lr 11/19/2009 23:54'! testFollowSetExampleE self assert: self grammarE followSet includes: '' epsilon: true! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:07'! testInnerChildren | p1 p2 p3 | p1 := #digit asParser name: 'a'. p2 := #digit asParser star name: 'b'. p3 := (#digit asParser name: 'c') token star end. self assert: p1 innerChildren isEmpty. self assert: p2 innerChildren size equals: 1. self assert: (p2 innerChildren allSatisfy: [ :each | each name isNil ]). self assert: p3 innerChildren size equals: 2. self assert: (p3 innerChildren allSatisfy: [ :each | each name isNil ])! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'lr 11/20/2009 15:29'! testIsNullable self assert: $a asParser star isNullable. self assert: nil asParser isNullable. self deny: $a asParser plus isNullable. self deny: PPLiteralSequenceParser new isNullable. self deny: PPLiteralObjectParser new isNullable. self deny: PPPredicateParser new isNullable. self deny: PPChoiceParser new isNullable. self deny: PPSequenceParser new isNullable. self deny: PPAndParser new isNullable. self deny: PPTokenParser new isNullable! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'lr 6/12/2010 09:04'! testIsTerminal self assert: PPEpsilonParser new isTerminal. self assert: PPFailingParser new isTerminal. self assert: PPPluggableParser new isTerminal. self assert: PPLiteralObjectParser new isTerminal. self assert: PPLiteralSequenceParser new isTerminal. self assert: PPPredicateObjectParser new isTerminal. self assert: PPPredicateSequenceParser new isTerminal. self deny: ($a asParser / $b asParser) isTerminal. self deny: ($a asParser , $b asParser) isTerminal. self deny: ($a asParser and) isTerminal. self deny: ($a asParser not) isTerminal! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 12:21'! testListReplace | one other another list | one := $a asParser. other := $b asParser. another := $c asParser. list := one , another , one. self assert: list children first == one. self assert: list children second == another. self assert: list children last == one. list replace: other with: one. self assert: list children first == one. self assert: list children second == another. self assert: list children last == one. list replace: one with: other. self assert: list children first == other. self assert: list children second == another. self assert: list children last == other. list replace: another with: one. self assert: list children first == other. self assert: list children second == one. self assert: list children last == other! ! !PPAnalyzerTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testNamedChildren | p1 p2 p3 p4 | p1 := #digit asParser name: 'a'. p2 := (#digit asParser name: 'b') star. p3 := (#digit asParser name: 'c') token end. p4 := ((#digit asParser name: 'c') token name: 'd') end. self assert: p1 namedChildren isEmpty. self assert: p2 namedChildren size equals: 1. self assert: p2 namedChildren first name equals: 'b'. self assert: p3 namedChildren size equals: 1. self assert: p3 namedChildren first name equals: 'c'. self assert: p4 namedChildren size equals: 1. self assert: p4 namedChildren first name equals: 'd'! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/4/2011 19:22'! testRepetitionReplace | one two otherone othertwo repetition | one := $a asParser. two := $b asParser. otherone := $1 asParser. othertwo := $2 asParser. repetition := one starLazy: two. self assert: repetition children first == one. self assert: repetition children second == two. repetition replace: one with: otherone. self assert: repetition children first == otherone. self assert: repetition children second == two. repetition replace: two with: othertwo. self assert: repetition children first == otherone. self assert: repetition children second == othertwo! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 23:33'! testTransformIdentityGrammarC | orig tran | orig := self grammarC. tran := orig transform: [ :each | each ]. self deny: orig == tran. self deny: orig children first == tran children first. self deny: orig children first children first == tran children first children first. self deny: orig children first children last == tran children first children last. self deny: orig children last == tran children last. self assert: orig class == PPChoiceParser. self assert: orig children first class == PPSequenceParser. self assert: orig children first children first == orig. self assert: orig children first children last == orig. self assert: orig children last class == PPLiteralObjectParser. self assert: tran class == PPChoiceParser. self assert: tran children first class == PPSequenceParser. self assert: tran children first children first == tran. self assert: tran children first children last == tran. self assert: tran children last class == PPLiteralObjectParser! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 23:13'! testTransformIdentityGrammarE | orig tran | orig := self grammarE. tran := orig transform: [ :each | each ]. self deny: orig == tran. self deny: orig children first = tran children first. self assert: orig class == PPDelegateParser. self assert: orig children first == orig. self assert: tran class == PPDelegateParser. self assert: tran children first == tran! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 23:32'! testTransformWrapGrammarC | orig tran | orig := self grammarC. tran := orig transform: [ :each | each memoized ]. self assert: orig class == PPChoiceParser. self assert: orig children first class == PPSequenceParser. self assert: orig children first children first == orig. self assert: orig children first children last == orig. self assert: orig children last class == PPLiteralObjectParser. self assert: tran class == PPMemoizedParser. self assert: tran children first class == PPChoiceParser. self assert: tran children first children first class == PPMemoizedParser. self assert: tran children first children first children first class == PPSequenceParser. self assert: tran children first children first children first children first == tran. self assert: tran children first children first children first children last == tran. self assert: tran children first children last class == PPMemoizedParser. self assert: tran children first children last children first class == PPLiteralObjectParser! ! !PPAnalyzerTest methodsFor: 'testing-transform' stamp: 'lr 4/13/2010 23:08'! testTransformWrapGrammarE | orig tran | orig := self grammarE. tran := orig transform: [ :each | each memoized ]. self assert: orig class == PPDelegateParser. self assert: orig children first == orig. self assert: tran class == PPMemoizedParser. self assert: tran children first class == PPDelegateParser. self assert: tran children first children first == tran! ! !PPComposedTest methodsFor: 'accessing' stamp: 'lr 2/8/2010 16:44'! comment ^ ($" asParser , $" asParser negate star , $" asParser) flatten! ! !PPComposedTest methodsFor: 'accessing' stamp: 'lr 2/8/2010 16:44'! identifier ^ (#letter asParser , #word asParser star) flatten! ! !PPComposedTest methodsFor: 'accessing' stamp: 'lr 2/8/2010 16:44'! number ^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten! ! !PPComposedTest methodsFor: 'testing-examples' stamp: 'lr 2/8/2010 16:44'! testComment self assert: self comment parse: '""' to: '""'. self assert: self comment parse: '"a"' to: '"a"'. self assert: self comment parse: '"ab"' to: '"ab"'. self assert: self comment parse: '"abc"' to: '"abc"'. self assert: self comment parse: '""a' to: '""' end: 2. self assert: self comment parse: '"a"a' to: '"a"' end: 3. self assert: self comment parse: '"ab"a' to: '"ab"' end: 4. self assert: self comment parse: '"abc"a' to: '"abc"' end: 5. self assert: self comment fail: '"'. self assert: self comment fail: '"a'. self assert: self comment fail: '"aa'. self assert: self comment fail: 'a"'. self assert: self comment fail: 'aa"'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 7/6/2009 08:34'! testDoubledString | parser | parser := ($' asParser , (($' asParser , $' asParser) / $' asParser negate) star flatten , $' asParser) ==> [ :nodes | nodes second copyReplaceAll: '''''' with: '''' ]. self assert: parser parse: '''''' to: ''. self assert: parser parse: '''a''' to: 'a'. self assert: parser parse: '''ab''' to: 'ab'. self assert: parser parse: '''a''''b''' to: 'a''b'. self assert: parser parse: '''a''''''''b''' to: 'a''''b'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 12/5/2010 14:25'! testEvenNumber "Create a grammar that parses an even number of a's and b's." | a as b bs s | a := $a asParser ==> [ :char | as := as + 1 ]. b := $b asParser ==> [ :char | bs := bs + 1 ]. s := (a / b) star >=> [ :stream :cc | as := bs := 0. cc value. (as even and: [ bs even ]) ifFalse: [ PPFailure message: 'Even number of a and b expected' at: 0 ] ]. self assert: s fail: 'a' end: 1. self assert: s fail: 'b' end: 1. self assert: s fail: 'ab' end: 2. self assert: s fail: 'ba' end: 2. self assert: s fail: 'aaa' end: 3. self assert: s fail: 'bbb' end: 3. self assert: s fail: 'aab' end: 3. self assert: s fail: 'abb' end: 3. self assert: s parse: ''. self assert: s parse: 'aa'. self assert: s parse: 'bb'. self assert: s parse: 'aaaa'. self assert: s parse: 'aabb'. self assert: s parse: 'abab'. self assert: s parse: 'baba'. self assert: s parse: 'bbaa'. self assert: s parse: 'bbbb'! ! !PPComposedTest methodsFor: 'testing-examples' stamp: 'lr 2/8/2010 16:44'! testIdentifier self assert: self identifier parse: 'a' to: 'a'. self assert: self identifier parse: 'a1' to: 'a1'. self assert: self identifier parse: 'a12' to: 'a12'. self assert: self identifier parse: 'ab' to: 'ab'. self assert: self identifier parse: 'a1b' to: 'a1b'. self assert: self identifier parse: 'a_' to: 'a' end: 1. self assert: self identifier parse: 'a1-' to: 'a1' end: 2. self assert: self identifier parse: 'a12+' to: 'a12' end: 3. self assert: self identifier parse: 'ab^' to: 'ab' end: 2. self assert: self identifier parse: 'a1b*' to: 'a1b' end: 3. self assert: self identifier fail: ''. self assert: self identifier fail: '1'. self assert: self identifier fail: '1a'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:11'! testIfThenElse "S ::= if C then S else S | if C then S | X" | start if then else cond expr parser | start := PPDelegateParser new. if := 'if' asParser token trim. then := 'then' asParser token trim. else := 'else' asParser token trim. cond := 'C' asParser token trim. expr := 'X' asParser token trim. start setParser: (if , cond , then , start , else , start) / (if , cond , then , start) / expr. parser := start end. self assert: parser parse: 'X'. self assert: parser parse: 'if C then X'. self assert: parser parse: 'if C then X else X'. self assert: parser parse: 'if C then if C then X'. self assert: parser parse: 'if C then if C then X else if C then X'. self assert: parser parse: 'if C then if C then X else X else if C then X'. self assert: parser parse: 'if C then if C then X else X else if C then X else X'. self assert: parser fail: 'if C'. self assert: parser fail: 'if C else X'. self assert: parser fail: 'if C then if C'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:09'! testLeftRecursion "S ::= S 'x' S / '1'" | parser | parser := PPDelegateParser new. parser setParser: ((parser , $x asParser , parser) / $1 asParser) memoized flatten. self assert: parser parse: '1' to: '1'. self assert: parser parse: '1x1' to: '1x1'. self assert: parser parse: '1x1x1' to: '1x1x1'. self assert: parser parse: '1x1x1x1' to: '1x1x1x1'. self assert: parser parse: '1x1x1x1x1' to: '1x1x1x1x1'. self assert: parser parse: '1x1x1x1x1x1' to: '1x1x1x1x1x1'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 2/25/2013 23:50'! testListOfIntegers "S ::= S , number | number" | number list parser | number := #digit asParser plus flatten trim ==> [ :node | node asInteger ]. list := (number separatedBy: $, asParser token trim) ==> [ :node | node select: [ :each | each isInteger ] ]. parser := list end. self assert: parser parse: '1' to: (1 to: 1) asArray. self assert: parser parse: '1,2' to: (1 to: 2) asArray. self assert: parser parse: '1,2,3' to: (1 to: 3) asArray. self assert: parser parse: '1,2,3,4' to: (1 to: 4) asArray. self assert: parser parse: '1,2,3,4,5' to: (1 to: 5) asArray. self assert: parser parse: '1' to: (1 to: 1) asArray. self assert: parser parse: '1, 2' to: (1 to: 2) asArray. self assert: parser parse: '1, 2, 3' to: (1 to: 3) asArray. self assert: parser parse: '1, 2, 3, 4' to: (1 to: 4) asArray. self assert: parser parse: '1, 2, 3, 4, 5' to: (1 to: 5) asArray. self assert: parser parse: '1' to: (1 to: 1) asArray. self assert: parser parse: '1 ,2' to: (1 to: 2) asArray. self assert: parser parse: '1 ,2 ,3' to: (1 to: 3) asArray. self assert: parser parse: '1 ,2 ,3 ,4' to: (1 to: 4) asArray. self assert: parser parse: '1 ,2 ,3 ,4 ,5' to: (1 to: 5) asArray. self assert: parser fail: ''. self assert: parser fail: ','. self assert: parser fail: '1,'. self assert: parser fail: '1,,2'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:09'! testNestedComments "C ::= B I* E" "I ::= !!E (C | T)" "B ::= /*" "E ::= */" "T ::= ." | begin end any inside parser | begin := '/*' asParser. end := '*/' asParser. any := #any asParser. parser := PPDelegateParser new. inside := end not , (parser / any). parser setParser: begin , inside star , end. self assert: parser parse: '/*ab*/cd' end: 6. self assert: parser parse: '/*a/*b*/c*/'. self assert: parser fail: '/*a/*b*/c'! ! !PPComposedTest methodsFor: 'testing-examples' stamp: 'lr 2/8/2010 16:44'! testNumber self assert: self number parse: '1' to: '1'. self assert: self number parse: '12' to: '12'. self assert: self number parse: '12.3' to: '12.3'. self assert: self number parse: '12.34' to: '12.34'. self assert: self number parse: '1..' to: '1' end: 1. self assert: self number parse: '12-' to: '12' end: 2. self assert: self number parse: '12.3.' to: '12.3' end: 4. self assert: self number parse: '12.34.' to: '12.34' end: 5. self assert: self number parse: '-1' to: '-1'. self assert: self number parse: '-12' to: '-12'. self assert: self number parse: '-12.3' to: '-12.3'. self assert: self number parse: '-12.34' to: '-12.34'. self assert: self number fail: ''. self assert: self number fail: '-'. self assert: self number fail: '.'. self assert: self number fail: '.1'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:10'! testPalindrome "S0 ::= a S1 a | b S1 b | ... S1 ::= S0 | epsilon" | s0 s1 parser | s0 := PPDelegateParser new. s1 := PPDelegateParser new. s0 setParser: ($a asParser , s1 , $a asParser) / ($b asParser , s1 , $b asParser) / ($c asParser , s1 , $c asParser). s1 setParser: s0 / nil asParser. parser := s0 flatten end. self assert: parser parse: 'aa' to: 'aa'. self assert: parser parse: 'bb' to: 'bb'. self assert: parser parse: 'cc' to: 'cc'. self assert: parser parse: 'abba' to: 'abba'. self assert: parser parse: 'baab' to: 'baab'. self assert: parser parse: 'abccba' to: 'abccba'. self assert: parser parse: 'abaaba' to: 'abaaba'. self assert: parser parse: 'cbaabc' to: 'cbaabc'. self assert: parser fail: 'a'. self assert: parser fail: 'ab'. self assert: parser fail: 'aab'. self assert: parser fail: 'abccbb'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:10'! testParseAaaBbb "S0 ::= a S1 b S1 ::= S0 | epsilon" | s0 s1 parser | s0 := PPDelegateParser new. s1 := PPDelegateParser new. s0 setParser: $a asParser , s1 , $b asParser. s1 setParser: s0 / nil asParser. parser := s0 flatten. self assert: parser parse: 'ab' to: 'ab'. self assert: parser parse: 'aabb' to: 'aabb'. self assert: parser parse: 'aaabbb' to: 'aaabbb'. self assert: parser parse: 'aaaabbbb' to: 'aaaabbbb'. self assert: parser parse: 'abb' to: 'ab' end: 2. self assert: parser parse: 'aabbb' to: 'aabb' end: 4. self assert: parser parse: 'aaabbbb' to: 'aaabbb' end: 6. self assert: parser parse: 'aaaabbbbb' to: 'aaaabbbb' end: 8. self assert: parser fail: 'a'. self assert: parser fail: 'b'. self assert: parser fail: 'aab'. self assert: parser fail: 'aaabb'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:10'! testParseAaaaaa "S ::= a a S | epsilon" | s0 s1 parser | s0 := PPDelegateParser new. s1 := $a asParser , $a asParser , s0. s0 setParser: s1 / nil asParser. parser := s0 flatten. self assert: parser parse: '' to: ''. self assert: parser parse: 'aa' to: 'aa'. self assert: parser parse: 'aaaa' to: 'aaaa'. self assert: parser parse: 'aaaaaa' to: 'aaaaaa'. self assert: parser parse: 'a' to: '' end: 0. self assert: parser parse: 'aaa' to: 'aa' end: 2. self assert: parser parse: 'aaaaa' to: 'aaaa' end: 4. self assert: parser parse: 'aaaaaaa' to: 'aaaaaa' end: 6! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 9/18/2008 09:26'! testParseAbAbAb "S ::= (A B)+" | parser | parser := ($a asParser , $b asParser) plus flatten. self assert: parser parse: 'ab' to: 'ab'. self assert: parser parse: 'abab' to: 'abab'. self assert: parser parse: 'ababab' to: 'ababab'. self assert: parser parse: 'abababab' to: 'abababab'. self assert: parser parse: 'abb' to: 'ab' end: 2. self assert: parser parse: 'ababa' to: 'abab' end: 4. self assert: parser parse: 'abababb' to: 'ababab' end: 6. self assert: parser parse: 'ababababa' to: 'abababab' end: 8. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: 'bab'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 9/18/2008 09:26'! testParseAbabbb "S ::= (A | B)+" | parser | parser := ($a asParser / $b asParser) plus flatten. self assert: parser parse: 'a' to: 'a'. self assert: parser parse: 'b' to: 'b'. self assert: parser parse: 'ab' to: 'ab'. self assert: parser parse: 'ba' to: 'ba'. self assert: parser parse: 'aaa' to: 'aaa'. self assert: parser parse: 'aab' to: 'aab'. self assert: parser parse: 'aba' to: 'aba'. self assert: parser parse: 'baa' to: 'baa'. self assert: parser parse: 'abb' to: 'abb'. self assert: parser parse: 'bab' to: 'bab'. self assert: parser parse: 'bba' to: 'bba'. self assert: parser parse: 'bbb' to: 'bbb'. self assert: parser parse: 'ac' to: 'a' end: 1. self assert: parser parse: 'bc' to: 'b' end: 1. self assert: parser parse: 'abc' to: 'ab' end: 2. self assert: parser parse: 'bac' to: 'ba' end: 2. self assert: parser fail: ''. self assert: parser fail: 'c'! ! !PPComposedTest methodsFor: 'testing' stamp: 'lr 6/24/2011 06:11'! testParseAnBnCn "PEGs for a non context- free language: a^n , b^n , c^n S <- &P1 P2 P1 <- AB 'c' AB <- 'a' AB 'b' / epsilon P2 <- 'a'* BC end BC <- 'b' BC 'c' / epsilon" | s p1 ab p2 bc | s := PPDelegateParser new. p1 := PPDelegateParser new. ab := PPDelegateParser new. p2 := PPDelegateParser new. bc := PPDelegateParser new. s setParser: (p1 and , p2 end) flatten. p1 setParser: ab , $c asParser. ab setParser: ($a asParser , ab , $b asParser) optional. p2 setParser: $a asParser star , bc. bc setParser: ($b asParser , bc , $c asParser) optional. self assert: s parse: 'abc' to: 'abc'. self assert: s parse: 'aabbcc' to: 'aabbcc'. self assert: s parse: 'aaabbbccc' to: 'aaabbbccc'. self assert: s fail: 'bc'. self assert: s fail: 'ac'. self assert: s fail: 'ab'. self assert: s fail: 'abbcc'. self assert: s fail: 'aabcc'. self assert: s fail: 'aabbc'! ! !PPComposedTest methodsFor: 'testing-examples' stamp: 'lr 2/25/2013 23:51'! testReturn | number spaces return | number := #digit asParser plus flatten. spaces := #space asParser star. return := (spaces , $^ asParser token , spaces , number) ==> [ :nodes | Array with: #return with: (nodes at: 4) ]. self assert: return parse: '^1' to: #(return '1'). self assert: return parse: '^12' to: #(return '12'). self assert: return parse: '^ 123' to: #(return '123'). self assert: return parse: '^ 1234' to: #(return '1234'). self assert: return fail: '1'. self assert: return fail: '^'! ! !PPArithmeticParserTest methodsFor: 'accessing' stamp: 'FirstnameLastname 11/26/2009 21:53'! parserClass ^ PPArithmeticParser! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/30/2008 17:21'! testAdd self assert: '1 + 2' is: 3. self assert: '2 + 1' is: 3. self assert: '1 + 2.3' is: 3.3. self assert: '2.3 + 1' is: 3.3. self assert: '1 + -2' is: -1. self assert: '-2 + 1' is: -1! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/21/2008 10:23'! testAddMany self assert: '1' is: 1. self assert: '1 + 2' is: 3. self assert: '1 + 2 + 3' is: 6. self assert: '1 + 2 + 3 + 4' is: 10. self assert: '1 + 2 + 3 + 4 + 5' is: 15! ! !PPArithmeticParserTest methodsFor: 'testing-expression' stamp: 'lr 4/21/2008 10:03'! testBrackets self assert: '(1)' is: 1. self assert: '(1 + 2)' is: 3. self assert: '((1))' is: 1. self assert: '((1 + 2))' is: 3. self assert: '2 * (3 + 4)' is: 14. self assert: '(2 + 3) * 4' is: 20. self assert: '6 / (2 + 4)' is: 1. self assert: '(2 + 6) / 2' is: 4! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/21/2008 09:32'! testDiv self assert: '12 / 3' is: 4. self assert: '-16 / -4' is: 4! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 7/3/2008 15:46'! testDivMany self assert: '100 / 2' is: 50. self assert: '100 / 2 / 2' is: 25. self assert: '100 / 2 / 2 / 5' is: 5. self assert: '100 / 2 / 2 / 5 / 5' is: 1 ! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/21/2008 09:31'! testMul self assert: '2 * 3' is: 6. self assert: '2 * -4' is: -8! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/21/2008 10:16'! testMulMany self assert: '1 * 2' is: 2. self assert: '1 * 2 * 3' is: 6. self assert: '1 * 2 * 3 * 4' is: 24. self assert: '1 * 2 * 3 * 4 * 5' is: 120! ! !PPArithmeticParserTest methodsFor: 'testing' stamp: 'lr 4/21/2008 09:32'! testNum self assert: '0' is: 0. self assert: '0.0' is: 0.0. self assert: '1' is: 1. self assert: '1.2' is: 1.2. self assert: '34' is: 34. self assert: '56.78' is: 56.78. self assert: '-9' is: -9. self assert: '-9.9' is: -9.9! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 7/3/2008 15:28'! testPow self assert: '2 ^ 3' is: 8. self assert: '-2 ^ 3' is: -8. self assert: '-2 ^ -3' is: -0.125! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 7/3/2008 15:45'! testPowMany self assert: '4 ^ 3' is: 64. self assert: '4 ^ 3 ^ 2' is: 262144. self assert: '4 ^ 3 ^ 2 ^ 1' is: 262144. self assert: '4 ^ 3 ^ 2 ^ 1 ^ 0' is: 262144! ! !PPArithmeticParserTest methodsFor: 'testing-expression' stamp: 'lr 4/21/2008 10:00'! testPriority self assert: '2 * 3 + 4' is: 10. self assert: '2 + 3 * 4' is: 14. self assert: '6 / 3 + 4' is: 6. self assert: '2 + 6 / 2' is: 5! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 8/14/2010 13:38'! testSub self assert: '1 - 2' is: -1. self assert: '1.2 - 1.2' is: 0. self assert: '1 - -2' is: 3. self assert: '-1 - -2' is: 1! ! !PPArithmeticParserTest methodsFor: 'testing-operations' stamp: 'lr 4/28/2008 11:56'! testSubMany self assert: '1' is: 1. self assert: '1 - 2' is: -1. self assert: '1 - 2 - 3' is: -4. self assert: '1 - 2 - 3 - 4' is: -8. self assert: '1 - 2 - 3 - 4 - 5' is: -13! ! !PPExpressionParserTest class methodsFor: 'testing' stamp: 'lr 4/6/2010 19:40'! shouldInheritSelectors ^ true! ! !PPExpressionParserTest methodsFor: 'accessing' stamp: 'lr 2/25/2013 23:50'! parserInstance | expression parens number | expression := PPExpressionParser new. parens := $( asParser trim , expression , $) asParser trim ==> [ :value | value second ]. number := (#digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim ==> [ :value | value asNumber ]. expression term: parens / number. expression group: [ :g | g prefix: $- asParser trim do: [ :op :a | a negated ] ]; group: [ :g | g postfix: '++' asParser trim do: [ :a :op | a + 1 ]. g postfix: '--' asParser trim do: [ :a :op | a - 1 ] ]; group: [ :g | g right: $^ asParser trim do: [ :a :op :b | a raisedTo: b ] ]; group: [ :g | g left: $* asParser trim do: [ :a :op :b | a * b ]. g left: $/ asParser trim do: [ :a :op :b | a / b ] ]; group: [ :g | g left: $+ asParser trim do: [ :a :op :b | a + b ]. g left: $- asParser trim do: [ :a :op :b | a - b ] ]. ^ expression end! ! !PPExpressionParserTest methodsFor: 'testing' stamp: 'FirstnameLastname 11/26/2009 22:13'! testPostfixAdd self assert: '0++' is: 1. self assert: '0++++' is: 2. self assert: '0++++++' is: 3. self assert: '0+++1' is: 2. self assert: '0+++++1' is: 3. self assert: '0+++++++1' is: 4! ! !PPExpressionParserTest methodsFor: 'testing' stamp: 'FirstnameLastname 11/26/2009 22:11'! testPostfixSub self assert: '1--' is: 0. self assert: '2----' is: 0. self assert: '3------' is: 0. self assert: '2---1' is: 0. self assert: '3-----1' is: 0. self assert: '4-------1' is: 0.! ! !PPExpressionParserTest methodsFor: 'testing' stamp: 'FirstnameLastname 11/26/2009 22:13'! testPrefixNegate self assert: '1' is: 1. self assert: '-1' is: -1. self assert: '--1' is: 1. self assert: '---1' is: -1! ! !PPCompositeParserTest class methodsFor: 'testing' stamp: 'lr 10/4/2009 17:09'! isAbstract ^ self name = #PPCompositeParserTest! ! !PPCompositeParserTest class methodsFor: 'accessing' stamp: 'lr 3/29/2010 15:21'! resources ^ Array with: PPParserResource! ! !PPCompositeParserTest methodsFor: 'utilities' stamp: 'lr 11/29/2010 11:20'! assert: aCollection is: anObject self parse: aCollection. self assert: result = anObject description: 'Got: ' , result printString , '; Expected: ' , anObject printString resumable: true! ! !PPCompositeParserTest methodsFor: 'parsing' stamp: 'lr 11/18/2011 19:45'! fail: aString rule: aSymbol | production | production := self parserInstanceFor: aSymbol. result := production end parse: aString. self assert: result isPetitFailure description: 'Able to parse ' , aString printString. ^ result! ! !PPCompositeParserTest methodsFor: 'parsing' stamp: 'lr 11/29/2010 11:26'! parse: aString ^ self parse: aString rule: #start! ! !PPCompositeParserTest methodsFor: 'parsing' stamp: 'lr 11/18/2011 19:45'! parse: aString rule: aSymbol | production | production := self parserInstanceFor: aSymbol. result := production end parse: aString. self deny: result isPetitFailure description: 'Unable to parse ' , aString printString. ^ result! ! !PPCompositeParserTest methodsFor: 'accessing' stamp: 'FirstnameLastname 11/26/2009 21:52'! parserClass self subclassResponsibility! ! !PPCompositeParserTest methodsFor: 'accessing' stamp: 'lr 3/29/2010 15:21'! parserInstance ^ PPParserResource current parserAt: self parserClass! ! !PPCompositeParserTest methodsFor: 'accessing' stamp: 'lr 11/18/2011 19:44'! parserInstanceFor: aSymbol ^ aSymbol = #start ifTrue: [ self parserInstance ] ifFalse: [ self parserInstance productionAt: aSymbol ifAbsent: [ self error: 'Production ' , self parserClass name , '>>' , aSymbol printString , ' not found.' ] ]! ! !PPCompositeParserTest methodsFor: 'running' stamp: 'FirstnameLastname 11/26/2009 21:48'! setUp super setUp. parser := self parserInstance! ! !PPCompositeParserTest methodsFor: 'running' stamp: 'lr 11/29/2010 11:19'! tearDown super tearDown. parser := result := nil! ! !PPLambdaParserTest methodsFor: 'accessing' stamp: 'FirstnameLastname 11/26/2009 21:53'! parserClass ^ PPLambdaParser! ! !PPLambdaParserTest methodsFor: 'testing' stamp: 'lr 4/30/2008 09:38'! testAbstraction self assert: '\x.y' is: #('x' 'y'). self assert: '\x.\y.z' is: #('x' ('y' 'z'))! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:17'! testAnd self assert: self parserClass and equals: #('p' #('q' #(#('p' 'q') 'p')))! ! !PPLambdaParserTest methodsFor: 'testing' stamp: 'lr 4/30/2008 09:38'! testApplication self assert: '(x x)' is: #('x' 'x'). self assert: '(x y)' is: #('x' 'y'). self assert: '((x y) z)' is: #(('x' 'y') 'z'). self assert: '(x (y z))' is: #('x' ('y' 'z'))! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:02'! testFalse self assert: self parserClass false equals: #('x' #('y' 'y'))! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:11'! testIfThenElse self assert: self parserClass ifthenelse equals: #('p' 'p')! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:18'! testNot self assert: self parserClass not equals: #('p' #('a' #('b' #(#('p' 'b') 'a'))))! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:03'! testOr self assert: self parserClass or equals: #('p' #('q' #(#('p' 'p') 'q')))! ! !PPLambdaParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:11'! testParseOnError | beenHere | result := self parserClass parse: '\x.y' onError: [ self fail ]. self assert: result equals: #('x' 'y'). beenHere := false. result := self parserClass parse: '\x.' onError: [ beenHere := true ]. self assert: beenHere. beenHere := false. result := self parserClass parse: '\x.' onError: [ :fail | beenHere := true. fail ]. self assert: beenHere. self assert: (result message includesSubstring: '$('). self assert: (result message includesSubstring: 'expected'). self assert: result position equals: 0. beenHere := false. result := self parserClass parse: '\x.' onError: [ :msg :pos | self assert: (msg includesSubstring: '$('). self assert: (msg includesSubstring: 'expected'). self assert: pos equals: 0. beenHere := true ]. self assert: result. self assert: beenHere! ! !PPLambdaParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:18'! testParseStartingAtOnError | beenHere | result := self parserClass parse: 'x' startingAt: #variable onError: [ self fail ]. self assert: result equals: 'x'. beenHere := false. result := self parserClass parse: '\' startingAt: #variable onError: [ beenHere := true ]. self assert: beenHere. beenHere := false. result := self parserClass parse: '\' startingAt: #variable onError: [ :fail | beenHere := true. fail ]. self assert: beenHere. self assert: result message equals: 'letter expected'. self assert: result position equals: 0. beenHere := false. result := self parserClass parse: '\' startingAt: #variable onError: [ :msg :pos | self assert: msg equals: 'letter expected'. self assert: pos equals: 0. beenHere := true ]. self assert: beenHere! ! !PPLambdaParserTest methodsFor: 'testing-utilities' stamp: 'FirstnameLastname 11/26/2009 21:56'! testProductionAt self assert: (parser productionAt: #foo) isNil. self assert: (parser productionAt: #foo ifAbsent: [ true ]). self assert: (parser productionAt: #start) notNil. self assert: (parser productionAt: #start ifAbsent: [ true ]) notNil. self assert: (parser productionAt: #variable) notNil. self assert: (parser productionAt: #variable ifAbsent: [ true ]) notNil! ! !PPLambdaParserTest methodsFor: 'testing-curch' stamp: 'Nicolasanquetil 5/3/2013 15:04'! testTrue self assert: self parserClass true equals: #('x' #('y' 'x'))! ! !PPLambdaParserTest methodsFor: 'testing' stamp: 'lr 4/30/2008 09:33'! testVariable self assert: 'x' is: 'x'. self assert: 'xy' is: 'xy'. self assert: 'x12' is: 'x12'! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 5/2/2010 18:18'! testCharacter | parser | parser := $a asParser. self assert: parser parse: 'a' to: $a. self assert: parser fail: 'b'! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 11/29/2011 20:38'! testChoice | parser | parser := #(1 2) asChoiceParser. self assert: parser parse: #(1) to: 1. self assert: parser parse: #(2) to: 2. self assert: parser parse: #(1 2) to: 1 end: 1. self assert: parser parse: #(2 1) to: 2 end: 1. self assert: parser fail: #(). self assert: parser fail: #(3)! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 5/5/2010 14:03'! testClosure | parser | parser := [ :stream | stream upTo: $s ] asParser. self assert: parser parse: '' to: ''. self assert: parser parse: 'a' to: 'a'. self assert: parser parse: 'aa' to: 'aa'. self assert: parser parse: 's' to: ''. self assert: parser parse: 'as' to: 'a'. self assert: parser parse: 'aas' to: 'aa'. self assert: parser parse: 'sa' to: '' end: 1. self assert: parser parse: 'saa' to: '' end: 1. parser := [ :stream | stream upTo: $s. PPFailure message: 'stream' at: stream position ] asParser. self assert: parser fail: ''. self assert: parser fail: 's'. self assert: parser fail: 'as' ! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'Nicolasanquetil 5/3/2013 14:59'! testEpsilon | parser | parser := nil asParser. self assert: parser asParser equals: parser! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'Nicolasanquetil 5/3/2013 15:08'! testParser | parser | parser := $a asParser. self assert: parser asParser equals: parser! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 9/17/2008 22:48'! testRange | parser | parser := $a - $c. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'b' to: $b. self assert: parser parse: 'c' to: $c. self assert: parser fail: 'd'! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 11/29/2011 20:40'! testSequence | parser | parser := #(1 2) asSequenceParser. self assert: parser parse: #(1 2) to: #(1 2). self assert: parser parse: #(1 2 3) to: #(1 2) end: 2. self assert: parser fail: #(). self assert: parser fail: #(1). self assert: parser fail: #(1 1). self assert: parser fail: #(1 1 2)! ! !PPExtensionTest methodsFor: 'testing-stream' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testStream | stream | stream := 'abc' readStream asPetitStream. self assert: stream class equals: PPStream. self assert: stream printString equals: '·abc'. self assert: stream peek equals: $a. self assert: stream uncheckedPeek equals: $a. self assert: stream next equals: $a. self assert: stream printString equals: 'a·bc'. self assert: stream asPetitStream equals: stream! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 5/2/2010 18:18'! testString | parser | parser := 'ab' asParser. self assert: parser parse: 'ab' to: 'ab'. self assert: parser parse: 'aba' to: 'ab' end: 2. self assert: parser parse: 'abb' to: 'ab' end: 2. self assert: parser fail: 'a'. self assert: parser fail: 'ac'! ! !PPExtensionTest methodsFor: 'testing-parser' stamp: 'lr 9/17/2008 22:03'! testSymbol | parser | parser := #any asParser. self assert: parser parse: 'a'. self assert: parser fail: ''! ! !PPExtensionTest methodsFor: 'testing-stream' stamp: 'Nicolasanquetil 5/3/2013 15:00'! testText | stream | stream := 'abc' asText asPetitStream. self assert: stream class equals: PPStream! ! !PPObjectTest methodsFor: 'parsers' stamp: 'lr 12/9/2010 10:25'! integer ^ PPPredicateObjectParser on: [ :each | each isInteger ] message: 'integer expected'! ! !PPObjectTest methodsFor: 'parsers' stamp: 'lr 10/30/2010 12:45'! string ^ PPPredicateObjectParser on: [ :each | each isString ] message: 'string expected'! ! !PPObjectTest methodsFor: 'testing-operators' stamp: 'lr 12/9/2010 10:25'! testChoice | parser | parser := self integer / self string. self assert: parser parse: #(123) to: 123. self assert: parser parse: #('abc') to: 'abc'! ! !PPObjectTest methodsFor: 'testing-fancy' stamp: 'lr 12/9/2010 10:25'! testFibonacci "This parser accepts fibonacci sequences with arbitrary start pairs." | parser | parser := ((self integer , self integer) end ==> [ :pair | pair first + pair last ]) / (self integer , (self integer , self integer) and >=> [ :stream :continuation | | result | result := continuation value. (result isPetitFailure or: [ result first + result last first ~= result last last ]) ifFalse: [ parser parseOn: stream ] ifTrue: [ PPFailure message: 'invalid fibonacci sequence' at: stream position ] ]). self assert: parser parse: #(1 1) to: 2. self assert: parser parse: #(1 1 2) to: 3. self assert: parser parse: #(1 1 2 3) to: 5. self assert: parser parse: #(1 1 2 3 5) to: 8. self assert: parser parse: #(1 1 2 3 5 8) to: 13. self assert: parser parse: #(1 1 2 3 5 8 13) to: 21. self assert: parser fail: #(). self assert: parser fail: #(1). self assert: parser fail: #(1 2 3 4) end: 2 ! ! !PPObjectTest methodsFor: 'testing' stamp: 'lr 12/9/2010 10:25'! testInteger self assert: self integer parse: #(123) to: 123. self assert: self integer fail: #('abc')! ! !PPObjectTest methodsFor: 'testing-operators' stamp: 'lr 12/9/2010 10:25'! testSequence | parser | parser := self integer , self string. self assert: parser parse: #(123 'abc') to: #(123 'abc'). self assert: parser fail: #(123 456). self assert: parser fail: #('abc' 'def'). self assert: parser fail: #('abc' 123) ! ! !PPObjectTest methodsFor: 'testing' stamp: 'lr 10/30/2010 12:47'! testString self assert: self string parse: #('abc') to: 'abc'. self assert: self string fail: #(123)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testAction | block parser | block := [ :char | char asUppercase ]. parser := #any asParser ==> block. self assert: parser block equals: block. self assert: parser parse: 'a' to: $A. self assert: parser parse: 'b' to: $B! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testAnd | parser | parser := 'foo' asParser flatten , 'bar' asParser flatten and. self assert: parser parse: 'foobar' to: #('foo' 'bar') end: 3. self assert: parser fail: 'foobaz'. parser := 'foo' asParser and. self assert: parser and equals: parser! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testAnswer | parser | parser := $a asParser answer: $b. self assert: parser parse: 'a' to: $b. self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/2/2009 19:56'! testBlock | parser | parser := [ :s | s next ] asParser. self assert: parser parse: 'ab' to: $a end: 1. self assert: parser parse: 'b' to: $b. self assert: parser parse: '' to: nil! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:07'! testChildren | p1 p2 p3 | p1 := #lowercase asParser. p2 := p1 ==> #asUppercase. p3 := PPUnresolvedParser new. p3 def: p2 / p3. self assert: p1 children isEmpty. self assert: p2 children size equals: 1. self assert: p3 children size equals: 2! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 9/15/2008 09:24'! testChoice | parser | parser := $a asParser / $b asParser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'b' to: $b. self assert: parser parse: 'ab' to: $a end: 1. self assert: parser parse: 'ba' to: $b end: 1. self assert: parser fail: ''. self assert: parser fail: 'c'. self assert: parser fail: 'ca'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 5/7/2008 08:58'! testDelimitedBy | parser | parser := $a asParser delimitedBy: $b asParser. self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aba' to: #($a $b $a). self assert: parser parse: 'ababa' to: #($a $b $a $b $a). self assert: parser parse: 'ab' to: #($a $b). self assert: parser parse: 'abab' to: #($a $b $a $b). self assert: parser parse: 'ababab' to: #($a $b $a $b $a $b). self assert: parser parse: 'ac' to: #($a) end: 1. self assert: parser parse: 'abc' to: #($a $b) end: 2. self assert: parser parse: 'abac' to: #($a $b $a) end: 3. self assert: parser parse: 'ababc' to: #($a $b $a $b) end: 4. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'c'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 2/25/2012 16:56'! testDelimitedByWithoutSeparators | parser | parser := ($a asParser delimitedBy: $b asParser) withoutSeparators. self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aba' to: #($a $a). self assert: parser parse: 'ababa' to: #($a $a $a). self assert: parser parse: 'ab' to: #($a). self assert: parser parse: 'abab' to: #($a $a). self assert: parser parse: 'ababab' to: #($a $a $a). self assert: parser parse: 'ac' to: #($a) end: 1. self assert: parser parse: 'abc' to: #($a) end: 2. self assert: parser parse: 'abac' to: #($a $a) end: 3. self assert: parser parse: 'ababc' to: #($a $a) end: 4. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'c'! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testEndOfInput | parser | parser := PPEndOfInputParser on: $a asParser. self assert: parser end equals: parser. self assert: parser parse: 'a' to: $a. self assert: parser fail: ''. self assert: parser fail: 'aa'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 9/17/2008 22:47'! testEndOfInputAfterMatch | parser | parser := 'stuff' asParser end. self assert: parser parse: 'stuff' to: 'stuff'. self assert: parser fail: 'stufff'. self assert: parser fail: 'fluff'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 11/20/2009 15:31'! testEpsilon | parser | parser := nil asParser. self assert: parser parse: '' to: nil. self assert: parser parse: 'a' to: nil end: 0. self assert: parser parse: 'ab' to: nil end: 0! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 14:58'! testFailing | parser result | parser := PPFailingParser message: 'Plonk'. self assert: parser message equals: 'Plonk'. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: 'aa'. result := parser parse: 'a'. self assert: result message equals: 'Plonk'. self assert: result printString equals: 'Plonk at 0'! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:07'! testFailure | failure | failure := PPFailure message: 'Error' at: 3. self assert: failure message equals: 'Error'. self assert: failure position equals: 3. self assert: failure isPetitFailure. self deny: 4 isPetitFailure. self deny: 'foo' isPetitFailure! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 5/2/2010 12:18'! testFlatten | parser | parser := $a asParser flatten. self assert: parser parse: 'a' to: 'a'. self assert: parser parse: #($a) to: #($a). self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testFoldLeft2 | parser | parser := #any asParser star foldLeft: [ :a :b | Array with: a with: b ]. self assert: parser parse: #(a) to: #a. self assert: parser parse: #(a b) to: #(a b). self assert: parser parse: #(a b c) to: #((a b) c). self assert: parser parse: #(a b c d) to: #(((a b) c) d). self assert: parser parse: #(a b c d e) to: #((((a b) c) d) e)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testFoldLeft3 | parser | parser := #any asParser star foldLeft: [ :a :b :c | Array with: a with: b with: c ]. self assert: parser parse: #(a) to: #a. self assert: parser parse: #(a b c) to: #(a b c). self assert: parser parse: #(a b c d e) to: #((a b c) d e)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testFoldRight2 | parser | parser := #any asParser star foldRight: [ :a :b | Array with: a with: b ]. self assert: parser parse: #(a) to: #a. self assert: parser parse: #(a b) to: #(a b). self assert: parser parse: #(a b c) to: #(a (b c)). self assert: parser parse: #(a b c d) to: #(a (b (c d))). self assert: parser parse: #(a b c d e) to: #(a (b (c (d e))))! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testFoldRight3 | parser | parser := #any asParser star foldRight: [ :a :b :c | Array with: a with: b with: c ]. self assert: parser parse: #(a) to: #a. self assert: parser parse: #(a b c) to: #(a b c). self assert: parser parse: #(a b c d e) to: #(a b (c d e))! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:38'! testHasProperty | parser | parser := PPParser new. self deny: (parser hasProperty: #foo). parser propertyAt: #foo put: 123. self assert: (parser hasProperty: #foo)! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testListConstructor | p1 p2 p3 | p1 := PPChoiceParser with: $a asParser. p2 := PPChoiceParser with: $a asParser with: $b asParser. p3 := PPChoiceParser withAll: (Array with: $a asParser with: $b asParser with: $c asParser). self assert: p1 children size equals: 1. self assert: p2 children size equals: 2. self assert: p3 children size equals: 3! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 14:59'! testLiteralObject | parser | parser := PPLiteralObjectParser on: $a message: 'letter "a" expected'. self assert: parser literal equals: $a. self assert: parser message equals: 'letter "a" expected'. self assert: parser parse: 'a' to: $a. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 6/1/2010 22:30'! testLiteralObjectCaseInsensitive | parser | parser := $a asParser caseInsensitive. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'A' to: $A. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'B' ! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:08'! testLiteralSequence | parser | parser := PPLiteralSequenceParser on: 'abc' message: 'sequence "abc" expected'. self assert: parser size equals: 3. self assert: parser literal equals: 'abc'. self assert: parser message equals: 'sequence "abc" expected'. self assert: parser parse: 'abc' to: 'abc'. self assert: parser fail: 'ab'. self assert: parser fail: 'abd'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 6/1/2010 22:31'! testLiteralSequenceCaseInsensitive | parser | parser := 'abc' asParser caseInsensitive. self assert: parser parse: 'abc' to: 'abc'. self assert: parser parse: 'ABC' to: 'ABC'. self assert: parser parse: 'abC' to: 'abC'. self assert: parser parse: 'AbC' to: 'AbC'. self assert: parser fail: 'ab'. self assert: parser fail: 'abd'! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testMap1 | parser | parser := #any asParser map: [ :a | Array with: a ]. self assert: parser parse: #(a) to: #(a)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testMap2 | parser | parser := (#any asParser , #any asParser) map: [ :a :b | Array with: b with: a ]. self assert: parser parse: #(a b) to: #(b a)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testMap3 | parser | parser := (#any asParser , #any asParser , #any asParser) map: [ :a :b :c | Array with: c with: b with: a ]. self assert: parser parse: #(a b c) to: #(c b a)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testMapFail1 self should: [ #any asParser map: [ ] ] raise: Error. self should: [ #any asParser map: [ :a :b | ] ] raise: Error ! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 6/24/2011 06:16'! testMapFail2 self should: [ (#any asParser , #any asParser) map: [ :a | ] ] raise: Error. self should: [ (#any asParser , #any asParser) map: [ :a :b :c | ] ] raise: Error ! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'lr 2/8/2010 00:32'! testMatches | parser | parser := $a asParser. self assert: (parser matches: 'a'). self deny: (parser matches: 'b'). self assert: (parser matches: 'a' readStream). self deny: (parser matches: 'b' readStream)! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testMatchesIn | parser result | parser := $a asParser. result := parser matchesIn: 'abba'. self assert: result size equals: 2. self assert: result first equals: $a. self assert: result last equals: $a. result := parser matchesIn: 'baaah'. self assert: result size equals: 3. self assert: result first equals: $a. self assert: result last equals: $a! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:00'! testMatchesInEmpty "Empty matches should properly advance and match at each position and at the end." | parser result | parser := [ :stream | stream position ] asParser. result := parser matchesIn: '123'. self assert: result asArray equals: #(0 1 2 3)! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testMatchesInOverlapping "Matches that overlap should be properly reported." | parser result | parser := #digit asParser , #digit asParser. result := parser matchesIn: 'a123b'. self assert: result size equals: 2. self assert: result first equals: #($1 $2). self assert: result last equals: #($2 $3)! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testMatchesSkipIn | parser result | parser := $a asParser. result := parser matchesSkipIn: 'abba'. self assert: result size equals: 2. self assert: result first equals: $a. self assert: result last equals: $a. result := parser matchesSkipIn: 'baaah'. self assert: result size equals: 3. self assert: result first equals: $a. self assert: result last equals: $a! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:00'! testMatchesSkipInOverlapping "Matches that overlap should be properly reported." | parser result | parser := #digit asParser , #digit asParser. result := parser matchesSkipIn: 'a123b'. self assert: result size equals: 1. self assert: result first equals: #($1 $2)! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testMatchingRangesIn | input parser result | input := 'a12b3'. parser := #digit asParser plus. result := parser matchingRangesIn: input. result := result collect: [ :each | input copyFrom: each first to: each last ]. self assert: result size equals: 3. self assert: result first equals: '12'. self assert: result second equals: '2'. self assert: result last equals: '3'! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:17'! testMatchingSkipRangesIn | input parser result | input := 'a12b3'. parser := #digit asParser plus. result := parser matchingSkipRangesIn: input. result := result collect: [ :each | input copyFrom: each first to: each last ]. self assert: result size equals: 2. self assert: result first equals: '12'. self assert: result last equals: '3'! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:01'! testMax | parser | parser := $a asParser max: 2. self assert: parser min equals: 0. self assert: parser max equals: 2. self assert: parser parse: '' to: #(). self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a) end: 2. self assert: parser parse: 'aaaa' to: #($a $a) end: 2. self assert: (parser printString endsWith: '[0, 2]')! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 21:02'! testMaxGreedy | parser | parser := #word asParser max: 2 greedy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abc'. self assert: parser parse: '1' to: #() end: 0. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser fail: 'abc1'. self assert: parser parse: '12' to: #($1) end: 1. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser fail: 'abc12'. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1) end: 2. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser fail: 'abc123'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 21:03'! testMaxLazy | parser | parser := #word asParser max: 2 lazy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abc'. self assert: parser parse: '1' to: #() end: 0. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser fail: 'abc1'. self assert: parser parse: '12' to: #() end: 0. self assert: parser parse: 'a12' to: #($a) end: 1. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser fail: 'abc12'. self assert: parser parse: '123' to: #() end: 0. self assert: parser parse: 'a123' to: #($a) end: 1. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser fail: 'abc123'! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:10'! testMemoized | count parser twice | count := 0. parser := [ :s | count := count + 1. s next ] asParser memoized. twice := parser and , parser. count := 0. self assert: parser parse: 'a' to: $a. self assert: count equals: 1. count := 0. self assert: twice parse: 'a' to: #($a $a). self assert: count equals: 1. self assert: parser memoized equals: parser! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:17'! testMin | parser | parser := $a asParser min: 2. self assert: parser min equals: 2. self assert: parser max > parser min. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a $a). self assert: parser parse: 'aaaa' to: #($a $a $a $a). self assert: (parser printString endsWith: '[2, *]')! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 21:12'! testMinGreedy | parser | parser := #word asParser min: 2 greedy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abcde'. self assert: parser fail: '1'. self assert: parser fail: 'a1'. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4. self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5. self assert: parser fail: '12'. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b $1) end: 3. self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4. self assert: parser parse: 'abcd12' to: #($a $b $c $d $1) end: 5. self assert: parser parse: 'abcde12' to: #($a $b $c $d $e $1) end: 6. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1 $2) end: 3. self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4. self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5. self assert: parser parse: 'abcd123' to: #($a $b $c $d $1 $2) end: 6. self assert: parser parse: 'abcde123' to: #($a $b $c $d $e $1 $2) end: 7. self assert: parser parse: '1234' to: #($1 $2 $3) end: 3. self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4. self assert: parser parse: 'ab1234' to: #($a $b $1 $2 $3) end: 5. self assert: parser parse: 'abc1234' to: #($a $b $c $1 $2 $3) end: 6. self assert: parser parse: 'abcd1234' to: #($a $b $c $d $1 $2 $3) end: 7. self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e $1 $2 $3) end: 8! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 21:15'! testMinLazy | parser | parser := #word asParser min: 2 lazy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abcde'. self assert: parser fail: '1'. self assert: parser fail: 'a1'. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4. self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5. self assert: parser fail: '12'. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser parse: 'abc12' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4. self assert: parser parse: 'abcde12' to: #($a $b $c $d $e) end: 5. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1) end: 2. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser parse: 'abc123' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4. self assert: parser parse: 'abcde123' to: #($a $b $c $d $e) end: 5. self assert: parser parse: '1234' to: #($1 $2) end: 2. self assert: parser parse: 'a1234' to: #($a $1) end: 2. self assert: parser parse: 'ab1234' to: #($a $b) end: 2. self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4. self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e) end: 5! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:02'! testMinMax | parser | parser := $a asParser min: 2 max: 4. self assert: parser min equals: 2. self assert: parser max equals: 4. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a $a). self assert: parser parse: 'aaaa' to: #($a $a $a $a). self assert: parser parse: 'aaaaa' to: #($a $a $a $a) end: 4. self assert: parser parse: 'aaaaaa' to: #($a $a $a $a) end: 4. self assert: (parser printString endsWith: '[2, 4]')! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 20:54'! testMinMaxGreedy | parser | parser := #word asParser min: 2 max: 4 greedy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abcde'. self assert: parser fail: '1'. self assert: parser fail: 'a1'. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde1'. self assert: parser fail: '12'. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b $1) end: 3. self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4. self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde12'. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1 $2) end: 3. self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4. self assert: parser parse: 'abc123' to: #($a $b $c $1) end: 4. self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde123'. self assert: parser parse: '1234' to: #($1 $2 $3) end: 3. self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4. self assert: parser parse: 'ab1234' to: #($a $b $1 $2) end: 4. self assert: parser parse: 'abc1234' to: #($a $b $c $1) end: 4. self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde1234'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/3/2011 20:57'! testMinMaxLazy | parser | parser := #word asParser min: 2 max: 4 lazy: #digit asParser. self assert: parser fail: ''. self assert: parser fail: 'abcde'. self assert: parser fail: '1'. self assert: parser fail: 'a1'. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde1'. self assert: parser fail: '12'. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser parse: 'abc12' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde12'. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1) end: 2. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser parse: 'abc123' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde123'. self assert: parser parse: '1234' to: #($1 $2) end: 2. self assert: parser parse: 'a1234' to: #($a $1) end: 2. self assert: parser parse: 'ab1234' to: #($a $b) end: 2. self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3. self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4. self assert: parser fail: 'abcde1234'! ! !PPParserTest methodsFor: 'testing-accessing' stamp: 'Nicolasanquetil 5/3/2013 15:11'! testNamed | parser | parser := PPSequenceParser new. self assert: parser name isNil. parser := PPChoiceParser named: 'choice'. self assert: parser name equals: 'choice'. parser := $* asParser name: 'star'. self assert: parser name equals: 'star'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 2/7/2010 20:10'! testNegate | parser | parser := 'foo' asParser negate. self assert: parser parse: 'f' to: $f end: 1. self assert: parser parse: 'fo' to: $f end: 1. self assert: parser parse: 'fob' to: $f end: 1. self assert: parser parse: 'ffoo' to: $f end: 1. self assert: parser fail: ''. self assert: parser fail: 'foo'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 8/26/2010 09:54'! testNot | parser | parser := 'foo' asParser flatten , 'bar' asParser flatten not. self assert: parser parse: 'foobaz' to: #('foo' nil) end: 3. self assert: parser fail: 'foobar'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/29/2008 11:32'! testOptional | parser | parser := $a asParser optional. self assert: parser parse: '' to: nil. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'aa' to: $a end: 1. self assert: parser parse: 'ab' to: $a end: 1. self assert: parser parse: 'b' to: nil end: 0. self assert: parser parse: 'bb' to: nil end: 0. self assert: parser parse: 'ba' to: nil end: 0! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:18'! testParse | parser result | parser := $a asParser. self assert: (parser parse: 'a') equals: $a. self assert: (result := parser parse: 'b') isPetitFailure. self assert: (result message includesSubstring: '$a'). self assert: (result message includesSubstring: 'expected'). self assert: result position equals: 0. self assert: (parser parse: 'a' readStream) equals: $a. self assert: (result := parser parse: 'b' readStream) isPetitFailure. self assert: (result message includesSubstring: '$a'). self assert: (result message includesSubstring: 'expected'). self assert: result position equals: 0! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:03'! testParseOnError0 | parser result seen | parser := $a asParser. result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ]. self assert: result equals: $a. result := parser parse: 'b' onError: [ seen := true ]. self assert: result. self assert: seen! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:11'! testParseOnError1 | parser result seen | parser := $a asParser. result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ]. self assert: result equals: $a. result := parser parse: 'b' onError: [ :failure | self assert: failure position equals: 0. self assert: (failure message includesSubstring: '$a'). self assert: (failure message includesSubstring: 'expected'). seen := true ]. self assert: result. self assert: seen! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'Nicolasanquetil 5/3/2013 15:18'! testParseOnError2 | parser result seen | parser := $a asParser. result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ]. self assert: result equals: $a. result := parser parse: 'b' onError: [ :msg :pos | self assert: (msg includesSubstring: '$a'). self assert: (msg includesSubstring: 'expected'). self assert: pos equals: 0. seen := true ]. self assert: result. self assert: seen! ! !PPParserTest methodsFor: 'testing-utilities' stamp: 'lr 8/6/2010 19:06'! testParser | parser | parser := PPParser new. self assert: parser isPetitParser. self deny: 4 isPetitParser. self deny: 'foo' isPetitParser! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 1/8/2010 12:09'! testPermutation | parser | parser := #any asParser , #any asParser , #any asParser. self assert: (parser permutation: #()) parse: '123' to: #(). self assert: (parser permutation: #(1)) parse: '123' to: #($1). self assert: (parser permutation: #(1 3)) parse: '123' to: #($1 $3). self assert: (parser permutation: #(3 1)) parse: '123' to: #($3 $1). self assert: (parser permutation: #(2 2)) parse: '123' to: #($2 $2). self assert: (parser permutation: #(3 2 1)) parse: '123' to: #($3 $2 $1). self should: [ parser permutation: #(0) ] raise: Error. self should: [ parser permutation: #(4) ] raise: Error. self should: [ parser permutation: #($2) ] raise: Error! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:04'! testPluggable | block parser | block := [ :stream | stream position ]. parser := block asParser. self assert: parser block equals: block! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:12'! testPlus | parser | parser := $a asParser plus. self assert: parser min equals: 1. self assert: parser max > parser min. self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a $a). self assert: parser parse: 'ab' to: #($a) end: 1. self assert: parser parse: 'aab' to: #($a $a) end: 2. self assert: parser parse: 'aaab' to: #($a $a $a) end: 3. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'ba'! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:19'! testPlusGreedy | limit parser | limit := #digit asParser. parser := #word asParser plusGreedy: limit. self assert: parser min equals: 1. self assert: parser max > parser min. self assert: parser limit equals: limit. self assert: parser children size equals: 2. self assert: parser children last equals: limit. self assert: parser fail: ''. self assert: parser fail: '1'. self assert: parser fail: 'a'. self assert: parser fail: 'ab'. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b $1) end: 3. self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4. self assert: parser parse: 'a123' to: #($a $1 $2) end: 3. self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4. self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:04'! testPlusLazy | limit parser | limit := #digit asParser. parser := #word asParser plusLazy: limit. self assert: parser min equals: 1. self assert: parser max > parser min. self assert: parser limit equals: limit. self assert: parser children size equals: 2. self assert: parser children last equals: limit. self assert: parser fail: ''. self assert: parser fail: '1'. self assert: parser fail: 'a'. self assert: parser fail: 'ab'. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: 'a12' to: #($a) end: 1. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser parse: 'abc12' to: #($a $b $c) end: 3. self assert: parser parse: 'a123' to: #($a) end: 1. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser parse: 'abc123' to: #($a $b $c) end: 3! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:41'! testPostCopy | parser copy | parser := PPParser new. parser propertyAt: #foo put: true. copy := parser copy. copy propertyAt: #foo put: false. self assert: (parser propertyAt: #foo). self deny: (copy propertyAt: #foo)! ! !PPParserTest methodsFor: 'testing-accessing' stamp: 'TudorGirba 3/4/2013 07:02'! testPrint | parser | parser := PPParser new. self assert: (parser printString includesSubstring: 'PPParser'). parser := PPParser named: 'choice'. self assert: (parser printString includesSubstring: 'PPParser(choice'). parser := PPLiteralObjectParser on: $a. self assert: (parser printString includesSubstring: '$a'). parser := PPFailingParser message: 'error'. self assert: (parser printString includesSubstring: 'error'). parser := PPPredicateObjectParser on: [ :c | true ] message: 'error'. self assert: (parser printString includesSubstring: 'error')! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:36'! testPropertyAt | parser | parser := PPParser new. self should: [ parser propertyAt: #foo ] raise: Error. parser propertyAt: #foo put: true. self assert: (parser propertyAt: #foo)! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:37'! testPropertyAtIfAbsent | parser | parser := PPParser new. self assert: (parser propertyAt: #foo ifAbsent: [ true ]). parser propertyAt: #foo put: true. self assert: (parser propertyAt: #foo ifAbsent: [ false ])! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:37'! testPropertyAtIfAbsentPut | parser | parser := PPParser new. self assert: (parser propertyAt: #foo ifAbsentPut: [ true ]). self assert: (parser propertyAt: #foo ifAbsentPut: [ false ])! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:37'! testRemoveProperty | parser | parser := PPParser new. self should: [ parser removeProperty: #foo ] raise: Error. parser propertyAt: #foo put: true. self assert: (parser removeProperty: #foo)! ! !PPParserTest methodsFor: 'testing-properties' stamp: 'lr 4/19/2010 10:37'! testRemovePropertyIfAbsent | parser | parser := PPParser new. self assert: (parser removeProperty: #foo ifAbsent: [ true ]). parser propertyAt: #foo put: true. self assert: (parser removeProperty: #foo ifAbsent: [ false ])! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/29/2008 11:42'! testSeparatedBy | parser | parser := $a asParser separatedBy: $b asParser. self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aba' to: #($a $b $a). self assert: parser parse: 'ababa' to: #($a $b $a $b $a). self assert: parser parse: 'ab' to: #($a) end: 1. self assert: parser parse: 'abab' to: #($a $b $a) end: 3. self assert: parser parse: 'ac' to: #($a) end: 1. self assert: parser parse: 'abac' to: #($a $b $a) end: 3. self assert: parser fail: ''. self assert: parser fail: 'c'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 2/25/2012 16:55'! testSeparatedByWithoutSeparators | parser | parser := ($a asParser separatedBy: $b asParser) withoutSeparators. self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aba' to: #($a $a). self assert: parser parse: 'ababa' to: #($a $a $a). self assert: parser parse: 'ab' to: #($a) end: 1. self assert: parser parse: 'abab' to: #($a $a) end: 3. self assert: parser parse: 'ac' to: #($a) end: 1. self assert: parser parse: 'abac' to: #($a $a) end: 3. self assert: parser fail: ''. self assert: parser fail: 'c'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/29/2008 11:33'! testSequence | parser | parser := $a asParser , $b asParser. self assert: parser parse: 'ab' to: #($a $b). self assert: parser parse: 'aba' to: #($a $b) end: 2. self assert: parser parse: 'abb' to: #($a $b) end: 2. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: 'aa'. self assert: parser fail: 'ba'. self assert: parser fail: 'bab'! ! !PPParserTest methodsFor: 'testing-fixtures' stamp: 'lr 2/7/2010 22:00'! testSideEffectChoice "Adding another element to a choice should create a copy, otherwise we get unwanted side-effects." | p1 p2 p3 | p1 := $a asParser. p2 := p1 / $b asParser. p3 := p1 / $c asParser. self assert: p1 parse: 'a'. self assert: p1 fail: 'b'. self assert: p1 fail: 'c'. self assert: p2 parse: 'a'. self assert: p2 parse: 'b'. self assert: p2 fail: 'c'. self assert: p3 parse: 'a'. self assert: p3 fail: 'b'. self assert: p3 parse: 'c'! ! !PPParserTest methodsFor: 'testing-fixtures' stamp: 'lr 5/31/2010 19:25'! testSideEffectListCopy | old new | old := $a asParser , $b asParser. new := old copy. self deny: old == new. self deny: old children == new children. self assert: old children first == new children first. self assert: old children last == new children last! ! !PPParserTest methodsFor: 'testing-fixtures' stamp: 'lr 4/14/2010 11:38'! testSideEffectSequence "Adding another element to a sequence should create a copy, otherwise we get unwanted side-effects." | p1 p2 p3 | p1 := $a asParser. p2 := p1 , $b asParser. p3 := p1 , $c asParser. self assert: p1 parse: 'a'. self assert: p1 parse: 'ab' end: 1. self assert: p1 parse: 'ac' end: 1. self assert: p2 fail: 'a'. self assert: p2 parse: 'ab'. self assert: p2 fail: 'ac'. self assert: p3 fail: 'a'. self assert: p3 fail: 'ab'. self assert: p3 parse: 'ac'! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:13'! testStar | parser | parser := $a asParser star. self assert: parser min equals: 0. self assert: parser max > parser min. self assert: parser parse: '' to: #(). self assert: parser parse: 'a' to: #($a). self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a $a). self assert: parser parse: 'b' to: #() end: 0. self assert: parser parse: 'ab' to: #($a) end: 1. self assert: parser parse: 'aab' to: #($a $a) end: 2. self assert: parser parse: 'aaab' to: #($a $a $a) end: 3! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:19'! testStarGreedy | limit parser | limit := #digit asParser. parser := #word asParser starGreedy: limit. self assert: parser min equals: 0. self assert: parser max > parser min. self assert: parser limit equals: limit. self assert: parser children size equals: 2. self assert: parser children last equals: limit. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: 'ab'. self assert: parser parse: '1' to: #() end: 0. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: '12' to: #($1) end: 1. self assert: parser parse: 'a12' to: #($a $1) end: 2. self assert: parser parse: 'ab12' to: #($a $b $1) end: 3. self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4. self assert: parser parse: '123' to: #($1 $2) end: 2. self assert: parser parse: 'a123' to: #($a $1 $2) end: 3. self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4. self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5! ! !PPParserTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:05'! testStarLazy | limit parser | limit := #digit asParser. parser := #word asParser starLazy: limit. self assert: parser min equals: 0. self assert: parser max > parser min. self assert: parser limit equals: limit. self assert: parser children size equals: 2. self assert: parser children last equals: limit. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: 'ab'. self assert: parser parse: '1' to: #() end: 0. self assert: parser parse: 'a1' to: #($a) end: 1. self assert: parser parse: 'ab1' to: #($a $b) end: 2. self assert: parser parse: 'abc1' to: #($a $b $c) end: 3. self assert: parser parse: '12' to: #() end: 0. self assert: parser parse: 'a12' to: #($a) end: 1. self assert: parser parse: 'ab12' to: #($a $b) end: 2. self assert: parser parse: 'abc12' to: #($a $b $c) end: 3. self assert: parser parse: '123' to: #() end: 0. self assert: parser parse: 'a123' to: #($a) end: 1. self assert: parser parse: 'ab123' to: #($a $b) end: 2. self assert: parser parse: 'abc123' to: #($a $b $c) end: 3! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 9/15/2010 09:53'! testTimes | parser | parser := $a asParser times: 2. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser parse: 'aa' to: #($a $a). self assert: parser parse: 'aaa' to: #($a $a) end: 2! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'Nicolasanquetil 5/3/2013 15:13'! testToken | parser | parser := $a asParser token. self assert: parser tokenClass equals: PPToken. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser fail: 'b'. self assert: parser fail: ''. parser := $a asParser token: PPToken. self assert: parser tokenClass equals: PPToken. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 7/11/2011 11:05'! testTrim | parser | parser := $a asParser token trim. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 5 stop: 5. self assert: parser parse: ' a' toToken: 5 stop: 5. self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 2. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 3. self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 7/31/2010 12:07'! testTrimBlanks | parser | parser := $a asParser token trimBlanks. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 5 stop: 5. self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 2. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 3. self assert: parser fail: ''. self assert: parser fail: ' '. self assert: parser fail: ' a'. self assert: parser fail: 'b'.! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 7/11/2011 11:05'! testTrimCustom | parser | parser := $a asParser token trim: $b asParser. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: 'ab' toToken: 1 stop: 1. self assert: parser parse: 'abb' toToken: 1 stop: 1. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: 'ba' toToken: 2 stop: 2. self assert: parser parse: 'bba' toToken: 3 stop: 3. self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1. self assert: parser parse: 'ab' toToken: 1 stop: 1 end: 2. self assert: parser parse: 'abba' toToken: 1 stop: 1 end: 3. self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'lr 7/31/2010 12:07'! testTrimSpaces | parser | parser := $a asParser token trimSpaces. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a ' toToken: 1 stop: 1. self assert: parser parse: 'a' toToken: 1 stop: 1. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 2 stop: 2. self assert: parser parse: ' a' toToken: 5 stop: 5. self assert: parser parse: ' a' toToken: 5 stop: 5. self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 2. self assert: parser parse: 'a a' toToken: 1 stop: 1 end: 3. self assert: parser fail: ''. self assert: parser fail: 'b'! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 11/20/2009 15:31'! testUnresolved | parser | parser := PPUnresolvedParser new. self assert: parser isUnresolved. self should: [ parser parse: '' ] raise: Error. self should: [ parser parse: 'a' ] raise: Error. self should: [ parser parse: 'ab' ] raise: Error. parser := nil asParser. self deny: parser isUnresolved! ! !PPParserTest methodsFor: 'testing' stamp: 'tg 7/29/2010 22:39'! testWrapped | parser | parser := $a asParser wrapped. self assert: parser parse: 'a' to: $a. self assert: parser fail: 'b'. parser := (($a asParser , $b asParser ) wrapped , $c asParser). self assert: parser parse: 'abc' to: #(#($a $b) $c)! ! !PPParserTest methodsFor: 'testing-mapping' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testWrapping | parser result | parser := #digit asParser plus >=> [ :stream :cc | Array with: stream position with: cc value with: stream position ]. self assert: parser parse: '1' to: #(0 #($1) 1). self assert: parser parse: '12' to: #(0 #($1 $2) 2). self assert: parser parse: '123' to: #(0 #($1 $2 $3) 3). result := parser parse: 'a'. self assert: result first equals: 0. self assert: result second isPetitFailure. self assert: result last equals: 0! ! !PPParserTest methodsFor: 'testing' stamp: 'lr 4/14/2010 16:30'! testXor | parser | parser := ($a asParser / $b asParser) | ($b asParser / $c asParser). self assert: parser parse: 'a' to: $a. self assert: parser parse: 'c' to: $c. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'd'. " truly symmetric " parser := ($b asParser / $c asParser) | ($a asParser / $b asParser). self assert: parser parse: 'a' to: $a. self assert: parser parse: 'c' to: $c. self assert: parser fail: ''. self assert: parser fail: 'b'. self assert: parser fail: 'd'! ! !PPPredicateTest methodsFor: 'utilities' stamp: 'lr 6/12/2010 08:37'! assertCharacterSets: aParser "Assert the character set of aParser does not overlap with the character set with the negated parser, and that they both cover the complete character space." | positives negatives | positives := self parsedCharacterSet: aParser. negatives := self parsedCharacterSet: aParser negate. self charactersDo: [ :char | | positive negative | positive := positives includes: char. negative := negatives includes: char. self assert: ((positive and: [ negative not ]) or: [ positive not and: [ negative ] ]) description: char printString , ' should be in exactly one set' ]! ! !PPPredicateTest methodsFor: 'private' stamp: 'lr 6/12/2010 08:37'! charactersDo: aBlock 1 to: 256 do: [ :index | aBlock value: (Character codePoint: index) ]! ! !PPPredicateTest methodsFor: 'utilities' stamp: 'lr 6/12/2010 08:37'! parsedCharacterSet: aParser | result | result := WriteStream on: String new. self charactersDo: [ :char | (aParser matches: (String with: char)) ifTrue: [ result nextPut: char ] ]. ^ result contents! ! !PPPredicateTest methodsFor: 'testing-objects' stamp: 'lr 11/29/2009 09:32'! testAny | parser | parser := #any asParser. self assertCharacterSets: parser. self assert: parser parse: ' ' to: $ . self assert: parser parse: '1' to: $1. self assert: parser parse: 'a' to: $a. self assert: parser fail: ''! ! !PPPredicateTest methodsFor: 'testing-objects' stamp: 'tg 7/12/2010 11:26'! testAnyExceptAnyOf | parser | parser := PPPredicateObjectParser anyExceptAnyOf: #($: $,). self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'z' to: $z. self assert: parser fail: ':'. self assert: parser fail: ','! ! !PPPredicateTest methodsFor: 'testing-objects' stamp: 'lr 6/12/2010 09:16'! testAnyOf | parser | parser := PPPredicateObjectParser anyOf: #($a $z). self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'z' to: $z. self assert: parser fail: 'x'! ! !PPPredicateTest methodsFor: 'testing-objects' stamp: 'lr 6/12/2010 09:16'! testBetweenAnd | parser | parser := PPPredicateObjectParser between: $b and: $d. self assertCharacterSets: parser. self assert: parser fail: 'a'. self assert: parser parse: 'b' to: $b. self assert: parser parse: 'c' to: $c. self assert: parser parse: 'd' to: $d. self assert: parser fail: 'e'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 5/5/2010 14:15'! testBlank | parser | parser := #blank asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character space) to: Character space. self assert: parser parse: (String with: Character tab) to: Character tab. self assert: parser fail: ''. self assert: parser fail: '1'. self assert: parser fail: (String with: Character cr)! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 5/2/2010 12:51'! testChar | parser | parser := $* asParser. self assertCharacterSets: parser. self assert: parser parse: '*' to: $*. self assert: parser parse: '**' to: $* end: 1. self assert: parser fail: ''. self assert: parser fail: '1'. self assert: parser fail: 'a'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testCr | parser | parser := #cr asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character cr) to: Character cr! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testDigit | parser | parser := #digit asParser. self assertCharacterSets: parser. self assert: parser parse: '0' to: $0. self assert: parser parse: '9' to: $9. self assert: parser fail: ''. self assert: parser fail: 'a'! ! !PPPredicateTest methodsFor: 'testing-objects' stamp: 'lr 6/12/2010 09:16'! testExpect | parser | parser := PPPredicateObjectParser expect: $a. self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser fail: 'b'. self assert: parser fail: ''! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testHex | parser | parser := #hex asParser. self assertCharacterSets: parser. self assert: parser parse: '0' to: $0. self assert: parser parse: '5' to: $5. self assert: parser parse: '9' to: $9. self assert: parser parse: 'A' to: $A. self assert: parser parse: 'D' to: $D. self assert: parser parse: 'F' to: $F. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'e' to: $e. self assert: parser parse: 'f' to: $f. self assert: parser fail: ''. self assert: parser fail: 'g'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testLetter | parser | parser := #letter asParser. self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'Z' to: $Z. self assert: parser fail: ''. self assert: parser fail: '0'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testLf | parser | parser := #lf asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character lf) to: Character lf! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testLowercase | parser | parser := #lowercase asParser. self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'z' to: $z. self assert: parser fail: ''. self assert: parser fail: 'A'. self assert: parser fail: '0'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:36'! testNewline | parser | parser := #newline asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character cr) to: Character cr. self assert: parser parse: (String with: Character lf) to: Character lf. self assert: parser fail: ' '! ! !PPPredicateTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:06'! testOnMessage | block parser | block := [ :char | char = $* ]. parser := PPPredicateObjectParser on: block message: 'starlet'. self assert: parser block equals: block. self assert: parser message equals: 'starlet'. self assertCharacterSets: parser. self assert: parser parse: '*' to: $*. self assert: parser parse: '**' to: $* end: 1. self assert: parser fail: ''. self assert: parser fail: '1'. self assert: parser fail: 'a'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 5/5/2010 14:14'! testPunctuation | parser | parser := #punctuation asParser. self assertCharacterSets: parser. self assert: parser parse: '.' to: $.. self assert: parser parse: ',' to: $,. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: '1'! ! !PPPredicateTest methodsFor: 'testing-sequence' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testSequenceParser | parser | parser := PPPredicateSequenceParser on: [ :value | value first isUppercase ] message: 'uppercase 3 letter words' size: 3. self assert: parser size equals: 3. self assert: parser parse: 'Abc'. self assert: parser parse: 'ABc'. self assert: parser parse: 'ABC'. self assert: parser fail: 'abc'. self assert: parser fail: 'aBC'. self assert: parser fail: 'Ab'. parser := parser negate. self assert: parser size equals: 3. self assert: parser fail: 'Abc'. self assert: parser fail: 'ABc'. self assert: parser fail: 'ABC'. self assert: parser parse: 'abc'. self assert: parser parse: 'aBC'. self assert: parser fail: 'Ab'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testSpace | parser | parser := #space asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character tab) to: Character tab. self assert: parser parse: ' ' to: Character space. self assert: parser fail: ''. self assert: parser fail: 'a'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testTab | parser | parser := #tab asParser. self assertCharacterSets: parser. self assert: parser parse: (String with: Character tab) to: Character tab! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testUppercase | parser | parser := #uppercase asParser. self assertCharacterSets: parser. self assert: parser parse: 'A' to: $A. self assert: parser parse: 'Z' to: $Z. self assert: parser fail: ''. self assert: parser fail: 'a'. self assert: parser fail: '0'! ! !PPPredicateTest methodsFor: 'testing-chars' stamp: 'lr 11/29/2009 09:32'! testWord | parser | parser := #word asParser. self assertCharacterSets: parser. self assert: parser parse: 'a' to: $a. self assert: parser parse: 'A' to: $A. self assert: parser parse: '0' to: $0. self assert: parser fail: ''. self assert: parser fail: '-'! ! !PPRewriterTest methodsFor: 'running' stamp: 'lr 4/29/2010 08:47'! setUp rewriter := PPRewriter new! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testDuplicationRemoval | duplicate before between after result | duplicate := PPPattern any. before := PPListPattern any. between := PPListPattern any. after := PPListPattern any. rewriter replace: before / duplicate / between / duplicate / after with: before / duplicate / between / after. result := rewriter execute: $a asParser / $a asParser. self assert: rewriter hasChanged. self assert: result children size equals: 1. self assert: result children first literal equals: $a. result := rewriter execute: $b asParser / $a asParser / $a asParser. self assert: rewriter hasChanged. self assert: result children size equals: 2. self assert: result children first literal equals: $b. self assert: result children last literal equals: $a. result := rewriter execute: $a asParser / $b asParser / $a asParser. self assert: rewriter hasChanged. self assert: result children size equals: 2. self assert: result children first literal equals: $a. self assert: result children last literal equals: $b. result := rewriter execute: $a asParser / $a asParser / $b asParser. self assert: rewriter hasChanged. self assert: result children size equals: 2. self assert: result children first literal equals: $a. self assert: result children last literal equals: $b! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:06'! testPatternRemoval | pattern result | pattern := PPPattern class: PPLiteralObjectParser. rewriter replace: pattern / pattern with: pattern. result := rewriter execute: $a asParser / $a asParser. self assert: rewriter hasChanged. self assert: result class equals: PPLiteralObjectParser. self assert: result literal equals: $a. result := rewriter execute: $a asParser / $a asParser / $a asParser. self deny: rewriter hasChanged. self assert: result class equals: PPChoiceParser. self assert: result children size equals: 3! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:14'! testPatternReplacement | pattern result | pattern := PPPattern class: PPLiteralObjectParser. rewriter replace: pattern with: pattern , pattern. result := rewriter execute: $a asParser. self assert: rewriter hasChanged. self assert: result class equals: PPSequenceParser. self assert: result children first literal equals: $a. self assert: result children last literal equals: $a. result := rewriter execute: #any asParser. self deny: rewriter hasChanged. self assert: result class equals: PPPredicateObjectParser! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 14:58'! testReplaceLiteral | result | rewriter replace: $a asParser with: $b asParser. result := rewriter execute: $a asParser. self assert: rewriter hasChanged. self assert: result literal equals: $b. result := rewriter execute: $c asParser. self deny: rewriter hasChanged. self assert: result literal equals: $c. result := rewriter execute: $a asParser , $b asParser , $c asParser. self assert: rewriter hasChanged. self assert: result children size equals: 3. self assert: result children first literal equals: $b. self assert: result children last literal equals: $c! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:07'! testSwapTwoPattern | first second result | first := PPPattern any. second := PPPattern any. rewriter replace: first , second with: second , first. result := rewriter execute: $a asParser , $b asParser. self assert: rewriter hasChanged. self assert: result children first literal equals: $b. self assert: result children last literal equals: $a. result := rewriter execute: $a asParser / $b asParser. self deny: rewriter hasChanged. self assert: result children first literal equals: $a. self assert: result children last literal equals: $b! ! !PPRewriterTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testWrapLiteral | result | rewriter replace: $a asParser withValueFrom: [ :parser | parser token ]. result := rewriter execute: $a asParser. self assert: rewriter hasChanged. self assert: result class equals: PPTokenParser. self assert: result children first literal equals: $a. result := rewriter execute: $c asParser. self deny: rewriter hasChanged. self assert: result literal equals: $c. result := rewriter execute: $a asParser , $b asParser. self assert: rewriter hasChanged. self assert: result children first class equals: PPTokenParser. self assert: result children first children first literal equals: $a. self assert: result children last class equals: PPLiteralObjectParser. self assert: result children last literal equals: $b! ! !PPScriptingTest commentStamp: '' prior: 34277319! These are some simple demo-scripts of parser combinators for the compiler construction course. http://www.iam.unibe.ch/~scg/Teaching/CC/index.html! !PPScriptingTest methodsFor: 'examples' stamp: 'lr 6/12/2010 08:30'! expressionInterpreter "Same as #expressionInterpreter but with semantic actions." | mul prim add dec | add := PPUnresolvedParser new. mul := PPUnresolvedParser new. prim := PPUnresolvedParser new. dec := ($0 - $9) ==> [ :token | token codePoint - $0 codePoint ]. add def: ((mul , $+ asParser , add) ==> [ :nodes | (nodes at: 1) + (nodes at: 3) ]) / mul. mul def: ((prim , $* asParser , mul) ==> [ :nodes | (nodes at: 1) * (nodes at: 3) ]) / prim. prim def: (($( asParser , add , $) asParser) ==> [ :nodes | nodes at: 2 ]) / dec. ^ add end! ! !PPScriptingTest methodsFor: 'examples' stamp: 'lr 6/12/2010 08:30'! expressionParser "Simple demo of scripting an expression parser." | mul prim add dec | add := PPUnresolvedParser new. mul := PPUnresolvedParser new. prim := PPUnresolvedParser new. dec := ($0 - $9). add def: (mul , $+ asParser , add) / mul. mul def: (prim , $* asParser , mul) / prim. prim def: ($( asParser , add , $) asParser) / dec. ^ add end! ! !PPScriptingTest methodsFor: 'examples' stamp: 'lr 10/20/2008 13:27'! straightLineParser | goal stm stmList id char dec exp expList mulExp primExp nonzero num lower upper | goal := PPUnresolvedParser new. stmList := PPUnresolvedParser new. stm := PPUnresolvedParser new. exp := PPUnresolvedParser new. expList := PPUnresolvedParser new. mulExp := PPUnresolvedParser new. primExp := PPUnresolvedParser new. lower := $a - $z. upper := $A - $Z. char := lower / upper. nonzero := $1 - $9. dec := $0 - $9. id := char, ( char / dec ) star. num := $0 asParser / ( nonzero, dec star). goal def: stmList end. stmList def: stm , ( $; asParser, stm ) star. stm def: ( id, ':=' asParser, exp ) / ( 'print' asParser, $( asParser, expList, $) asParser ). exp def: mulExp, ( ( $+ asParser / $- asParser ), mulExp ) star. expList def: exp, ( $, asParser, exp ) star. mulExp def: primExp, ( ( $* asParser / $/ asParser ), primExp ) star. primExp def: id / num / ( $( asParser, stmList, $, asParser, exp, $) asParser ). ^ goal ! ! !PPScriptingTest methodsFor: 'tests' stamp: 'lr 6/12/2010 08:31'! testExpressionInterpreter self assert: self expressionInterpreter parse: '2*(3+4)' to: 14! ! !PPScriptingTest methodsFor: 'tests' stamp: 'lr 6/12/2010 08:31'! testExpressionParser self assert: self expressionParser parse: '2*(3+4)' to: #($2 $* ($( ($3 $+ $4) $)))! ! !PPScriptingTest methodsFor: 'tests' stamp: 'lr 9/17/2008 22:44'! testSLassign self assert: self straightLineParser parse: 'abc:=1' to: #(#($a #($b $c) ':=' #(#(#($1 #()) #()) #())) #())! ! !PPScriptingTest methodsFor: 'tests' stamp: 'lr 6/12/2010 08:27'! testSLprint self assert: self straightLineParser parse: 'print(3,4)' to: #(('print' $( ((($3 ()) ()) () (($, ((($4 ()) ()) ())))) $)) ())! ! !PPSearcherTest methodsFor: 'running' stamp: 'lr 4/29/2010 08:09'! setUp searcher := PPSearcher new! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 14:59'! testAnyPattern | result | searcher matches: PPPattern any do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser initialAnswer: OrderedCollection new. self assert: result size equals: 1. result := searcher execute: $a asParser star initialAnswer: OrderedCollection new. self assert: result size equals: 2. result := searcher execute: $a asParser , $b asParser initialAnswer: OrderedCollection new. self assert: result size equals: 3! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:08'! testClassPattern | result | searcher matches: (PPPattern class: PPLiteralObjectParser) do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser initialAnswer: OrderedCollection new. self assert: result size equals: 1. self assert: (result allSatisfy: [ :each | each class = PPLiteralObjectParser ]). result := searcher execute: 'abc' asParser initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: #any asParser initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: $a asParser / #any asParser , $b asParser initialAnswer: OrderedCollection new. self assert: result size equals: 2. self assert: (result allSatisfy: [ :each | each class = PPLiteralObjectParser ])! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/31/2010 19:16'! testCopyMatchAction | old new | old := $a asParser ==> [ :token | $b ]. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 4/30/2010 08:04'! testCopyMatchDelegate | old new | old := $a asParser token trim. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 9/1/2010 22:08'! testCopyMatchEpsilon | old new | old := nil asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/31/2010 19:17'! testCopyMatchFailure | old new | old := PPFailingParser message: 'problem'. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 4/30/2010 08:04'! testCopyMatchList | old new | old := $a asParser , $b asParser , $c asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 4/30/2010 08:04'! testCopyMatchLiteral | old new | old := $a asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/31/2010 19:18'! testCopyMatchPluggable | old new | old := [ :stream | ] asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/31/2010 19:17'! testCopyMatchPredicate | old new | old := #word asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 1/14/2013 08:37'! testCopyMatchPredicateSequence | old new | old := 'foo' asParser caseInsensitive. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 4/30/2010 08:15'! testCopyMatchRecursiveDelegate | old new | old := PPDelegateParser new. old setParser: old. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 4/30/2010 08:16'! testCopyMatchRecursiveList | old new | old := PPChoiceParser new. old setParsers: (Array with: old). new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/8/2011 20:25'! testCopyMatchRepetition | old new | old := #word asParser star. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/8/2011 20:25'! testCopyMatchRepetitionGreedy | old new | old := #word asParser starGreedy: #digit asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/8/2011 20:25'! testCopyMatchRepetitionLazy | old new | old := #word asParser starLazy: #digit asParser. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing-copy' stamp: 'lr 5/8/2011 20:26'! testCopyMatchRepetitionMinMax | old new | old := #word asParser min: 5 max: 10. new := old copyInContext: Dictionary new. self assert: (old match: old inContext: Dictionary new). self assert: (old match: new inContext: Dictionary new). self deny: (old == new).! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testKindPattern | result | searcher matches: (PPPattern kind: PPLiteralParser) do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser initialAnswer: OrderedCollection new. self assert: result size equals: 1. self assert: (result allSatisfy: [ :each | each class = PPLiteralObjectParser ]). result := searcher execute: 'abc' asParser initialAnswer: OrderedCollection new. self assert: result size equals: 1. self assert: (result allSatisfy: [ :each | each class = PPLiteralSequenceParser ]). result := searcher execute: #any asParser initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: $a asParser / #any asParser , $b asParser initialAnswer: OrderedCollection new. self assert: result size equals: 2. self assert: (result allSatisfy: [ :each | each class = PPLiteralObjectParser ])! ! !PPSearcherTest methodsFor: 'testing-lists' stamp: 'lr 6/4/2010 13:37'! testListInfix | result | searcher matches: PPListPattern any , $a asParser , PPListPattern any do: [ :parser :answer | true ]. result := searcher execute: $a asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $a asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $b asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $b asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser , $b asParser initialAnswer: false. self deny: result! ! !PPSearcherTest methodsFor: 'testing-lists' stamp: 'lr 6/4/2010 13:37'! testListPostfix | result | searcher matches: PPListPattern any , $b asParser do: [ :parser :answer | true ]. result := searcher execute: $a asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $b asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $a asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $b asParser , $a asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $b asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $b asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser , $b asParser initialAnswer: false. self assert: result! ! !PPSearcherTest methodsFor: 'testing-lists' stamp: 'lr 6/4/2010 13:37'! testListPrefix | result | searcher matches: $a asParser , PPListPattern any do: [ :parser :answer | true ]. result := searcher execute: $a asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $b asParser , $b asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $a asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $b asParser , $a asParser initialAnswer: false. self assert: result. result := searcher execute: $a asParser , $a asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $b asParser , $a asParser initialAnswer: false. self deny: result. result := searcher execute: $a asParser , $b asParser , $b asParser initialAnswer: false. self assert: result. result := searcher execute: $b asParser , $a asParser , $b asParser initialAnswer: false. self deny: result. result := searcher execute: $b asParser , $b asParser , $b asParser initialAnswer: false. self deny: result! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 14:59'! testMatchesAny | result | searcher matchesAnyOf: (Array with: $a asParser with: $b asParser) do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser , $b asParser , $c asParser initialAnswer: OrderedCollection new. self assert: result size equals: 2. self assert: result first literal equals: $a. self assert: result last literal equals: $b! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testMultiplePattern | result | searcher matches: $a asParser do: [ :parser :answer | answer first add: parser. answer ]. searcher matches: PPPattern any do: [ :parser :answer | answer second add: parser. answer ]. result := searcher execute: $a asParser , $a asParser , $b asParser initialAnswer: (Array with: OrderedCollection new with: OrderedCollection new). self assert: result first size equals: 2. self assert: result first first literal equals: $a. self assert: result first last literal equals: $a. self assert: result last size equals: 2. self assert: result last first class equals: PPSequenceParser. self assert: result last last literal equals: $b! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testNamePattern | result | searcher matches: (PPPattern name: 'foo') do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: ($a asParser name: 'foo') initialAnswer: OrderedCollection new. self assert: result size equals: 1. self assert: result first name equals: 'foo'. result := searcher execute: ($a asParser name: 'bar') , ($b asParser name: 'foo') initialAnswer: OrderedCollection new. self assert: result size equals: 1. self assert: result first name equals: 'foo'! ! !PPSearcherTest methodsFor: 'testing' stamp: 'lr 4/29/2010 21:03'! testNewPattern self should: [ PPPattern new ] raise: Error! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:00'! testRecursivePattern | recursive | recursive := PPDelegateParser new. recursive setParser: recursive. searcher matches: recursive do: [ :parser :answer | parser ]. self assert: (searcher execute: recursive) equals: recursive. self assert: (searcher execute: $a asParser) isNil. self assert: (searcher execute: $a asParser / $b asParser star) isNil! ! !PPSearcherTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testRepeatedPattern | pattern result | searcher matches: (pattern := PPPattern any) , pattern do: [ :parser :answer | answer add: parser; yourself ]. result := searcher execute: $a asParser , $b asParser initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: $a asParser , $a asParser initialAnswer: OrderedCollection new. self assert: result size equals: 1. result := searcher execute: $a asParser , ($a asParser , $b asParser) initialAnswer: OrderedCollection new. self assert: result isEmpty. result := searcher execute: $b asParser , ($a asParser , $a asParser) initialAnswer: OrderedCollection new. self assert: result size equals: 1! ! !PPTokenTest methodsFor: 'accessing' stamp: 'lr 4/3/2009 08:51'! identifier ^ #word asParser plus token! ! !PPTokenTest methodsFor: 'utilities' stamp: 'lr 3/29/2010 15:34'! parse: aString using: aParser ^ aParser parse: aString! ! !PPTokenTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:15'! testCollection | input result | input := 'foo '. result := self parse: input using: self identifier. self assert: result collection equals: input. self assert: result collection == input! ! !PPTokenTest methodsFor: 'testing-querying' stamp: 'Nicolasanquetil 5/3/2013 14:59'! testColumn | input parser result | input := '1' , (String with: Character cr) , '12' , (String with: Character cr with: Character lf) , '123' , (String with: Character lf) , '1234'. parser := #any asParser token star. result := parser parse: input. result with: #(1 2 1 2 3 4 1 2 3 4 1 2 3 4) do: [ :token :line | self assert: token column equals: line ]! ! !PPTokenTest methodsFor: 'testing-copying' stamp: 'Nicolasanquetil 5/3/2013 15:08'! testCopyFromTo | result other | result := PPToken on: 'abc'. other := result copyFrom: 2 to: 2. self assert: other size equals: 1. self assert: other start equals: 2. self assert: other stop equals: 2. self assert: other collection equals: result collection! ! !PPTokenTest methodsFor: 'testing-comparing' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testEquality | token1 token2 | token1 := self parse: 'foo' using: self identifier. token2 := self parse: 'foo' using: self identifier. self deny: token1 == token2. self assert: token1 equals: token2. self assert: token1 hash equals: token2 hash! ! !PPTokenTest methodsFor: 'testing' stamp: 'lr 2/26/2013 02:50'! testInitialize PPToken initialize! ! !PPTokenTest methodsFor: 'testing-values' stamp: 'Nicolasanquetil 5/3/2013 15:00'! testInputValue | input result | input := 'foo'. result := self parse: input using: self identifier. self assert: result inputValue equals: input. self deny: result inputValue == input! ! !PPTokenTest methodsFor: 'testing-querying' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testLine | input parser result | input := '1' , (String with: Character cr) , '12' , (String with: Character cr with: Character lf) , '123' , (String with: Character lf) , '1234'. parser := #any asParser token star. result := parser parse: input. result with: #(1 1 2 2 2 2 3 3 3 3 4 4 4 4) do: [ :token :line | self assert: token line equals: line ]! ! !PPTokenTest methodsFor: 'testing' stamp: 'lr 4/14/2010 11:44'! testNew self should: [ PPToken new ] raise: Error. ! ! !PPTokenTest methodsFor: 'testing-values' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testParsedValue | input result | input := 'foo'. result := self parse: input using: self identifier. self assert: result parsedValue equals: #($f $o $o)! ! !PPTokenTest methodsFor: 'testing' stamp: 'TudorGirba 3/4/2013 07:10'! testPrinting | result | result := PPToken on: 'var'. self assert: (result printString includesSubstring: 'PPToken[1,3]')! ! !PPTokenTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:01'! testSize | result | result := self parse: 'foo' using: self identifier. self assert: result size equals: 3! ! !PPTokenTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:10'! testStart | result | result := self parse: 'foo' using: self identifier. self assert: result start equals: 1! ! !PPTokenTest methodsFor: 'testing' stamp: 'Nicolasanquetil 5/3/2013 15:17'! testStop | result | result := self parse: 'foo' using: self identifier. self assert: result stop equals: 3! ! !PPTokenTest methodsFor: 'testing' stamp: 'lr 2/26/2013 02:49'! testValue | result | result := PPToken on: 'var'. self should: [ result value ] raise: Notification! ! !PPGrammarRefactoringTest methodsFor: 'accessing' stamp: 'lr 12/7/2011 22:14'! change ^ self refactoring changes! ! !PPGrammarRefactoringTest methodsFor: 'accessing' stamp: 'lr 12/7/2011 22:14'! changes ^ self change changes! ! !PPGrammarRefactoringTest methodsFor: 'utilities' stamp: 'lr 12/7/2011 22:08'! performRefactoring: aRefactoring refactoring := aRefactoring. aRefactoring primitiveExecute! ! !PPGrammarRefactoringTest methodsFor: 'accessing' stamp: 'lr 12/7/2011 22:09'! refactoring ^ refactoring! ! !PPGrammarRefactoringTest methodsFor: 'testing-parsers' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testAddParser self performRefactoring: (PPAddParserRefactoring name: #PPMockParser category: #'PetitGui-Mock'). self assert: self changes size equals: 2. self assert: self changes first class equals: RBAddClassChange. self assert: self changes first definitionClass equals: PPCompositeParser. self assert: self changes first changeClassName equals: #PPMockParser. self assert: self changes first category equals: #'PetitGui-Mock'. self assert: self changes last class equals: RBAddMethodChange. self assert: self changes last parseTree equals: (RBParser parseMethod: 'start ^ self shouldBeImplemented')! ! !PPGrammarRefactoringTest methodsFor: 'testing-parsers' stamp: 'Nicolasanquetil 5/3/2013 15:16'! testAddParserWithSuperclass self performRefactoring: (PPAddParserRefactoring name: #PPMockParser category: #'PetitGui-Mock' superclass: PPArithmeticParser). self assert: self changes size equals: 2. self assert: self changes first class equals: RBAddClassChange. self assert: self changes first definitionClass equals: PPArithmeticParser. self assert: self changes first changeClassName equals: #PPMockParser. self assert: self changes first category equals: #'PetitGui-Mock'. self assert: self changes last class equals: RBAddMethodChange. self assert: self changes last parseTree equals: (RBParser parseMethod: 'start ^ self shouldBeImplemented')! ! !PPGrammarRefactoringTest methodsFor: 'testing-productions' stamp: 'Nicolasanquetil 5/3/2013 15:01'! testDefineProduction self performRefactoring: (PPDefineProdcutionRefactoring onClass: PPArithmeticParser source: 'function ^ #any plus , $( , $) ==> [ :e | 0 ]' protocols: (Array with: #productions)). self assert: self changes size equals: 2. self assert: self changes first class equals: RBAddInstanceVariableChange. self assert: self changes first variable equals: 'function'. self assert: self changes last class equals: RBAddMethodChange. self assert: self changes last parseTree equals: (RBParser parseMethod: 'function ^ #any asParser plus , $( asParser , $) asParser ==> [ :e | 0 ]')! ! !PPGrammarRefactoringTest methodsFor: 'testing-productions' stamp: 'Nicolasanquetil 5/3/2013 15:09'! testExtractProduction self performRefactoring: (PPExtractProdcutionRefactoring onClass: PPArithmeticParser production: #addition interval: (36 to: 60) to: #plusOrMinus). self assert: self changes size equals: 3. self assert: self changes first class equals: RBAddInstanceVariableChange. self assert: self changes first variable equals: 'plusOrMinus'. self assert: self changes second class equals: RBAddMethodChange. self assert: self changes second parseTree equals: (RBParser parseMethod: 'plusOrMinus ^ $+ asParser / $- asParser'). self assert: self changes last class equals: RBAddMethodChange. self assert: self changes last parseTree equals: (RBParser parseMethod: 'addition ^ (factors separatedBy: plusOrMinus trim) foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]')! ! !PPGrammarRefactoringTest methodsFor: 'testing-parsers' stamp: 'Nicolasanquetil 5/3/2013 15:17'! testRemoveParser self performRefactoring: (PPRemoveParserRefactoring onClass: PPArithmeticParser). self assert: self changes size equals: 1. self assert: self changes first class equals: RBRemoveClassChange. self assert: self changes first changeClassName equals: 'PPArithmeticParser'! ! !PPGrammarRefactoringTest methodsFor: 'testing-productions' stamp: 'Nicolasanquetil 5/3/2013 15:01'! testRemoveProduction self performRefactoring: (PPRemoveProdcutionRefactoring onClass: PPArithmeticParser production: #addition). self assert: self changes size equals: 2. self assert: self changes first class equals: RBRemoveMethodChange. self assert: self changes first selector equals: #addition. self assert: self changes last class equals: RBRemoveInstanceVariableChange. self assert: self changes last variable equals: 'addition'! ! !PPGrammarRefactoringTest methodsFor: 'testing-productions' stamp: 'Nicolasanquetil 5/3/2013 15:10'! testRenameProduction self performRefactoring: (PPRenameProdcutionRefactoring onClass: PPArithmeticParser rename: #addition to: #add). self assert: self changes size equals: 3. self assert: self changes first class equals: RBRenameInstanceVariableChange. self assert: self changes first oldName equals: 'addition'. self assert: self changes first newName equals: 'add'. self assert: self changes second class equals: RBAddMethodChange. self assert: self changes second parseTree equals: (RBParser parseMethod: 'add ^ (factors separatedBy: ($+ asParser / $- asParser) trim) foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]'). self assert: self changes last class equals: RBRemoveMethodChange. self assert: self changes last selector equals: #addition! ! !PPParserDebuggerResultTest methodsFor: 'tests' stamp: 'Nicolasanquetil 5/3/2013 15:20'! testArithmetic | parser result | parser := PPArithmeticParser new. result := PPParserDebuggerResult parse: '1 + 2' with: parser. self assert: result children size equals: 1. self assert: result children first result equals: 3! ! !PPParserDebuggerResultTest methodsFor: 'tests' stamp: 'Nicolasanquetil 5/3/2013 15:06'! testNumberParser | parser result | parser := PPArithmeticParser new productionAt: #number. result := PPParserDebuggerResult parse: '1' with: parser. self assert: result children isEmpty. self assert: result result equals: 1! ! !PPParserVisualisationTest methodsFor: 'as yet unclassified' stamp: 'JurajKubelka 5/30/2013 13:53'! testViewAllNamedParsers self shouldnt: [ PPParser new viewAllNamedParsers delete ] raise: Error.! ! !ROAddNameTest methodsFor: 'running' stamp: 'AlexandreBergel 10/3/2012 17:47'! setUp super setUp. element := ROElement on: 42. view := ROView new. view add: element! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/3/2012 17:49'! testAddThenRemove ROAddName toElement: element. ROAddName removeFrom: element. self assert: view numberOfElements = 1. self assert: view elements first == element! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2013 18:45'! testAddTwice ROAddName toElement: element. ROAddName toElement: element. self assert: view numberOfElements = 2. ! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2013 18:41'! testAddition self assert: element view numberOfElements = 1. ROAddName toElement: element. self assert: element view numberOfElements = 2. ROAddName toElement: element. self assert: element view numberOfElements = 2. ! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/17/2013 10:28'! testBlock | addedElement | ROAddName new block: [ :el | 2 printString ]; toElement: element. addedElement := element view elements last. self assert: addedElement model = '2'! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/19/2013 13:55'! testColorAddition | newElement | ROAddName new color: Color red; toElement: element. self assert: element view numberOfElements = 2. newElement := view elements last. self assert: (newElement getShape: ROLabel) color = Color red. ! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/3/2012 17:47'! testRemoveFromEmpty self assert: element view numberOfElements = 1. ROAddName removeFrom: element. self assert: element view numberOfElements = 1.! ! !ROAddNameTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/3/2012 18:17'! testRemoveTwice ROAddName removeFrom: element. ROAddName removeFrom: element. self assert: view numberOfElements = 1. ! ! !ROAllConnectedNodeDraggableTest commentStamp: '' prior: 34277539! A ROAllConnectedNodeDraggableTest is a test class for testing the behavior of ROAllConnectedNodeDraggable! !ROAllConnectedNodeDraggableTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/21/2013 14:27'! testBasic | view oldPoss newPoss | view := ROView new. view addAll: (ROBox green elementsOn: #(1 2 3)). view addAll: (ROLine buildEdgesFromElement: view elements first from: #yourself toAll: #(2 3)). ROTreeLayout on: view elements. view elements first @ ROAllConnectedNodeDraggable. oldPoss := view elements collect: #position. view elements first translateBy: 10 @ 15. newPoss := view elements collect: #position. oldPoss with: newPoss do: [ :p1 :p2 | self assert: p2 = (p1 + (10 @ 15)) ]. ! ! !ROAllRecursivelyConnectedNodeDraggableTest commentStamp: '' prior: 34277729! A ROAllRecursivelyConnectedNodeDraggableTest is a test class for testing the behavior of ROAllRecursivelyConnectedNodeDraggable! !ROAllRecursivelyConnectedNodeDraggableTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/21/2013 21:24'! testBasic | view els firstNode o oldPos newPos | view := ROView new. els := (ROBox green size: 10) elementsOn: (1 to: 20). els do: [ :e | e @ ROPopup ]. view addAll: els. ROLine buildEdgesFromElements: view elements from: #yourself toAll: [ :v | Array with: v + 1 with: v + 2 ]. ROTreeLayout on: view elements. " view open " firstNode := view elements first. o := ROAllRecursivelyConnectedNodeDraggable new. self assert: (o computeAllRecursivelyConnectedNodesOf: firstNode) asSet = view elementsNotEdge allButFirst asSet. firstNode @ ROAllRecursivelyConnectedNodeDraggable. oldPos := view elementsNotEdge collect: #position. firstNode translateBy: 5 @ 10. newPos := view elementsNotEdge collect: #position. oldPos with: newPos do: [ :p1 :p2 | self assert: (p1 + (5 @ 10)) = p2 ] ! ! !ROAllRecursivelyConnectedNodeDraggableTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/21/2013 21:24'! testBasic2 | view els firstNode o | view := ROView new. els := (ROBox green size: 10) elementsOn: (1 to: 3). els do: [ :e | e @ ROPopup ]. view addAll: els. ROLine buildEdgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3 with: 3 -> 1) inView: view. ROTreeLayout on: view elements. " view open " firstNode := view elements first. o := ROAllRecursivelyConnectedNodeDraggable new. self assert: (o computeAllRecursivelyConnectedNodesOf: firstNode) asSet = view elementsNotEdge allButFirst asSet. ! ! !ROAnimatedResizingTest commentStamp: '' prior: 34277921! A ROAnimatedResizingTest is a test class for testing the behavior of ROAnimatedResizing! !ROAnimatedResizingTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/28/2013 18:09'! testBasic | view el | view := ROView new. el := ROBox element. view add: el. self assert: el extent = (5 @ 5). self assert: el position = (0 @ 0). self deny: view hasAnimation. ROAnimatedResizing for: el resize: (10 @ 10). self assert: view hasAnimation. view completeAllAnimations. self assert: el extent = (10 @ 10). self assert: el position = (0 @ 0).! ! !ROAnimatedResizingTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/28/2013 18:17'! testResizeAndFixBottomLeft | view el | view := ROView new. el := ROBox element. view add: el. self assert: el extent = (5 @ 5). self assert: el position = (0 @ 0). self deny: view hasAnimation. ROAnimatedResizing for: el resizeAndFixBottomLeft: (10 @ 10). self assert: view hasAnimation. view completeAllAnimations. self assert: el extent = (10 @ 10). self assert: el position = (0 @ -5).! ! !ROAnimationTest methodsFor: 'running' stamp: 'AlexandreBergel 11/30/2012 19:03'! setUp view := ROView new. element1 := ROElement sprite. element2 := ROElement sprite. view add: element1. view add: element2. animation1 := ROLinearMove new. animation1 for: element1 to: (50 @ 40). animation2 := ROLinearMove new. animation2 for: element2 to: (150 @ 10).! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 21:24'! testAnimation view := ROView new. self deny: view hasAnimation. view addAnimation: animation1. self assert: view hasAnimation.! ! !ROAnimationTest methodsFor: 'strategy' stamp: 'AlexandreBergel 5/2/2013 18:57'! testDefaultStrategy self assert: (ROMotionMove new strategy isAppend)! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/30/2012 19:12'! testDoAnimationCycle view addAnimation: animation1. view addAnimation: animation2. self deny: animation1 hasCompleted. self deny: animation2 hasCompleted. self assert: element1 position = (0 @ 0). self assert: element2 position = (0 @ 0). animation1 nbCycles timesRepeat: [ view doAnimationCycle ]. self assert: animation1 hasCompleted. self assert: animation2 hasCompleted. self assert: element1 position = (50 @ 40). self assert: element2 position = (150 @ 10). ! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 21:21'! testForBy | element | element := ROElement sprite. element translateTo: 50 @ 40. view add: element. ROLinearMove for: element by: 10 @ 5. view doAllAnimationCycles. self assert: element position = (60 @ 45)! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 10:26'! testHasAnimationAfterDoAllAnimationCycles view addAnimation: animation1. view addAnimation: animation2. self assert: view hasAnimation. view doAllAnimationCycles. self deny: view hasAnimation.! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 21:25'! testHasAnimationAfterDoAnimationCycle self assert: view hasAnimation. animation1 nbCycles timesRepeat: [ self assert: view hasAnimation. view doAnimationCycle ]. self assert: animation1 elapsedCycles = animation1 nbCycles. self deny: view hasAnimation.! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 16:17'! testInitialize self assert: animation1 element == element1. self assert: animation1 elapsedCycles = 0! ! !ROAnimationTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/30/2012 17:28'! testNoAnimation self deny: ROView new hasAnimation.! ! !ROAnimationTest methodsFor: 'strategy' stamp: 'AlexandreBergel 5/2/2013 19:03'! testSettingStrategy | animation mergingStrategy | animation := ROMotionMove new. mergingStrategy := ROAnimationExclusive instance. animation strategy: mergingStrategy. self assert: (animation strategy == mergingStrategy)! ! !ROCenterViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:22'! testBasic | view element1 element2 | view := ROView new. view camera windowSize: 500 @ 500. view @ RODraggable. view add: (element1 := ROBox element). element1 extent: 50 @ 50. element1 translateBy: -100 @ -100. view add: (element2 := ROBox element). element2 extent: 50 @ 50. element2 translateBy: 100 @ 100. self assert: view position = (0 @ 0). self assert: element1 position = (-100 @ -100). self assert: element2 position = (100 @ 100). ROFocusView centerView: view. view completeAllAnimations. self assert: view camera position = (-225@ -225). self assert: element1 position = (-100 @ -100). self assert: element2 position = (100 @ 100). ! ! !ROContainerCallbackTest commentStamp: '' prior: 34278074! A ROContainerCallbackTest is a test class for testing the behavior of ROContainerCallback! !ROContainerCallbackTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/2/2013 19:21'! testGridLayout | view c1 c2 el1 el2 | view := ROView new. view callback: (ROContainerCallbackLayout new layout: ROGridLayout new). c1 := ROBorder element. c1 callback: (ROContainerCallbackLayout new layout: ROGridLayout new). view add: c1. c1 add: (el1 := ((ROBox gray extent: (20 @ 20)) element)). c1 add: (ROBox gray extent: (20 @ 20)) element. c2 := ROBorder element. c2 callback: (ROContainerCallbackLayout new layout: ROGridLayout new). view add: c2. c2 add: (el2 := (ROBox red extent: (20 @ 20)) element). c2 add: (ROBox red extent: (20 @ 20)) element. " view open. " self assert: c1 bounds = ((5@5) corner: (65@35)). self assert: el2 absolutePosition = (80 @ 10). el1 extent: 40 @ 40. self assert: el2 absolutePosition = (100 @ 10). self assert: c1 bounds = ( (5@5) corner: (85@55))! ! !ROContainerCallbackTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/14/2013 12:28'! testResize | container element | container := ROElement on: 'container'. container callback: (ROContainerCallbackLayout new layout: ROHorizontalLineLayout new). element := ROElement on: 'child'. element callback: (ROContainerCallbackLayout new layout: ROHorizontalLineLayout new). element extent: (5 @ 5). container add: element. self assert: container extent = (15 @ 15). self assert: element extent = (5 @ 5). element extent: (10 @ 10). self assert: container extent = (20 @ 20). self assert: element extent = (10 @ 10). ! ! !RODynamicEdgeTest methodsFor: 'running' stamp: 'AlexandreBergel 5/17/2013 18:23'! setUp view := ROView new. view add: (el1 := ROBox element). view add: (el2 := ROBox element). view add: (el3 := ROBox element). ROHorizontalLineLayout on: (Array with: el1 with: el2 with: el3). el1 @ (RODynamicEdge toAll: (Array with: el2 with: el3) using: (ROLine arrowed color: Color red))! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/17/2013 18:23'! testDefining el2 @ (RODynamicEdge toAll: [ :el | (Array with: el1 with: el2 with: el3) copyWithout: el ] using: (ROLine arrowed color: Color red)). el2 announce: ROMouseEnter. self assert: view numberOfElements = 5.! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/19/2013 15:37'! testDefiningFromAll | edges | el2 @ (RODynamicEdge fromAll: [ :el | (Array with: el1 with: el2 with: el3) copyWithout: el ] using: (ROLine arrowed color: Color red)). el2 announce: ROMouseEnter. self assert: view numberOfElements = 5. edges := view elementsSuchThat:#isEdge. self assert: (edges allSatisfy: [ :edge | edge to == el2])! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/17/2013 18:23'! testDefiningMultiple el2 @ (RODynamicEdge toAll: [ :el | ((Array with: el1 with: el2 with: el3) copyWithout: el) copyFrom: 2 to: 2 ] using: (ROLine arrowed color: Color red)) @ (RODynamicEdge toAll: [ :el | ((Array with: el1 with: el2 with: el3) copyWithout: el) copyFrom: 2 to: 2 ] using: (ROLine arrowed color: Color blue)). el2 announce: ROMouseEnter. self assert: view numberOfElements = 5.! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/7/2013 01:08'! testEnteringAndExitingElement el1 announce: ROMouseEnter. el1 announce: ROMouseLeave. self assert: view numberOfElements = 3. self assert: (view elementsSuchThat: #isEdge) isEmpty! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/7/2013 01:12'! testEnteringElement el1 announce: ROMouseEnter. self assert: view numberOfElements = 5. self assert: (view elementsSuchThat: #isEdge) size = 2. self assert: (view elementsSuchThat: #isEdge) first from == el1. self assert: (view elementsSuchThat: #isEdge) first to == el2. self assert: (view elementsSuchThat: #isEdge) second from == el1. self assert: (view elementsSuchThat: #isEdge) second to == el3. self assert: (view elementsSuchThat: #isEdge) first shapes first color == Color red! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/7/2013 00:51'! testNoEdge self assert: view elements size = 3.! ! !RODynamicEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 09:27'! testTo el3 @ (RODynamicEdge to: el2). self assert: view numberOfElements = 3. el3 announce: ROMouseEnter. self assert: view numberOfElements = 4. el3 announce: ROMouseLeave. self assert: view numberOfElements = 3.! ! !ROElementTranslatedTest commentStamp: '' prior: 34278229! A ROElementTranslatedTest is a test class for testing the behavior of ROElementTranslated! !ROElementTranslatedTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/21/2013 13:50'! testBasic | t el | t := OrderedCollection new. el := ROElement new. el on: ROElementTranslated do: [ :event | t add: event step ]. el translateTo: 0 @ 0. el translateBy: 5 @ 5. el translateTo: 10 @ 15. self assert: t size = 2. self assert: t asArray = (Array with: 5 @ 5 with: 5 @ 10)! ! !ROKeyDownTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/14/2013 11:43'! testOnMondrianBuilder | pool raw view | pool := OrderedCollection new. view := ROMondrianViewBuilder new. view raw on: ROKeyDown do: [ :event | pool add: event ]. self assert: pool size = 0. view raw announce: (ROKeyDown new). self assert: pool size = 1. view raw announce: (ROKeyDown new). self assert: pool size = 2.! ! !ROKeyDownTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/14/2013 11:50'! testOnMondrianBuilder2 | rawView view t | t := 0. rawView := ROView new. view := ROMondrianViewBuilder view: rawView. rawView on: ROKeyDown do: [ :event | t := t + 1 ]. self assert: t = 0. rawView announce: ROKeyDown. self assert: t = 1. rawView announce: ROKeyDown. self assert: t = 2.! ! !ROKeyDownTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/14/2013 11:39'! testOnView | pool raw view | pool := OrderedCollection new. view := ROView new. view on: ROKeyDown do: [ :event | pool add: event ]. self assert: pool size = 0. view announce: (ROKeyDown new). self assert: pool size = 1. view announce: (ROKeyDown new). self assert: pool size = 2.! ! !ROPharoHTMLExporterTest methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 4/8/2013 11:44'! testExport | view exporter stream | view := ROMondrianViewBuilder new. view nodes: (1 to: 10). view edgesFrom: [ :v | v \\ 2 ]. view treeLayout. view applyLayout. stream := WriteStream on: String new. self assert: stream contents isEmpty. exporter := ROPharoHTMLExporter new view: view raw; exportOnStream: stream. self assert: stream contents notEmpty.! ! !ROQuadTreeTest methodsFor: 'testing' stamp: 'MathieuDehouck 4/25/2013 17:04'! isTrueLeaf: aQuad aQuad isNil ifTrue: [ ^ false ]. aQuad leaf ifTrue: [ ^ aQuad nodes allSatisfy: [ :e | e isNil ] ] ifFalse: [ ^ aQuad nodes anySatisfy: [ :e | self isTrueLeaf: e ] ]! ! !ROQuadTreeTest methodsFor: 'running' stamp: 'AlexandreBergel 5/17/2013 10:26'! setUp super setUp. nodes := OrderedCollection new. (0 to: 10) do: [ :e | nodes add: (ROElement new translateTo: e @ e); add: (ROElement new translateTo: e @ (10 - e)) ]. quad := ROQuadTree withAll: nodes.! ! !ROQuadTreeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 10:13'! testCreate | quadrants points | points := Array with: 0@0 with: 0@5 with: 5@0 with: 5@5. nodes := points collect: [ :pos | ROElement new translateTo: pos ]. quad := ROQuadTree withAll: nodes. quadrants := quad nodes. self assert: (quadrants at: 1) node position = (0@0). self assert: (quadrants at: 2) node position = (5@0). self assert: (quadrants at: 3) node position = (0@5). self assert: (quadrants at: 4) node position = (5@5)! ! !ROQuadTreeTest methodsFor: 'tests' stamp: 'MathieuDehouck 4/25/2013 17:01'! testLeaf self assert: (quad leaf ifTrue: [quad nodes allSatisfy: [ :e | e isNil ] ] ifFalse: [ quad nodes anySatisfy: [ :e | self isTrueLeaf: e ] ] )! ! !ROQuadTreeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 06:11'! testRectangle | points | points := Array with: 0@5 with: 5@0 with: 10@5 with: 5@5. nodes := points collect: [ :e | ROElement new translateTo: e ]. quad := ROQuadTree withAll: nodes. self assert: quad origin = (0@0). self assert: quad corner = (10@10)! ! !ROQuadTreeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 06:13'! testSquare | points | points := Array with: 0@5 with: 5@0 with: 10@5 with: 5@5. nodes := points collect: [ :pos | ROElement new translateTo: pos ]. quad := ROQuadTree withAll: nodes. self assert: quad origin = (0@0). self assert: quad corner = (10@10)! ! !ROQuadTreeTest methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 4/25/2013 16:03'! wellCreated: aQuad aQuad leaf ifTrue: [ aQuad node isNil ifTrue: [ ^ true ] ifFalse: [ ^ (Rectangle origin: aQuad origin corner: aQuad corner) contains: aQuad node position ] ] ifFalse: [ aQuad node isNil ifTrue: [ ^ aQuad nodes allSatisfy: [ :e | self wellCreated: e ] ] ifFalse: [ ^ ((Rectangle origin: aQuad origin corner: aQuad corner) contains: aQuad node position) & (aQuad nodes allSatisfy: [ :e | self wellCreated: e ]) ] ]! ! !RORectangleTreeMapTest commentStamp: '' prior: 34278383! A RORectangleTreeMapTest is a test class for testing the behavior of RORectangleTreeMap! !RORectangleTreeMapTest methodsFor: 'as yet unclassified' stamp: 'RobertoMinelli 10/14/2013 08:10'! test | builder view allBounds viewBounds | view := ROView new. builder := ROTreeMapBuilder new. builder weightBlock: [ :el | el ]. builder origin: 10 @ 10. builder extent: 600 @ 350. builder nodes: (1 to: 76). builder nestingFromAssociations: ((1 to: 76) collect: [ :each | (each // 10) -> each ]). builder drawOn: view . self assert: view numberOfElements = 9. allBounds := ((Array new: 9) at: 1 put: (((722/3)@(2632/13)) corner: (414@364)); at: 2 put: (((1642/3)@294) corner: (614@364)); at: 3 put: (((722/3)@14) corner: (414@(2632/13))); at: 4 put: ((414@294) corner: ((1642/3)@364)); at: 5 put: ((14@14) corner: ((722/3)@(3388/17))); at: 6 put: ((14@(3388/17)) corner: ((722/3)@364)); at: 7 put: ((414@(392/3)) corner: ((3698/7)@294)); at: 8 put: (((3698/7)@(392/3)) corner: (614@294)); at: 9 put: ((414@14) corner: (614@(392/3))); yourself). viewBounds := view elements collect: #bounds. self assert: (viewBounds includesAll: allBounds). self assert: ((viewBounds difference: allBounds) size = 0). self assert: ((allBounds difference: viewBounds) size = 0). self assert: (viewBounds asSet = allBounds asSet).! ! !RORemoveEdgeTest methodsFor: 'running' stamp: 'AlexandreBergel 11/21/2012 08:48'! setUp el1 := ROElement on: 1. el2 := ROElement on: 2. el3 := ROElement on: 3. view := ROView new. view addAll: (Array with: el1 with: el2 with: el3). view add: (ROEdge from: el1 to: el2). view add: (ROEdge from: el1 to: el3). view add: (ROEdge from: el2 to: el3).! ! !RORemoveEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/21/2012 08:49'! testEdges self assert: (view elements select: [ :el | el isEdge ]) size = 3.! ! !RORemoveEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/21/2012 08:49'! testRemoveEdge RORemoveEdge edgesFrom: el1. self assert: (view elements select: [ :el | el isEdge ]) size = 1.! ! !RORemoveEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/21/2012 08:50'! testRemoveEdge2 RORemoveEdge edgesFrom: el3. self assert: (view elements select: [ :el | el isEdge ]) size = 3.! ! !RORemoveEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/21/2012 08:50'! testRemoveEdgeTo RORemoveEdge edgesTo: el3. self assert: (view elements select: [ :el | el isEdge ]) size = 1.! ! !ROResizeTest commentStamp: '' prior: 34278525! A ROResizeTest is a test class for testing the behavior of ROResize! !ROResizeTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/28/2013 16:11'! testResizeHorizontally | view container1 container2 | view := ROView new. container1 := ROBorder elementOn: 'container1'. container2 := ROBorder elementOn: 'container2'. view add: container1. view add: container2. container1 extent: 20 @ 20. ROVerticalLineLayout new gapSize: 0; on: view elements. self assert: container1 bounds = ((5@5) corner: (25@25)). self assert: container2 bounds = ((5@25) corner: (10@30)). ROResize stretchHorizontally: view elements. self assert: container1 bounds = ((5@5) corner: (25@25)). self assert: container2 bounds = ((5@25) corner: (25@30)). ! ! !ROResizeTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/28/2013 16:11'! testResizeVertically | view container1 container2 | view := ROView new. container1 := ROBorder elementOn: 'container1'. container2 := ROBorder elementOn: 'container2'. view add: container1. view add: container2. container1 extent: 20 @ 20. ROHorizontalLineLayout new gapSize: 0; on: view elements. self assert: container1 bounds = ((5@5) corner: (25@25)). self assert: container2 bounds = ((25@5) corner: (30@10)). ROResize stretchVertically: view elements. self assert: container1 bounds = ((5@5) corner: (25@25)). self assert: container2 bounds = ((25@5) corner: (30@25)). ! ! !ROAbstractCanvasTest class methodsFor: 'testing' stamp: 'AlexandreBergel 4/19/2012 12:21'! isAbstract ^ self name == #ROAbstractCanvasTest ! ! !ROAbstractCanvasTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:20'! canvasClass ^ ROAbstractCanvas! ! !ROAbstractCanvasTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/19/2012 12:20'! testTransformationBijection | canvas camera | camera := ROCamera new realExtent: 100@50; extent: 200@100. canvas := self canvasClass onCamera: camera. self assert: (canvas realToVirtualPoint: (canvas virtualToRealPoint: 0@0)) = (0 @ 0). self assert: (canvas realToVirtualPoint: (canvas virtualToRealPoint: -100 @ -50)) = (-100 @ -50). self assert: (canvas realToVirtualPoint: (canvas virtualToRealPoint: 100 @ 50)) = (100 @ 50). self assert: (canvas realToVirtualPoint: (canvas virtualToRealPoint: -10@ -6)) = (-10 @ -6). self assert: (canvas realToVirtualPoint: (canvas virtualToRealPoint: 40 @ 50)) = (40 @ 50). self assert: (canvas realToVirtualRectangle: (canvas virtualToRealRectangle: (-10 @ -6 corner: 40 @ 50))) = (-10 @ -6 corner: 40 @ 50).! ! !ROPharoCanvasTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:20'! canvasClass ^ ROPharoCanvas ! ! !ROPharoCanvasTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/11/2012 14:22'! testMovingCameraUpAndDown | view el b bitmap1 bitmap2 cameraExtent1 | view := ROView new. view add: (el := ROElement sprite). "view open." "We do a visu" b := el bounds. self assert: (el extent = b extent). self assert: (view camera virtualToRealRectangle: b) = ( 0@0 corner: 50@50). cameraExtent1 := view camera bounds. bitmap1 := view bitmap. "we move up" view camera moveUp; moveUp; moveUp. view signalUpdate. self assert: (el extent = b extent). self assert: (view camera virtualToRealRectangle: b) extent < b extent. self assert: (view camera bounds ~= cameraExtent1). bitmap2 := view bitmap. "The bitmap should be different" self assert: (bitmap1 bits ~= bitmap2 bits). " bitmap1 asMorph openInWindow bitmap2 asMorph openInWindow"! ! !ROPharoCanvasTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/11/2013 15:27'! testRendering "Source code: ROMondrianExample>>orthoVerticalLineOn:" "Preambule. It includes the initialization. " | view rawView | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "-------------" "-------------" view shape rectangle size: 20. view nodes: (1 to: 20). view shape: (ROOrthoVerticalLineShape new). view edgesFrom: [ :i | i \\ 3 ]. view treeLayout. "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view raw camera windowSize: 500 @ 500. view raw bitmap. ! ! !ROPharoCanvasTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/11/2013 15:55'! testRendering2 "Source code: ROMondrianExample>>umlLikeOn:" "Preambule. It includes the initialization. " | view rawView | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "-------------" "-------------" view shape rectangle withText. view nodes: (ROShape withAllSubclasses). view shape: (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 1 )). view edgesFrom: #superclass. view treeLayout. "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view raw camera windowSize: 500 @ 500. view raw bitmap. ! ! !ROAbstractLabelTest class methodsFor: 'testing' stamp: 'AlexandreBergel 9/20/2012 12:00'! isAbstract ^ self name == #ROAbstractLabelTest! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 9/20/2012 11:58'! classToTest self subclassResponsibility ! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/29/2013 23:56'! drawOnMultilineForTrace self subclassResponsibility! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 6/12/2013 12:16'! drawOnMultilineForTraceVW self subclassResponsibility! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/29/2013 23:59'! drawOnMultilineWithTextPaddingForTrace self subclassResponsibility! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 6/12/2013 12:32'! drawOnMultilineWithTextPaddingForTraceVW self subclassResponsibility ! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/29/2013 23:06'! drawOnWithTextPaddingForTrace self subclassResponsibility ! ! !ROAbstractLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/30/2013 00:52'! drawOnZeroPaddingForTrace self subclassResponsibility ! ! !ROAbstractLabelTest methodsFor: 'ui' stamp: 'AlexandreBergel 6/12/2013 11:03'! drawOnZeroPaddingForTraceVW ^ #(#(#drawStringColor '3' '(-1@-4)' 14 'Color black'))! ! !ROAbstractLabelTest methodsFor: 'text cache' stamp: 'JurajKubelka 5/17/2013 12:24'! testAdaptedTextCache | label el trigger | label := self classToTest new. trigger := 0. label text: [ :e | trigger := trigger + 1. e model ]. el := ROElement on: '2 2'. self deny: label textCache hasAdaptedText. self assert: (label textAdaptedFor: el) = '2 2'. self assert: label textCache hasAdaptedText. self assert: label textCache adaptedText = '2 2'. self assert: trigger = 1. self assert: (label textAdaptedFor: el) = '2 2'. self assert: trigger = 1. ! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'AlexandreBergel 5/22/2013 11:11'! testBounds | el | el := ROLabel elementOn: 'hello world'. self assert: el bounds ~= ( 0@0 corner: 5@5). self assert: el extent = (self classToTest new preferedExtentFor: el).! ! !ROAbstractLabelTest methodsFor: 'text cache' stamp: 'AlexandreBergel 5/31/2013 18:03'! testCache | shape | shape := self classToTest new. shape text: 'hello'. self assert: (shape textFor: ROElement new) = 'hello'. shape text: 'world'. self assert: (shape textFor: ROElement new) = 'world'. ! ! !ROAbstractLabelTest methodsFor: 'colors' stamp: 'AlexandreBergel 10/14/2012 19:12'! testColorFor | rawView el1 shape | rawView := ROView new. el1 := ROElement on: 1. el1 extent: 50@50. el1 + (shape := self classToTest new color: [ :element | element model odd ifTrue: [ Color red ] ifFalse: [ Color blue ] ]). rawView add: el1. self assert: (shape colorFor: el1) = Color red.! ! !ROAbstractLabelTest methodsFor: 'ui' stamp: 'AlexandreBergel 6/12/2013 17:16'! testDrawOnFor | label el canvas trigger | label := self classToTest new. canvas := ROTracingCanvas new. trigger := 0. label text: [ :e | trigger := trigger + 1. e model + 1 ]. el := ROElement on: 2. label drawOn: canvas for: el. self assert: trigger = 1. "self assert: ((canvas trace = self drawOnForTracePharo) or: [ canvas trace = self drawOnForTraceVW ])." label drawOn: canvas for: el. self assert: trigger = 1.! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'AlexandreBergel 9/20/2012 12:01'! testDynamicBounds | el extent shape extentFromShape bounds | el := ROElement on: 'hello'. el + self classToTest. shape := el getShape: self classToTest. bounds := el bounds. el model: 'hello world'. self assert: (shape preferedExtentFor: el) = el extent. self assert: el bounds origin = bounds origin. self assert: el bounds extent x > bounds extent x. self assert: el bounds extent y = bounds extent y.! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'AlexandreBergel 9/20/2012 12:01'! testDynamicExtent | el extent shape extentFromShape | el := ROElement on: 'hello'. el + self classToTest. shape := el getShape: self classToTest. extent := el extent. extentFromShape := shape preferedExtentFor: el. self assert: extent = extentFromShape. el model: 'hello world'. self assert: (shape preferedExtentFor: el) x > extentFromShape x. self assert: (shape preferedExtentFor: el) y = extentFromShape y. self assert: (shape preferedExtentFor: el) = el extent. self assert: el extent x > extent x. self assert: el extent y = extent y. ! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'JurajKubelka 5/30/2013 00:33'! testHeightFor | label element1 element2 | label := self classToTest new. element1 := ROElement on: 'abcdefhhijk'. element2 := ROElement on: 'abcdefghijk abc def'. self assert: (label heightFor: element1) = ((label fontFor: element1) height + (2 * label textVerticalPadding)). label := self classToTest new. self assert: (label heightFor: element2) = ((label fontFor: element2) height * 3 + (2 * label interlineSpace) + (2 * label textVerticalPadding)).! ! !ROAbstractLabelTest methodsFor: 'size minimum' stamp: 'AlexandreBergel 9/14/2013 18:39'! testMinimumSize | el | el := ROElement on: 'hello'. el extent: (900 @ 450). self assert: el extent = (900 @ 450). "When we add a new shape, its size should not change" el + self classToTest. self assert: el extent = (900 @ 450).! ! !ROAbstractLabelTest methodsFor: 'size minimum' stamp: 'AlexandreBergel 9/20/2012 12:01'! testMinimumSize2 | el | el := ROElement on: 'hello'. el extent: (3 @ 3). self assert: el extent = (3 @ 3). el + self classToTest. self assert: el extent > (3 @ 3).! ! !ROAbstractLabelTest methodsFor: 'lines' stamp: 'AlexandreBergel 5/22/2013 11:12'! testMultilines " self debug: #testMultilines " | view elementWith2Lines elementWith1Line | view := ROView new. view add: (elementWith2Lines := ROLabel elementOn: 'hello world'). view add: (elementWith1Line := ROShape elementOn: 'bonjour le monde!!'). "view openInWindow." self assert: (elementWith2Lines height >= (elementWith1Line height * 2))! ! !ROAbstractLabelTest methodsFor: 'lines' stamp: 'JurajKubelka 5/17/2013 21:51'! testRawLinesOf | label | label := self classToTest new. self assert: (label rawLinesOf: 'hello world bravo') = #('hello' 'world' ' bravo')! ! !ROAbstractLabelTest methodsFor: 'lines' stamp: 'JurajKubelka 5/17/2013 21:52'! testRawLinesOfEmptyString | label | label := self classToTest new. self assert: (label rawLinesOf: '') = #()! ! !ROAbstractLabelTest methodsFor: 'lines' stamp: 'JurajKubelka 5/17/2013 21:52'! testRawLinesOfWithTrailingCR | label | label := self classToTest new. self assert: (label rawLinesOf: 'hello world bravo ') = #('hello' 'world' ' bravo')! ! !ROAbstractLabelTest methodsFor: 'white char' stamp: 'AlexandreBergel 10/17/2012 08:29'! testReplaingWhiteCharacter | label element str | label := self classToTest new. element := ROElement on: (str := ' abc def'). self assert: (label textFor: element) = str. self assert: (label textAdaptedFor: element) = ' abc def' ! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'JurajKubelka 10/11/2013 16:18'! testSize | el1 el2 | el1 := ROElement on: 'hello'. el2 := ROElement on: 'h'. self assert: el1 bounds = el2 bounds. self assert: el1 bounds = ( 0 @ 0 corner: 5 @ 5). el1 + self classToTest. el2 + self classToTest. self assert: el1 extent = (self classToTest new preferedExtentFor: el1). self assert: el2 extent = (self classToTest new preferedExtentFor: el2). self assert: el1 bounds ~= el2 bounds. self assert: el1 bounds height = el2 bounds height. self assert: el1 bounds width > el2 bounds width.! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'JurajKubelka 4/30/2013 17:57'! testSize2 | el1 el2 label1 | el1 := ROElement on: 'hello'. el2 := ROElement on: 'hello'. label1 := self classToTest new fontSize: 50. el1 + label1. el2 + self classToTest. self assert: el1 extent = (label1 preferedExtentFor: el1). self assert: el2 extent = (self classToTest new preferedExtentFor: el2). self assert: el1 bounds ~= el2 bounds. self assert: el1 bounds height > el2 bounds height. self assert: el1 bounds width > el2 bounds width.! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'AlexandreBergel 8/29/2013 10:09'! testSize3 | el1 el2 el3 text1 text2 text3 tmpFont | text1 := 'iiiiiiiiii'. text2 := 'WWWWW'. text3 := text1, ROPlatform current newLine, text2. el1 := ROElement on: text1. el2 := ROElement on: text2. el3 := ROElement on: text3. el1 + self classToTest. el2 + self classToTest. el3 + self classToTest. self assert: el1 extent = (self classToTest new preferedExtentFor: el1). self assert: el2 extent = (self classToTest new preferedExtentFor: el2). self assert: el3 extent = (self classToTest new preferedExtentFor: el3). self assert: el1 bounds ~= el2 bounds. self assert: el1 bounds height = el2 bounds height. "We can't have that. This depends on the used font" "self assert: el1 bounds width < el2 bounds width." self assert: el1 bounds ~= el3 bounds. tmpFont := self classToTest new fontFor: el1 with: el1 view camera. self assert: el1 bounds height + self classToTest new interlineSpace + tmpFont height = el3 bounds height. "We can't have that. This depends on the used font" "self assert: el1 bounds width < el3 bounds width." self assert: el2 bounds ~= el3 bounds. tmpFont := self classToTest new fontFor: el2 with: el2 view camera. self assert: el2 bounds height + self classToTest new interlineSpace + tmpFont height = el3 bounds height. "We can't have that. This depends on the used font" "self assert: el2 bounds width = el3 bounds width."! ! !ROAbstractLabelTest methodsFor: 'text cache' stamp: 'JurajKubelka 5/17/2013 12:24'! testTextCache | label el trigger | label := self classToTest new. trigger := 0. label text: [ :e | trigger := trigger + 1. e model + 1 ]. el := ROElement on: 2. self deny: label textCache hasText. self assert: (label textFor: el) = '3'. self assert: label textCache hasText. self assert: label textCache text = '3'. self assert: trigger = 1. self assert: (label textFor: el) = '3'. self assert: trigger = 1. ! ! !ROAbstractLabelTest methodsFor: 'text cache' stamp: 'AlexandreBergel 6/12/2013 11:01'! testTextCache2 | label el trigger | label := self classToTest new. trigger := 0. label text: [ :e | trigger := trigger + 1. e model + 1 ]. el := ROElement on: 2. el + label. self assert: (label textFor: el) = '3'. self assert: trigger = 1. el model: 4. self deny: label textCache hasText. self assert: (label textFor: el) = '5'. self assert: label textCache hasText. self assert: trigger = 2. self assert: (label textFor: el) = '5'. self assert: trigger = 2. ! ! !ROAbstractLabelTest methodsFor: 'text cache' stamp: 'AlexandreBergel 5/31/2013 18:01'! testTextFor | label el | label := self classToTest new. label text: [ :e | e model + 1 ]. el := ROElement on: 2. self assert: (label textFor: el) = '3'! ! !ROAbstractLabelTest methodsFor: 'ui' stamp: 'AlexandreBergel 6/12/2013 17:17'! testTextPadding | label el canvas extent1 extent2 | el := ROElement on: 2. label := self classToTest new. label text: [ :e | e model + 1 ]. canvas := ROTracingCanvas new. label textPadding: 0. label drawOn: canvas for: el. extent1 := label extentFor: el. "self assert: ((canvas trace = self drawOnZeroPaddingForTrace) or: [ canvas trace = self drawOnZeroPaddingForTraceVW ])." canvas := ROTracingCanvas new. label textPadding: 10. label drawOn: canvas for: el. extent2 := label extentFor: el. self deny: extent1 = extent2. self assert: extent2 = (extent1 + 20). "self assert: ((canvas trace = self drawOnWithTextPaddingForTrace) or: [ canvas trace = self drawOnZeroPaddingForTraceVW ])."! ! !ROAbstractLabelTest methodsFor: 'ui' stamp: 'AlexandreBergel 6/12/2013 17:17'! testTextPaddingMultiline | label el canvas extent1 extent2 text | text := 'First line Second line Third line Fourth line Fifth line Sixth line'. el := ROElement on: text. label := self classToTest new. label text: [ :e | e model ]. canvas := ROTracingCanvas new. label textPadding: 0. label drawOn: canvas for: el. extent1 := label extentFor: el. "self assert: (canvas trace = self drawOnMultilineForTrace or: [ canvas trace = self drawOnMultilineForTraceVW ])." canvas := ROTracingCanvas new. label textPadding: 10. label drawOn: canvas for: el. extent2 := label extentFor: el. self deny: extent1 = extent2. self assert: extent2 = (extent1 + 20). "self assert: (canvas trace = self drawOnMultilineWithTextPaddingForTrace or: [ canvas trace = self drawOnMultilineWithTextPaddingForTraceVW ])."! ! !ROAbstractLabelTest methodsFor: 'size' stamp: 'JurajKubelka 5/17/2013 21:47'! testWidthFor | label element1 element2 | label := self classToTest new. element1 := ROElement on: 'abcdefghijk abc def'. element2 := ROElement on: 'abcdefghijk'. self assert: (label widthFor: element1) = (label widthFor: element2).! ! !ROCenteredLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 9/20/2012 12:02'! classToTest ^ ROCenteredLabel! ! !ROCenteredLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/30/2013 00:23'! drawOnMultilineForTrace ^ #(#(#drawStringColor 'First line' '(-23@-47)' 14 'Color black') #(#drawStringColor 'Second line' '(-33@-30)' 14 'Color black') #(#drawStringColor 'Third line' '((-51/2)@-13)' 14 'Color black') #(#drawStringColor 'Fourth line' '(-29@4)' 14 'Color black') #(#drawStringColor 'Fifth line' '(-23@21)' 14 'Color black') #(#drawStringColor 'Sixth line' '(-25@38)' 14 'Color black'))! ! !ROCenteredLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 6/12/2013 12:30'! drawOnMultilineForTraceVW ^ #(#(#drawStringColor 'First line' '((-45 / 2)@-47)' 14 'Color black') #(#drawStringColor 'Second line' '((-63 / 2)@-30)' 14 'Color black') #(#drawStringColor 'Third line' '(-24@-13)' 14 'Color black') #(#drawStringColor 'Fourth line' '(-28@4)' 14 'Color black') #(#drawStringColor 'Fifth line' '((-45 / 2)@21)' 14 'Color black') #(#drawStringColor 'Sixth line' '((-49 / 2)@38)' 14 'Color black'))! ! !ROCenteredLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/30/2013 00:25'! drawOnMultilineWithTextPaddingForTrace ^ self drawOnMultilineForTrace! ! !ROCenteredLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 6/12/2013 12:32'! drawOnMultilineWithTextPaddingForTraceVW ^ #(#(#drawStringColor 'First line' '((-45 / 2)@-47)' 14 'Color black') #(#drawStringColor 'Second line' '((-63 / 2)@-30)' 14 'Color black') #(#drawStringColor 'Third line' '(-24@-13)' 14 'Color black') #(#drawStringColor 'Fourth line' '(-28@4)' 14 'Color black') #(#drawStringColor 'Fifth line' '((-45 / 2)@21)' 14 'Color black') #(#drawStringColor 'Sixth line' '((-49 / 2)@38)' 14 'Color black'))! ! !ROLabelTest methodsFor: 'hooks' stamp: 'AlexandreBergel 9/20/2012 11:58'! classToTest ^ ROLabel! ! !ROLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/29/2013 23:59'! drawOnMultilineForTrace ^ #(#(#drawStringColor 'First line' '(0@0)' 14 'Color black') #(#drawStringColor 'Second line' '(0@17)' 14 'Color black') #(#drawStringColor 'Third line' '(0@34)' 14 'Color black') #(#drawStringColor 'Fourth line' '(0@51)' 14 'Color black') #(#drawStringColor 'Fifth line' '(0@68)' 14 'Color black') #(#drawStringColor 'Sixth line' '(0@85)' 14 'Color black'))! ! !ROLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/30/2013 00:13'! drawOnMultilineWithTextPaddingForTrace ^ #(#(#drawStringColor 'First line' '(10@10)' 14 'Color black') #(#drawStringColor 'Second line' '(10@27)' 14 'Color black') #(#drawStringColor 'Third line' '(10@44)' 14 'Color black') #(#drawStringColor 'Fourth line' '(10@61)' 14 'Color black') #(#drawStringColor 'Fifth line' '(10@78)' 14 'Color black') #(#drawStringColor 'Sixth line' '(10@95)' 14 'Color black'))! ! !ROLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/29/2013 23:07'! drawOnWithTextPaddingForTrace ^ #(#(#drawStringColor '3' '(10@10)' 14 'Color black'))! ! !ROLabelTest methodsFor: 'hooks' stamp: 'JurajKubelka 5/30/2013 00:52'! drawOnZeroPaddingForTrace ^ #(#(#drawStringColor '3' '(0@0)' 14 'Color black'))! ! !ROLabelTest methodsFor: 'size' stamp: 'JurajKubelka 10/11/2013 16:46'! testSize | label border | border := ROBorder gray. label := ROLabel elementOn: 'Hello World'. label + border. self assert: label extent = ((label getShape: ROLabel) extentFor: label). self assert: (border extentFor: label) = border defaultExtent. self assert: label extent >= (50 @ 20). ! ! !ROAbstractPopupTest class methodsFor: 'testing' stamp: 'AlexandreBergel 4/5/2013 14:43'! isAbstract ^ self name = #ROAbstractPopupTest! ! !ROAbstractPopupTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/5/2013 14:42'! classToTest self subclassResponsibility! ! !ROAbstractPopupTest methodsFor: 'running' stamp: 'AlexandreBergel 4/5/2013 14:23'! setUp super setUp. view := ROView new.! ! !ROAbstractPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/5/2013 14:54'! testDefaultReceivingView | el | view := ROView new. el := ROElement on: 123. el @ self classToTest. view add: el. self assert: view numberOfElements = 1. el announce: ROMouseEnter. self assert: view numberOfElements = 2. el announce: ROMouseLeave. self assert: view numberOfElements = 1.! ! !ROAbstractPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/5/2013 14:54'! testReceivingView | el view2 | view := ROView new. view2 := ROView new. el := ROElement on: 123. el @ (ROPopup new receivingView: view2). view add: el. self assert: view numberOfElements = 1. self assert: view2 numberOfElements = 0. el announce: ROMouseEnter. self assert: view numberOfElements = 1. self assert: view2 numberOfElements = 1. el announce: ROMouseLeave. self assert: view numberOfElements = 1. self assert: view2 numberOfElements = 0. ! ! !ROAbstractPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/5/2013 14:54'! testReceivingViewWithStack | el stack | view := ROView new. stack := ROViewStack new. el := ROElement on: 123. el @ (ROPopup new receivingView: stack). view add: el. stack addView: view. self assert: view numberOfElements = 1. self assert: stack numberOfElements = 0. el announce: ROMouseEnter. self assert: view numberOfElements = 1. self assert: stack numberOfElements = 1. el announce: ROMouseLeave. self assert: view numberOfElements = 1. self assert: stack numberOfElements = 0. ! ! !ROPopupTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/5/2013 14:42'! classToTest ^ ROPopup! ! !ROPopupTest methodsFor: 'running' stamp: 'AlexandreBergel 4/5/2013 14:23'! setUp super setUp. el := ROElement new size: 50. el @ RODraggable. el @ (popup := ROPopup text: 'balh'). view add: (el + ROBox). view camera windowSize: 500 @ 500 ! ! !ROPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/19/2013 20:00'! testAfterCreationBlock view := ROView new. el := ROBox element. el @ (ROPopup new afterCreationBlock: [:e | e attributes at: #foo put: 'bar' ]). view add: el. el announce: ROMouseEnter. self assert: (view elements last attributes at: #foo) = 'bar'! ! !ROPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/19/2013 20:02'! testAfterCreationBlock2 view := ROView new. el := ROBox element. el @ (ROPopup new afterCreationBlock: [:e | e zIndex: 5 ]). view add: el. el announce: ROMouseEnter. self assert: view elements last zIndex = 5! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:12'! testBottomLeft self assert: ((popup closestPositionOf: el from: 4 @ 504 in: view) = ((4 @ 504) + (popup popupOffset x @ popup popupOffset y negated) - (0 @ el height)))! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:13'! testBottomRight self assert: ((popup closestPositionOf: el from: 504 @ 504 in: view) = ((504 @ 504) - popup popupOffset - (el width @ el height)))! ! !ROPopupTest methodsFor: 'tests' stamp: 'DR 1/15/2013 22:10'! testMouseEnteringAndDragNode | popupElement | view := ROView new. el := ROElement new. el @ ROPopup. view add: el. el announce: ROMouseEnter. self assert: view elements size = 2. popupElement := (view elements copyWithout: el) first. el announce: (ROMouseDragging step: 10 @ 10). self assert: view elements size = 1.! ! !ROPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 1/2/2013 09:14'! testPositionInAStack | stack element | element := (ROElement on: 'an element'). element + (ROLabel new color: Color gray) @ ROPopup. view := ROView new. view add: element. view @ RODraggable. stack := ROViewStack new. stack addView: view. " stack open" stack camera windowSize: 500 @ 500. view camera windowSize: 500 @ 500. self assert: (view numberOfElements = 1). element announce: ROMouseEnter. self assert: (view numberOfElements = 2). popup := (view elementsSuchThat: [ :ell | ell ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset). "The popup is not displayed anymore" element announce: ROMouseLeave. self assert: (view numberOfElements = 1). element translateBy: 40@60. element announce: (ROMouseEnter new position: 45 @ 65; realPosition: 45 @ 65). popup := (view elementsSuchThat: [ :ell | ell ~~ element ]) first. self assert: popup position = ((45 @ 65) + ROPopup defaultPopupOffset).! ! !ROPopupTest methodsFor: 'tests' stamp: 'AlexandreBergel 1/2/2013 09:14'! testPositionInAStack2 | stack element | element := (ROElement on: 'an element'). element + (ROLabel new color: Color gray) @ ROPopup. view := ROView new. view add: element. view @ RODraggable. stack := ROViewStack new. stack addView: view. " stack open" stack camera windowSize: 500 @ 500. view camera windowSize: 500 @ 500. self assert: (view numberOfElements = 1). element announce: ROMouseEnter. self assert: (view numberOfElements = 2). popup := (view elementsSuchThat: [ :ell | ell ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset). "The popup is not displayed anymore" element announce: ROMouseLeave. self assert: (view numberOfElements = 1). view translateBy: 40@60. element announce: (ROMouseEnter new realPosition: 40@60). popup := (view elementsSuchThat: [ :ell | ell ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset).! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 10/3/2013 18:23'! testPositionOfPopup | event center viewForPopup | view := ROView new. el := (ROBox new size: 40) element @ RODraggable. "popup := ROPopup text: (1 to: 10) asArray printString." viewForPopup := ROView new. viewForPopup add: (ROBox green extent: 200 @ 20) element. popup := ROPopupView new view: viewForPopup. el @ popup. view add: el. el translateTo: 63.0 @ 76.0. " view open. " view camera windowSize: (264 @ 287). "We simulate the mouse is at the center of the element" center := el bounds center. event := ROMouseEnter new realPosition: center. self assert: (popup closestPositionOf: viewForPopup elements first from: event realPosition in: view) = (center + popup popupOffset). " el announce: event. " ! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 10/3/2013 18:08'! testPositionOfPopup2 | event center | view := ROView new. el := (ROBox new size: 40) element @ RODraggable. popup := ROPopup text: (1 to: 10) asArray printString. el @ popup. view add: el. el translateTo: 63.0 @ 76.0. "We simulate the mouse is at the center of the element" center := el bounds center. event := ROMouseEnter new realPosition: center. self assert: (popup closestPositionOf: el from: event realPosition in: view) = (center + popup popupOffset). ! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:07'! testTopLeft self assert: ((popup closestPositionOf: el from: 4 @ 4 in: view)= ((4 @ 4) + (popup popupOffset)))! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 4/6/2013 22:23'! testTopLeftWithBigPopup | popupElement | popup := ROPopupView new view: (ROView new add: ((ROElement new extent: 800 @ 800) + ROBox)). popupElement := popup createPopupFor: el. self assert: ((popup closestPositionOf: popupElement from: 4 @ 4 in: view)= ((4 @ 4) + (popup popupOffset)))! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:06'! testTopLeftWithEvents | popupElement | el announce: (ROMouseEnter new realPosition: 4 @ 4). popupElement := view elements second. self assert: (popupElement position = ((4 @ 4) + (popup popupOffset)))! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:11'! testTopRight self assert: ((popup closestPositionOf: el from: 500 @ 4 in: view) = ((500 @ 4) + (popup popupOffset x negated @ popup popupOffset y) - (el width @ 0)))! ! !ROPopupTest methodsFor: 'positionning popup' stamp: 'AlexandreBergel 1/2/2013 09:15'! testTopRightWithEvents | popupElement viewWidth | viewWidth := view camera windowSize x. el announce: (ROMouseEnter new realPosition: viewWidth @ 4). popupElement := view elements second. self assert: (popupElement position = ((viewWidth @ 4) + (popup popupOffset x negated @ popup popupOffset y) - (popupElement width @ 0)))! ! !ROPopupViewTest methodsFor: 'hooks' stamp: 'AlexandreBergel 4/5/2013 14:43'! classToTest ^ ROPopupView! ! !ROPopupViewTest methodsFor: 'animation' stamp: 'AlexandreBergel 5/19/2013 19:09'! notWorkingTestAnimation | element | view := ROMondrianViewBuilder new. view interaction popupView: [ :e :v | v shape rectangle size: 80; fillColor: Color black. ROColorAlphaFading new for: (v node: 123) nbCycles: 200. ]. view shape label. element := view node: 'Hello'. self assert: view raw numberOfElements = 1. self assert: view stack numberOfElements = 0. self assert: view stack numberOfAnimations = 0. element announce: ROMouseEnter. self assert: view stack numberOfElements = 1. self assert: view stack numberOfAnimations = 1.! ! !ROPopupViewTest methodsFor: 'running' stamp: 'AlexandreBergel 4/5/2013 14:23'! setUp | el | super setUp. popupView := ROView new. el := (ROElement new extent: 50@60)+ (ROBox new color: Color blue). popupView add: el. ! ! !ROPopupViewTest methodsFor: 'animation' stamp: 'AlexandreBergel 5/22/2013 18:23'! testAnimation | element | view := ROMondrianViewBuilder new. view interaction popupView: [ :e :v | v shape rectangle size: 80; fillColor: Color black. ROColorAlphaFading new for: (v node: 123) nbCycles: 200. ]. view shape label. element := view node: 'Hello'. self assert: view raw numberOfElements = 1. self assert: view stack numberOfElements = 0. self assert: view stack numberOfAnimations = 0. element announce: ROMouseEnter. self assert: view stack numberOfElements = 1. " self assert: view stack numberOfAnimations = 1."! ! !ROPopupViewTest methodsFor: 'position in a stack' stamp: 'AlexandreBergel 1/2/2013 09:16'! testPositionInAStack | stack element | element := (ROElement on: 'an element'). element + (ROLabel new color: Color gray) @ ROPopup. view := ROView new. view add: element. view @ RODraggable. view @ RODraggable. stack := ROViewStack new. stack addView: view. " stack open" stack camera windowSize: 500 @ 500. view camera windowSize: 500 @ 500. self assert: (view numberOfElements = 1). element announce: ROMouseEnter. self assert: (view numberOfElements = 2). popup := (view elementsSuchThat: [ :el | el ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset). "The popup is not displayed anymore" element announce: ROMouseLeave. self assert: (view numberOfElements = 1). element translateBy: 40@60. element announce: (ROMouseEnter new realPosition: 40 @ 60). popup := (view elementsSuchThat: [ :el | el ~~ element ]) first. self assert: popup position = ((40 @ 60) + ROPopup defaultPopupOffset).! ! !ROPopupViewTest methodsFor: 'position in a stack' stamp: 'AlexandreBergel 1/2/2013 09:16'! testPositionInAStack2 | stack element | element := (ROElement on: 'an element'). element + (ROLabel new color: Color gray) @ ROPopup. view := ROView new. view add: element. view @ RODraggable. view @ RODraggable. stack := ROViewStack new. stack addView: view. " stack open" stack camera windowSize: 500 @ 500. view camera windowSize: 500 @ 500. self assert: (view numberOfElements = 1). element announce: ROMouseEnter. self assert: (view numberOfElements = 2). popup := (view elementsSuchThat: [ :el | el ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset). "The popup is not displayed anymore" element announce: ROMouseLeave. self assert: (view numberOfElements = 1). view translateBy: 40@60. element announce: (ROMouseEnter new realPosition: 40@60). popup := (view elementsSuchThat: [ :el | el ~~ element ]) first. self assert: popup position = (element position + ROPopup defaultPopupOffset).! ! !ROPopupViewTest methodsFor: 'receiving view' stamp: 'AlexandreBergel 1/2/2013 09:18'! testPositionWithReceivingView | el receivingView | receivingView := ROView new. view := ROView new. el := ROElement sprite. el translateTo: 50@25. el @ (ROPopup new receivingView: receivingView). view add: el. view camera windowSize: 500 @ 500. receivingView camera windowSize: 500 @ 500. el announce: ROMouseEnter. popup := receivingView elements first. self assert: popup position = (10@10).! ! !ROPopupViewTest methodsFor: 'size' stamp: 'AlexandreBergel 7/7/2012 07:48'! testSize | v2 raw el | v2 := ROView new. v2 add: ((ROElement new extent: 90@20) + ROBox green). raw := ROView new. el := ROElement new extent: 150@ 60. el + (ROBox new). el @ RODraggable. el @ (ROPopupView view: v2). raw add: el. self assert: v2 encompassingRectangle = ( (0@0) corner: (90@20))! ! !ROPopupViewTest methodsFor: 'subview' stamp: 'AlexandreBergel 8/19/2012 09:53'! testSubview | canvas oldCamera viewDisplayerShape element | view := ROMondrianViewBuilder new. canvas := RONullCanvas new. oldCamera := canvas camera. viewDisplayerShape := ROViewDisplayer new view: view raw; yourself. element := ROElement new. element + viewDisplayerShape. element drawOn: canvas. self assert: canvas camera == view raw camera. ! ! !ROPopupViewTest methodsFor: 'receiving view' stamp: 'AlexandreBergel 6/1/2012 18:26'! testWithReceivingView | el receivingView | receivingView := ROView new. view := ROView new. el := ROElement sprite. el @ (ROPopup new receivingView: receivingView). view add: el. self assert: view elements size = 1. self assert: receivingView elements isEmpty. el announce: ROMouseEnter. self assert: view elements size = 1. self assert: receivingView elements size = 1. el announce: ROMouseLeave. self assert: view elements size = 1. self assert: receivingView elements isEmpty. el announce: ROMouseLeave. self assert: view elements size = 1. self assert: receivingView elements isEmpty.! ! !ROPopupViewTest methodsFor: 'receiving view' stamp: 'AlexandreBergel 6/1/2012 18:21'! testWithoutReceivingView | el | view := ROView new. el := ROElement sprite. el @ ROPopup. view add: el. self assert: view elements size = 1. el announce: ROMouseEnter. self assert: view elements size = 2. el announce: ROMouseLeave. self assert: view elements size = 1. el announce: ROMouseLeave. self assert: view elements size = 1.! ! !ROAnnouncerTest methodsFor: 'running'! setUp super setUp. announcer := ROAnnouncer new.! ! !ROAnnouncerTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2012 13:57'! testIsForwarder | t | self deny: announcer isForwarder. t := 0. announcer when: ROEvent do: [ :ann | t := t + 1 ]. self assert: t isZero. announcer announce: ROEvent. self assert: t = 1. announcer announce: ROMouseClick. self assert: t = 2. announcer forward: ROMouseClick. announcer announce: ROMouseClick. self assert: t = 2. "No increase since it is forwarded." announcer announce: ROEvent. self assert: t = 3. ! ! !ROAnnouncerTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2012 13:57'! testIsForwarder2 | t | t := 0. announcer when: ROEvent do: [ :ann | t := t + 1 ]. self deny: (announcer isForwarded: ROMouseClick). announcer forward: ROEvent. self assert: (announcer isForwarded: ROMouseClick). announcer announce: ROMouseClick. self assert: t = 0. "No increase since it is forwarded." announcer announce: ROEvent. self assert: t = 0. ! ! !ROArrowTest methodsFor: 'running' stamp: 'AlexandreBergel 6/12/2012 15:01'! setUp super setUp. arrow := ROArrow new.! ! !ROArrowTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2012 15:02'! testInitialization self assert: arrow offset = 0! ! !ROArrowTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2012 16:54'! testLine | line | line := ROLine new. self assert: line numberOfArrows = 0. self deny: line hasArrow. line add: arrow. self assert: line numberOfArrows = 1. self assert: line hasArrow.! ! !ROAttachPointTest methodsFor: 'running' stamp: 'AlexandreBergel 8/20/2013 21:31'! setUp view := ROView new. el1 := ROElement spriteOn: 1. el2 := ROElement spriteOn: 2. el1 @ RODraggable. el2 @ RODraggable. edge := ROEdge from: el1 to: el2. view addAll: (Array with: el1 with: el2 with: edge). shape := ROLine new. edge + shape. ROHorizontalLineLayout on: (Array with: el1 with: el2) ! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:11'! testHorizontalAttachPoint shape attachPoint: (ROHorizontalAttachPoint new). self assert: (shape startingPointOf: edge) = (el1 bounds topRight + (0 @ (el1 bounds extent y / 2)) asIntegerPoint ) . self assert: (shape endingPointOf: edge) = (el2 bounds topLeft + (0 @ (el2 bounds extent y / 2)) asIntegerPoint ) .! ! !ROAttachPointTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 12:13'! testRenderingEmbeddedVerticalAttachPoint | canvas str spr embedding trace1 | view := ROView new. el1 := ROElement sprite. el2 := ROElement sprite. shape := ROLine new. shape attachPoint: (ROVerticalAttachPoint new). edge := (ROEdge from: el1 to: el2) + shape. embedding := ROElement sprite. embedding add: el1; add: el2; add: edge. ROHorizontalLineLayout on: (Array with: el1 with: el2). embedding translateBy: 40 @ 30. canvas := ROTracingCanvas new. view add: embedding. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(40@30)' '(160@30)' 1 'Color red') #(#line '(160@30)' '(160@90)' 1 'Color red') #(#line '(160@90)' '(40@90)' 1 'Color red') #(#line '(40@90)' '(40@30)' 1 'Color red') #(#line '(45@35)' '(95@35)' 1 'Color red') #(#line '(95@35)' '(95@85)' 1 'Color red') #(#line '(95@85)' '(45@85)' 1 'Color red') #(#line '(45@85)' '(45@35)' 1 'Color red') #(#line '(105@35)' '(155@35)' 1 'Color red') #(#line '(155@35)' '(155@85)' 1 'Color red') #(#line '(155@85)' '(105@85)' 1 'Color red') #(#line '(105@85)' '(105@35)' 1 'Color red') #(#line '(130@35)' '(70@85)' 1 'Color veryLightGray'))! ! !ROAttachPointTest methodsFor: 'rendering' stamp: 'AlexandreBergel 8/20/2013 21:32'! testRenderingVerticalAttachPoint | canvas | shape attachPoint: (ROVerticalAttachPoint new). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(5@5)' '(55@5)' 1 'Color red') #(#line '(55@5)' '(55@55)' 1 'Color red') #(#line '(55@55)' '(5@55)' 1 'Color red') #(#line '(5@55)' '(5@5)' 1 'Color red') #(#line '(65@5)' '(115@5)' 1 'Color red') #(#line '(115@5)' '(115@55)' 1 'Color red') #(#line '(115@55)' '(65@55)' 1 'Color red') #(#line '(65@55)' '(65@5)' 1 'Color red') #(#line '(90@5)' '(30@55)' 1 'Color veryLightGray'))! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:11'! testShorterDistancePoint1 shape attachPoint: (ROShorterDistanceAttachPoint new). "el1 and el2 are on the same horizontal line. el1 is on the left of el2" self assert: (shape startingPointOf: edge) = (el1 bounds topRight + (0 @ (el1 bounds extent y / 2)) asIntegerPoint) . self assert: (shape endingPointOf: edge) = (el2 bounds topLeft + (0 @ (el2 bounds extent y / 2)) asIntegerPoint)! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:12'! testShorterDistancePoint2 | p | shape attachPoint: (ROShorterDistanceAttachPoint new). "el1 and el2 are on the same horizontal line. el2 is on the left of el1" p := el1 position. el1 translateTo: el2 position. el2 translateTo: p. self assert: (shape startingPointOf: edge) = (el1 bounds topLeft + (0 @ (el1 bounds extent y / 2)) asIntegerPoint) . self assert: (shape endingPointOf: edge) = (el2 bounds topRight + (0 @ (el2 bounds extent y / 2)) asIntegerPoint)! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:12'! testShorterDistancePoint3 | p | shape attachPoint: (ROShorterDistanceAttachPoint new). "el1 and el2 are on the same horizontal line. el2 is on the left of el1" p := el1 position. el1 translateBy: 0 @ 80. el2 translateTo: p. self assert: (shape startingPointOf: edge) = (el1 bounds topLeft + ((el1 bounds width / 2) asInteger @0)) . self assert: (shape endingPointOf: edge) = (el2 bounds topLeft + ((el2 bounds width / 2) asInteger @ el2 bounds width))! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:12'! testShorterDistancePoint4 | p | shape attachPoint: (ROShorterDistanceAttachPoint new). "el1 and el2 are on the same vertical line. el1 is above el2" el2 translateTo: el1 position. el2 translateBy: 0 @ 80. self assert: (shape startingPointOf: edge) = (el1 bounds topLeft + ((el1 bounds width / 2) asInteger @ el1 bounds height)) . self assert: (shape endingPointOf: edge) = (el2 bounds topLeft + ((el2 bounds width / 2) asInteger @ 0))! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/9/2012 08:52'! testShorterDistancePoint4WithOffset | p | shape attachPoint: (ROShorterDistanceAttachPoint new offset: 5). "el1 and el2 are on the same vertical line. el1 is above el2" el2 translateTo: el1 position. el2 translateBy: 0 @ 80. self assert: (shape startingPointOf: edge) = ((el1 bounds topLeft + ((el1 bounds width / 2) asInteger @ el1 bounds height)) + (5 @ 0)) . self assert: (shape endingPointOf: edge) = ((el2 bounds topLeft + ((el2 bounds width / 2) asInteger @ 0) + (5 @ 0)))! ! !ROAttachPointTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 13:12'! testVerticalAttachPoint shape attachPoint: (ROVerticalAttachPoint new). self assert: (shape startingPointOf: edge) = (el1 bounds bottomLeft + ((el1 bounds extent x / 2) asInteger @ 0)) . self assert: (shape endingPointOf: edge) = (el2 bounds topLeft + ((el2 bounds extent x / 2) asInteger @ 0)) .! ! !ROBSplineLineTest commentStamp: '' prior: 34278652! A ROBSplineLineTest is a test class for testing the behavior of ROBSplineLine! !ROBSplineLineTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/23/2013 18:24'! testExample | bs edges view tracingCanvas | view := ROMondrianViewBuilder new. view shape circle size: 10. view nodes: (0 to: 100). view shape line attachPoint: (ROCenteredAttachPoint instance). edges := view edgesFrom: [ :x | x // 10 ]. bs := ROBSplineLine new. bs alpha: 0.8. bs customCpoints add: (view raw elementFromModel: 0). bs color: (Color blue). view shape: bs. "view shape line color: Color blue." view edges: #(37 39) from: #yourself to: 90. view treeLayout userDefinedEdges: edges. view applyLayout. tracingCanvas := ROTracingCanvas new. self shouldnt: [ view raw drawOn: tracingCanvas ] raise: Error ! ! !ROBSplineLineTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/30/2013 18:47'! testSetDiscovery | view edges bs | view := ROMondrianViewBuilder new. view shape circle size: 10. view nodes: (1 to: 10). edges := view edges: (1 to: 10) from: [ :v | v // 2 ] to: #yourself. view treeLayout userDefinedEdges: edges. bs := ROBSplineLine new. bs setDiscovery: [ :v | v // 2 ]. bs color: Color red. view shape: bs. "view shape line color: Color red." view edgesFromAssociations: (Array with: 5 -> 6 with: 9 -> 4 with: 8 -> 7 with: 4 -> 6). view applyLayout. self shouldnt: [ view raw bitmap ] raise: Error! ! !ROBitmapGenerationTest methodsFor: 'util' stamp: 'AlexandreBergel 4/25/2012 15:51'! encodeForm: aFormCanvas | writer bytes v | writer := ZipWriteStream on: String new. aFormCanvas bits do: [:c | writer nextPutAll: c printString ]. writer close. bytes := writer encodedStream contents. v := OrderedCollection new. bytes do: [:c | v add: c asInteger ]. ^ v asArray ! ! !ROBitmapGenerationTest methodsFor: 'running' stamp: 'AlexandreBergel 5/11/2012 14:21'! setUp node1 := ROElement on: 'hello'. node1 extent: 40 @ 30. node1 addShape: (ROBox new color: Color yellow); addShape: ROBorder new. node1 addInteraction: RODraggable. node2 := ROElement on: 'hello'. node2 extent: 40 @ 30. node2 addShape: (ROBox new color: Color green). node2 translateBy: 100@30. view := ROView new. view add: node1. view add: node2. emptyView := ROView new.! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:25'! testArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 2). view shape: (ROLine new add: (ROArrow new offset: 0)). view edgeFromAssociation: 1 -> 2. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 219 177 17 128 32 0 4 193 150 94 5 129 254 27 51 53 215 113 132 221 232 67 2 110 76 176 236 173 111 35 233 153 125 141 50 206 182 143 58 247 138 111 25 179 223 78 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 252 182 110 167 79 171 103 45 135 223 150 207 111 203 255 110 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 239 73 91 254 63 253 126 91 190 55 219 250 228 230 44 241 102 194 111 203 247 195 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 111 203 95 126 91 126 91 254 242 219 242 249 109 249 109 249 252 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 251 57 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 214 114 1)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:26'! testArrowAndVerticalArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROLine new add: (ROVerticalArrow new offset: 0)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 219 177 17 128 32 0 4 193 150 94 5 129 254 27 51 53 215 113 132 221 232 67 2 110 76 176 236 173 111 35 233 153 125 141 50 206 182 143 58 247 138 111 25 179 223 78 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 252 182 110 167 79 171 103 45 135 223 150 207 111 203 255 110 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 239 73 91 254 63 253 126 91 190 55 219 250 228 230 44 241 102 194 111 203 247 195 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 111 203 95 126 91 126 91 254 242 219 242 249 109 249 109 249 252 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 251 57 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 214 114 1)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:26'! testArrowAndVerticalArrowOffset1 | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROLine new add: (ROVerticalArrow new offset: 1)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 219 177 1 128 32 16 4 193 150 78 5 225 251 111 204 34 52 16 102 162 43 128 133 136 118 142 121 84 50 179 250 170 86 247 56 171 175 189 226 219 198 234 167 211 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 190 109 203 255 211 239 183 229 251 178 173 202 232 119 111 215 70 203 111 203 247 143 182 182 184 239 253 119 203 231 183 229 47 191 45 191 45 127 249 109 249 252 182 252 182 124 126 91 254 242 219 242 219 242 151 223 150 207 111 203 111 203 231 183 229 47 191 45 191 45 127 249 109 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 119 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 18 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 219 203 3)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:26'! testArrowOffset1 | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 2). view shape: (ROLine new add: (ROArrow new offset: 1)). view edgeFromAssociation: 1 -> 2. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 219 177 1 128 32 16 4 193 150 78 5 225 251 111 204 34 52 16 102 162 43 128 133 136 118 142 121 84 50 179 250 170 86 247 56 171 175 189 226 219 198 234 167 211 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 190 109 203 255 211 239 183 229 251 178 173 202 232 119 111 215 70 203 111 203 247 143 182 182 184 239 253 119 203 231 183 229 47 191 45 191 45 127 249 109 249 252 182 252 182 124 126 91 254 242 219 242 219 242 151 223 150 207 111 203 111 203 231 183 229 47 191 45 191 45 127 249 109 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 119 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 18 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 219 203 3)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 6/12/2012 15:28'! testArrowedLine | el1 el2 edge form1 view2 bitmap2 line | form1 := #(229 219 209 170 226 48 0 69 209 95 58 54 166 234 255 255 152 224 75 40 20 171 24 106 211 181 30 46 103 238 192 60 152 236 222 206 192 92 167 219 253 242 72 41 213 95 202 138 111 112 254 45 246 171 245 249 213 250 203 175 214 231 87 235 47 191 90 159 95 173 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 229 87 235 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 151 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 213 250 203 175 214 231 87 235 47 191 90 159 95 173 191 252 106 253 106 253 229 87 235 243 171 245 151 95 173 207 175 214 95 126 181 126 181 254 242 171 245 249 213 250 203 175 214 231 87 235 47 191 90 159 95 173 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 106 125 126 181 254 242 171 245 249 213 250 203 175 214 231 87 235 47 191 90 191 90 127 249 213 250 252 106 253 229 87 235 243 171 245 151 95 173 95 173 191 252 106 125 126 181 254 242 171 245 249 213 250 203 175 214 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 229 87 235 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 239 179 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 106 125 126 181 254 242 171 245 249 213 250 203 175 214 231 87 235 47 255 214 251 213 250 203 175 214 119 184 156 253 207 194 63 125 159 254 163 220 255 84 252 167 128 207 63 125 159 127 250 62 255 244 125 254 251 159 207 127 10 248 252 211 247 249 167 239 243 79 223 231 191 255 249 252 167 128 207 63 125 159 127 250 62 255 244 125 254 251 159 207 127 10 248 252 211 247 249 167 239 243 223 0 124 254 83 192 231 159 190 207 63 125 159 127 250 62 255 253 207 231 63 5 124 254 233 251 252 211 247 249 167 239 243 223 255 124 254 83 192 231 159 190 207 63 125 223 65 254 7 232 239 215 194 55 142 118 218 235 231 190 245 251 190 243 223 140 213 239 249 215 193 191 15 254 117 240 239 67 59 241 197 55 252 251 128 223 135 229 47 253 235 224 191 89 190 14 255 237 45 241 225 127 231 240 175 131 255 147 195 191 5 254 37 240 111 129 127 9 252 91 224 95 2 255 22 248 151 96 235 155 62 235 18 248 183 192 191 5 254 45 96 78 126 170 181 204 187 173 246 207 18 125 254 148 62 107 223 207 224 191 203 231 87 235 87 230 87 235 59 251 207 90 127 249 213 250 252 106 253 229 87 235 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 239 179 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 106 125 126 181 254 242 171 245 249 213 250 203 175 214 231 87 235 47 159 95 173 191 252 106 125 126 181 254 242 171 245 249 213 250 203 175 214 175 214 95 126 181 62 191 90 127 249 213 250 252 106 253 229 87 235 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 151 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 213 250 235 195 85 235 160 203 231 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 151 95 173 207 175 214 95 126 181 62 191 90 127 249 213 250 213 250 203 175 214 231 87 235 47 191 90 159 95 173 191 252 106 253 106 253 229 87 235 243 171 245 151 95 173 207 175 214 95 126 181 126 181 254 242 171 245 249 213 250 203 175 214 231 87 235 47 191 90 191 90 255 62 251 213 250 252 106 253 229 87 235 243 171 245 151 95 173 207 175 214 175 214 231 87 235 47 191 90 159 95 173 191 252 106 125 126 181 254 242 171 245 171 245 151 95 173 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 175 163 196 255 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 190 47 60 1). "-------------" view2 := ROView new. el1 := ROElement new. el1 @RODraggable. el1 extent: 50@50. el1 + ROBox blue. el2 := ROElement new. el2 @RODraggable. el2 extent: 50@50. el2 + ROBox green. el2 translateBy: 60@100. edge := ROEdge from: el1 to: el2. line := ROLine blue. line addBegining: ROArrow new. edge + line. view2 add: el1; add: el2; add: edge. bitmap2 := view2 bitmap. self assert: form1 = (self encodeForm: bitmap2) ! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/23/2013 19:30'! testContainingElementDragging | bitmap node3 | node2 := ROElement on: 'world'. node2 extent: 40@30. node2 addShape: (ROBox new color: Color green). node3 := ROElement on: 'world'. node3 extent: 40@30. node3 addShape: (ROBox new color: Color yellow). node3 translateBy: 40@30. node1 := ROElement on: 'hello'. node1 extent: 100 @ 130. node1 addShape: ROBorder new; addShape: ROBox new. node1 add: node2. node1 add: node3. node1 @ RODraggable. node1 @ ROPopup. node1 translateBy: 10@15. bitmap := ROView new add: node1; bitmap. " view open " self assert: (self encodeForm: bitmap) = #(229 221 49 14 194 48 16 68 209 43 13 137 29 199 247 191 24 162 138 68 5 136 192 42 239 21 209 244 120 127 75 91 102 155 219 88 102 247 87 133 21 223 101 248 239 217 191 45 159 127 91 254 109 249 252 219 242 151 127 91 62 255 61 251 183 229 243 111 203 191 45 159 127 91 254 242 111 203 231 191 103 255 182 124 254 109 249 183 229 243 111 203 95 254 109 249 252 247 236 223 150 207 191 45 255 182 124 254 109 249 203 191 45 159 255 158 253 219 242 249 183 229 223 150 207 191 173 231 53 246 219 76 246 248 203 95 254 186 254 242 129 105 159 25 125 235 109 245 151 191 252 117 181 229 167 221 79 187 127 10 254 242 151 159 118 159 159 118 127 249 203 95 126 218 125 126 218 253 229 47 127 249 105 247 211 94 45 237 99 95 122 95 183 248 171 198 242 195 229 47 63 237 126 218 253 180 251 105 247 151 159 118 159 159 118 63 237 126 218 253 229 167 221 231 167 221 95 126 218 253 229 167 221 231 167 221 95 126 218 253 229 167 221 79 187 159 118 127 249 105 247 151 159 118 63 237 126 218 253 180 251 203 79 187 159 118 63 237 126 218 253 180 251 203 79 187 207 79 187 191 252 180 251 203 79 187 207 79 187 191 252 180 251 203 79 187 207 15 176 31 96 127 249 1 246 249 1 246 151 31 96 127 249 1 246 3 236 7 216 15 176 191 252 0 251 252 0 251 203 15 176 191 252 0 251 1 246 3 236 7 216 95 126 128 125 126 128 253 229 7 216 95 126 128 253 0 251 203 15 176 191 252 0 251 252 0 251 1 246 67 227 47 63 192 126 128 253 229 7 216 95 126 128 125 126 128 253 0 251 203 95 126 128 253 0 251 203 15 176 191 252 0 251 252 0 251 1 246 151 31 96 159 31 96 127 249 1 246 151 31 96 63 192 126 128 253 0 251 203 15 176 207 15 176 191 252 0 251 203 15 176 31 96 63 192 126 128 253 229 7 216 231 7 216 95 126 128 253 229 7 216 15 176 31 96 63 192 254 242 3 236 243 3 236 47 63 192 254 242 3 236 7 216 95 126 128 253 229 7 216 247 219 0 251 171 216 122 252 193 106 90 252 85 100 249 1 246 249 1 246 3 252 205 53 155 191 94 94 126 128 125 126 128 253 0 251 203 15 176 31 96 63 192 254 242 3 236 7 216 15 176 207 15 176 31 96 127 249 1 246 249 1 246 151 31 96 63 192 126 128 125 126 128 253 0 251 203 15 176 207 15 176 191 252 0 251 1 246 3 236 7 216 95 126 128 253 229 7 216 231 7 216 95 126 128 253 0 251 1 246 3 236 47 63 192 254 242 3 236 243 3 236 47 63 192 126 128 253 0 251 1 246 151 31 96 127 249 1 246 249 1 246 3 236 231 207 15 176 31 96 63 192 254 242 3 236 7 216 15 176 207 15 176 31 96 127 249 1 246 3 236 7 216 95 126 128 253 0 251 1 246 249 1 246 3 236 47 63 192 62 63 192 254 242 3 236 7 216 15 176 31 96 63 192 126 128 253 229 7 216 231 7 216 95 126 128 253 0 251 1 246 3 236 47 63 192 254 242 3 236 243 3 236 47 63 192 126 128 253 0 251 1 246 151 31 96 127 249 1 246 249 1 246 151 31 224 210 235 248 101 222 95 25 39 45 63 192 126 128 253 117 206 58 78 223 95 21 86 201 87 226 7 216 15 176 191 252 0 251 1 246 3 236 243 3 236 7 216 95 126 128 125 126 128 253 229 7 216 15 176 31 96 63 192 126 204 252 0 251 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 229 7 216 15 176 191 252 229 47 63 192 62 63 192 254 242 151 191 252 0 251 1 246 151 191 252 229 7 216 231 7 216 95 254 242 151 31 96 63 192 254 242 151 191 252 0 251 252 0 251 203 95 126 128 253 0 251 1 246 151 191 252 229 7 216 231 7 216 95 254 242 3 236 243 3 236 47 127 249 203 15 176 31 96 255 153 250 203 95 126 128 125 126 128 253 229 47 127 249 1 246 3 236 47 127 249 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 229 7 248 19 73 137 143 31 96 127 249 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 229 7 216 15 176 191 252 229 47 63 192 62 63 192 254 242 151 191 252 0 251 1 246 151 191 252 229 7 216 231 7 216 95 254 242 151 31 96 63 192 254 242 151 191 252 0 251 252 0 251 203 95 254 242 3 236 7 216 95 254 242 151 31 96 159 31 96 127 249 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 0 251 203 95 126 128 125 126 128 253 229 47 127 249 1 246 3 236 47 127 249 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 229 7 216 15 176 191 252 229 47 63 192 62 63 192 254 242 151 191 252 0 251 1 246 151 191 252 229 7 216 231 7 216 95 254 242 151 31 96 63 192 127 93 91 247 151 191 252 229 7 216 15 176 191 252 229 47 63 192 62 63 192 254 242 151 31 96 159 31 96 127 249 203 95 126 128 253 0 251 207 212 95 254 242 3 236 243 3 236 47 127 249 203 15 176 31 96 127 249 203 95 126 128 125 126 128 253 229 47 127 249 1 246 3 236 47 127 249 203 15 176 207 15 176 191 252 229 47 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 229 7 216 15 176 191 252 229 47 63 192 62 63 192 254 242 151 31 96 63 192 126 128 253 229 47 127 249 1 246 249 1 246 151 191 252 0 251 252 0 251 203 95 254 242 3 236 7 216 127 166 254 242 151 31 96 159 31 96 127 249 203 95 126 128 253 0 251 203 95 254 242 3 236 243 3 236 47 127 249 203 15 176 31 96 127 249 203 95 126 128 125 126 128 253 229 47 127 249 1 246 3 236 47 127 245 230 175 194 203 15 112 249 0 251 203 95 254 186 250 242 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 240 167 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 197 221 1)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 12:16'! testContainingElementRenderingSimple | bitmap node3 | node2 := ROElement on: 'world'. node2 extent: 40@30. node2 addShape: (ROBox new color: Color green). node3 := ROElement on: 'world'. node3 extent: 40@30. node3 addShape: (ROBox new color: Color yellow). node3 translateBy: 40@30. node1 := ROElement on: 'hello'. node1 extent: 100 @ 130. node1 addShape: ROBorder new; addShape: ROBox new. node1 add: node2; add: node3. self assert: node2 view == node1 view. self assert: node3 view == node1 view. view camera realExtent: 150@150. bitmap := view bitmapForElements: (Array with: node1). self assert: (self encodeForm: bitmap) = #(229 220 59 10 192 32 16 69 209 45 141 198 239 254 55 102 27 2 130 93 132 115 170 87 14 220 126 74 238 35 205 136 17 254 58 95 63 121 159 50 163 215 86 203 227 175 221 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 203 143 229 199 242 99 249 177 252 88 126 44 63 150 31 235 27 203 95 151 191 86 240 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 103 90) " bitmap asMorph openInWindow "! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 8/11/2013 17:21'! testDiamond view := ROMondrianViewBuilder new. view shape rectangle size: 40. view nodes: #( 'container' 'element' ). view shape: (ROLine new add: (RODiamondDecoration new offset: 1 )). view edgesFromAssociations: (Array with: 'container' -> 'element' ). view treeLayout verticalGap: 40. view applyLayout. self assert: (self encodeForm: view raw bitmap) = #(229 220 65 142 194 48 16 69 193 43 253 196 118 28 223 255 98 72 217 32 177 6 236 164 106 129 122 77 247 211 12 204 40 117 31 117 28 125 31 205 159 86 152 226 123 12 255 158 253 182 124 126 91 126 91 62 191 45 127 242 219 242 249 247 236 183 229 91 167 173 126 110 35 57 227 79 43 76 62 63 68 255 135 210 196 201 15 209 15 209 15 209 15 209 231 135 232 79 126 136 126 136 126 136 126 136 62 63 68 127 242 67 244 67 244 67 244 67 244 249 33 250 147 31 162 31 162 31 162 31 162 207 15 209 159 252 16 253 16 253 16 253 16 125 126 136 254 228 135 232 135 232 135 232 135 232 243 67 244 39 63 68 63 68 63 68 63 68 159 31 162 63 249 33 250 33 250 33 250 33 250 252 16 253 201 15 209 15 209 15 209 15 209 231 135 232 79 126 136 126 136 126 136 126 136 62 63 68 127 242 67 244 67 244 67 244 67 244 249 33 250 147 31 162 31 162 31 162 31 162 111 122 141 126 91 126 91 62 191 45 191 45 159 223 150 63 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 254 228 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 147 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 79 126 91 126 91 126 91 126 91 62 191 45 191 45 223 61 219 242 167 249 147 239 233 189 141 244 118 180 90 252 247 2 222 189 127 6 254 21 248 87 224 31 193 181 121 255 12 252 35 240 207 192 191 2 255 10 252 35 40 254 231 4 255 8 138 255 113 209 63 130 226 127 107 224 95 129 127 5 254 17 124 238 219 63 3 255 12 252 35 240 175 192 191 2 255 12 252 35 240 207 192 63 2 255 10 252 43 240 207 192 255 6 217 63 3 255 111 138 254 25 248 255 95 224 243 175 192 231 255 46 224 47 223 95 190 191 124 255 189 240 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 243 151 239 251 215 162 253 71 96 250 143 227 244 253 186 45 255 113 206 254 99 164 125 126 91 126 91 62 191 45 127 242 219 242 219 242 111 220 111 203 231 183 229 183 229 91 221 123 171 215 166 143 238 95 187 223 150 239 43 252 182 252 182 124 126 91 126 91 62 191 45 127 242 219 242 249 109 249 109 249 252 182 252 182 124 126 91 254 228 183 229 243 219 242 219 242 249 109 249 109 249 252 182 252 201 111 203 231 183 229 183 229 243 219 242 219 242 249 109 249 147 223 150 207 111 203 111 203 231 183 229 183 229 243 219 242 39 191 45 159 223 150 223 150 207 111 203 111 203 231 183 229 79 126 91 62 191 45 191 45 159 223 150 223 150 207 111 203 159 252 182 124 126 91 126 91 62 191 45 191 45 159 223 150 63 249 109 249 252 182 252 182 124 126 91 126 91 62 191 45 127 242 219 242 249 109 249 109 249 252 182 252 182 124 126 91 254 228 183 229 243 219 242 219 242 249 109 249 109 249 238 218 150 63 205 159 124 62 159 207 231 243 249 124 62 159 207 231 243 45 33 241 95 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 18 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 153 94)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:55'! testDrawingLine | el1 el2 edge line | view := ROView new. el1 := ROElement new. el1 extent: 50@50. el1 + ROBox blue. el2 := ROElement new. el2 extent: 50@50. el2 + ROBox green. edge := ROEdge from: el1 to: el2. line := ROLine new. line add: ROArrow new offset: 1. edge + line. view add: el1; add: el2; add: edge. self shouldnt: [ view bitmap ] raise: Error ! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 16:21'! testFormSize | form | form := view bitmapForRealSize: 20@30. self assert: form extent = (20 @ 30)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 6/21/2013 09:46'! testInnerEdges | bitmap | view := ROMondrianViewBuilder new. view node: 'foo' forIt: [ view node: 'bar' forIt: [ view nodes: #(1 2). view edgesFrom: 1 to: 2. ] ]. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 225 9 128 32 20 70 209 149 190 196 74 247 95 172 17 34 16 82 207 249 245 6 120 23 73 170 90 238 118 244 164 197 155 122 237 215 93 250 57 211 20 223 54 102 223 181 241 147 223 150 207 111 203 111 203 231 183 229 183 229 183 229 243 219 242 219 242 205 219 214 218 55 19 126 91 190 21 218 90 241 20 242 219 242 249 109 249 109 249 252 182 252 182 252 182 124 126 91 126 91 190 157 218 154 233 102 194 111 203 183 103 91 255 151 226 183 229 243 219 242 219 242 249 109 249 109 249 109 249 252 231 45 191 45 159 127 79 232 183 229 243 219 242 219 242 219 242 249 109 249 109 249 252 182 252 182 124 110 91 254 123 240 126 91 190 145 109 249 223 111 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 190 111 109 249 255 39 244 219 242 141 108 203 56 173 86 153 252 141 244 219 242 39 191 45 159 223 150 223 150 207 111 203 159 252 141 244 219 242 39 191 45 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 247 206 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 189 60)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 6/12/2013 17:13'! testLabelRendering | bitmap node canvas | view := ROView new. view add: (node := (ROElement spriteOn: '50') + (ROLabel new textPadding: 0); + (ROBox red)). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (50@50)' 'Color red' 0 'Color black') #(#drawStringColor '50' '(0@0)' 'Color black') #(#line '(0@0)' '(50@0)' 1 'Color red') #(#line '(50@0)' '(50@50)' 1 'Color red') #(#line '(50@50)' '(0@50)' 1 'Color red') #(#line '(0@50)' '(0@0)' 1 'Color red')). bitmap := view bitmapForRealSize: 200@200. self assert: node bounds = ((0@0) corner: (50@50)) " bitmap asMorph openInWindow "! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 5/11/2012 14:20'! testMovingCamera | bitmap1 bitmap2 bitmap3 | bitmap1 := view bitmapForRealSize: 100@100. view cameraTranslateByRealStep: -10 @ -15. bitmap2 := view bitmapForRealSize: 100@100. node1 translateBy: 10@15. node2 translateBy: 10@15. view camera realExtent: 100@100. bitmap3 := view bitmap. self assert: (bitmap1 bits ~= bitmap2 bits). self assert: (bitmap2 bits ~= bitmap3 bits). " bitmap1 asMorph openInWindow bitmap2 asMorph openInWindow bitmap3 asMorph openInWindow "! ! !ROBitmapGenerationTest methodsFor: 'ortho lines' stamp: 'AlexandreBergel 12/5/2012 09:42'! testOrthLineAndArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROOrthoVerticalLineShape new add: (ROArrow new offset: 0)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. view applyLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 81 138 234 64 16 64 209 45 149 154 24 179 255 141 249 51 63 130 233 20 173 200 84 157 243 213 240 24 121 33 117 203 204 128 46 215 125 217 239 219 117 95 253 211 127 56 133 175 13 127 158 253 182 124 126 91 126 91 62 191 45 255 228 183 229 243 231 217 111 203 231 183 245 219 211 246 184 236 17 143 168 125 242 249 141 10 141 86 254 223 251 252 70 253 70 253 70 125 126 163 126 163 126 163 126 163 126 153 126 163 62 191 81 191 81 191 81 159 223 168 223 168 223 168 223 168 223 168 223 168 207 111 212 111 212 111 212 231 55 234 55 234 243 27 245 27 245 27 245 249 141 250 141 250 141 250 141 250 141 250 141 250 252 70 253 70 253 70 125 126 163 126 163 62 191 81 191 81 191 81 159 223 168 223 168 223 168 223 168 127 242 27 245 249 141 250 141 250 141 250 252 70 253 239 74 241 27 245 27 245 79 95 56 197 182 222 215 229 230 127 87 152 223 150 127 242 219 242 249 109 249 109 249 252 182 252 182 252 182 252 182 252 147 223 150 111 62 181 191 219 61 245 239 103 63 238 171 58 14 31 221 248 244 203 248 234 238 139 236 8 124 242 42 190 202 111 40 217 25 152 127 17 95 237 39 142 236 16 204 190 134 175 199 51 136 127 170 126 242 231 186 235 211 223 240 205 58 187 196 15 223 244 253 169 98 31 9 70 191 37 28 142 192 96 170 14 6 200 159 166 214 127 210 26 173 141 131 91 63 152 182 209 210 242 117 155 157 119 247 247 237 29 159 253 57 95 155 73 201 221 242 204 27 153 63 41 205 39 37 51 42 169 39 30 127 82 186 79 202 249 168 228 30 141 253 73 105 63 41 103 163 146 252 29 202 159 148 254 147 50 30 149 236 47 219 254 164 180 152 143 30 159 179 58 251 139 161 127 149 254 103 230 124 191 216 34 197 63 81 237 95 138 255 57 119 159 191 15 252 125 224 239 3 159 191 15 252 125 224 239 3 159 191 15 252 125 224 239 3 159 191 15 252 125 224 239 3 159 191 15 252 125 224 239 3 159 191 15 252 125 224 239 3 159 191 15 252 136 252 125 224 243 247 129 31 145 191 15 124 254 62 240 35 242 247 129 207 223 7 126 68 254 62 240 249 251 192 143 200 223 7 62 127 31 248 17 249 251 192 231 239 3 63 34 127 31 248 252 125 224 71 228 95 138 207 223 7 126 68 254 165 248 251 192 223 7 126 68 254 165 248 251 192 223 7 126 68 254 165 248 251 160 225 62 40 254 205 92 254 165 248 223 151 230 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 94 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 139 240 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 23 225 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 194 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 132 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 8 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 17 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 146 158)! ! !ROBitmapGenerationTest methodsFor: 'ortho lines' stamp: 'AlexandreBergel 12/5/2012 09:42'! testOrthLineAndReversedArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROOrthoVerticalLineShape new add: (ROReversedArrow new offset: 0)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. view applyLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 75 142 226 80 16 68 209 45 5 198 31 188 255 141 49 97 128 144 129 68 178 0 231 57 35 11 161 238 114 243 110 116 49 128 113 88 199 117 94 134 117 242 175 254 225 42 190 54 252 243 236 183 229 243 219 242 219 242 249 109 249 87 126 91 62 255 60 251 109 249 252 182 190 123 181 92 78 107 114 201 177 175 124 126 163 66 163 71 254 233 125 126 163 126 163 126 163 62 191 81 191 81 191 81 191 81 191 76 191 81 159 223 168 223 168 223 168 207 111 212 111 212 111 212 111 212 111 212 111 212 231 55 234 55 234 55 234 243 27 245 27 245 249 141 250 141 250 141 250 252 70 253 70 253 70 253 70 253 70 253 70 125 126 163 126 163 126 163 62 191 81 191 81 159 223 168 223 168 223 168 207 111 212 111 212 111 212 111 212 191 242 27 245 249 141 250 141 250 141 250 252 70 253 239 74 241 27 245 27 245 175 118 184 202 50 205 211 120 246 191 43 204 111 203 191 242 219 242 249 109 249 109 249 252 182 252 182 252 182 252 182 252 43 191 45 223 238 5 222 78 129 255 111 225 191 248 62 255 197 247 249 47 190 207 127 241 125 93 94 101 255 170 207 149 127 174 219 198 249 114 168 95 60 205 63 48 254 140 127 52 32 133 99 242 228 249 165 67 236 79 158 111 243 247 204 253 143 195 195 163 155 79 218 243 111 245 15 101 215 183 63 181 7 183 158 85 255 227 124 29 142 74 241 177 218 67 254 65 177 78 74 113 44 252 147 98 29 149 218 9 40 254 143 228 31 148 198 71 165 244 43 201 155 223 190 253 131 34 28 149 15 222 187 188 123 27 229 31 148 22 7 164 205 231 172 186 220 202 125 87 254 199 224 124 191 31 134 131 127 72 218 191 21 255 163 235 62 127 15 252 61 240 247 192 231 239 129 191 7 254 30 248 252 61 240 247 192 223 3 159 191 7 254 30 248 123 224 243 247 192 223 3 127 15 124 254 30 248 123 224 239 129 207 223 3 63 34 127 15 124 254 30 248 17 249 123 224 243 247 192 143 200 223 3 159 191 7 126 68 254 30 248 252 61 240 35 242 247 192 231 239 129 31 145 191 7 62 127 15 252 136 252 61 240 249 123 224 71 228 223 138 207 223 3 63 34 255 86 252 61 240 247 192 143 200 191 21 127 15 252 61 240 35 242 111 197 223 131 134 123 224 127 113 154 127 43 254 247 165 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 44 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 147 93 1)! ! !ROBitmapGenerationTest methodsFor: 'ortho lines' stamp: 'AlexandreBergel 12/5/2012 09:43'! testOrthLineAndReversedArrowOffset1 | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 1)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. view applyLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 177 174 218 64 20 69 209 95 58 152 25 219 243 255 63 70 133 64 20 84 215 136 153 181 138 200 74 82 196 121 119 31 37 197 163 109 163 141 253 216 70 247 159 254 225 41 190 101 248 247 236 183 229 243 219 242 219 242 249 109 249 79 126 91 62 255 158 253 182 124 126 91 191 125 58 206 219 72 206 204 253 228 243 27 21 26 157 249 79 239 243 27 245 27 245 27 245 249 141 250 141 250 141 250 141 250 101 250 141 250 252 70 253 70 253 70 125 126 163 126 163 126 163 126 163 126 163 126 163 62 191 81 191 81 191 81 159 223 168 223 168 207 111 212 111 212 111 212 231 55 234 55 234 55 234 55 234 55 234 55 234 243 27 245 27 245 27 245 249 141 250 141 250 252 70 253 70 253 70 125 126 163 126 163 126 163 126 163 254 147 223 168 207 111 212 111 212 111 212 231 55 234 127 86 138 223 168 223 168 255 84 240 148 163 239 189 221 253 207 10 243 219 242 159 174 41 234 245 115 254 69 250 109 249 79 37 69 125 249 125 254 109 250 145 249 79 181 105 61 255 113 232 87 230 71 230 63 93 145 214 251 255 192 252 202 200 10 63 191 230 254 25 248 71 224 159 129 127 4 254 25 248 71 224 159 129 127 4 254 25 112 95 119 255 105 157 39 255 174 215 158 228 146 95 247 249 231 224 243 207 193 255 187 244 207 193 63 7 255 28 252 115 240 207 193 63 7 255 28 252 115 240 207 193 63 7 255 28 252 115 160 143 96 153 239 219 241 95 197 255 110 42 95 225 30 76 254 189 182 254 171 248 223 1 237 243 247 192 223 3 127 15 124 254 30 248 123 224 239 129 207 223 3 127 15 252 61 240 249 123 224 239 129 191 7 62 127 15 252 61 240 247 192 231 239 129 191 7 254 30 248 252 61 240 35 242 247 192 231 239 129 31 145 191 7 62 127 15 252 136 252 61 240 249 123 224 71 228 239 129 207 223 3 63 34 127 15 124 254 30 248 17 249 123 224 243 247 192 143 200 223 3 159 191 7 126 68 254 171 248 252 61 240 35 242 95 197 223 3 127 15 252 136 252 87 241 247 192 223 3 63 34 255 85 252 61 88 112 15 252 15 25 243 95 197 255 188 52 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 155 75 226 255 224 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 87 226 1)! ! !ROBitmapGenerationTest methodsFor: 'ortho lines' stamp: 'AlexandreBergel 12/5/2012 09:43'! testOrthoVertical | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROOrthoVerticalLineShape new add: (ROVerticalArrow new offset: 0)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. view applyLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 49 146 170 80 20 69 209 41 29 21 4 230 63 49 19 19 21 136 110 89 220 183 86 244 170 155 160 249 176 207 143 116 186 111 211 246 92 238 219 236 159 174 112 138 111 24 254 251 236 183 229 243 219 242 219 242 249 109 249 39 191 45 159 255 62 251 109 249 252 182 254 123 90 214 219 150 172 233 125 242 249 141 10 141 118 254 235 125 126 163 126 163 126 163 62 191 81 191 81 191 81 191 81 191 76 191 81 159 223 168 223 168 223 168 207 111 212 111 212 111 212 111 212 111 212 111 212 231 55 234 55 234 55 234 243 27 245 27 245 249 141 250 141 250 141 250 252 70 253 70 253 70 253 70 253 70 253 70 125 126 163 126 163 126 163 62 191 81 191 81 159 223 168 223 168 223 168 207 111 212 111 212 111 212 111 212 63 249 141 250 252 70 253 70 253 70 125 126 163 254 119 165 248 141 250 141 250 167 130 83 150 249 57 79 15 255 187 194 252 182 252 147 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 159 252 182 124 229 5 190 223 2 255 223 194 127 248 62 255 225 251 252 135 239 243 31 190 175 247 179 245 79 254 233 106 39 191 207 129 254 175 248 252 85 253 133 190 65 94 149 239 95 212 95 232 27 226 85 249 253 113 253 133 190 1 94 149 189 31 214 95 232 107 255 170 236 63 214 250 11 125 205 95 149 163 199 90 127 161 175 245 171 114 252 88 235 47 244 53 126 85 206 30 107 253 133 190 182 175 202 249 99 173 191 208 215 227 5 25 230 99 81 254 173 248 31 86 243 21 238 65 243 143 50 251 183 226 127 192 220 231 239 129 191 7 254 30 248 252 61 240 247 192 223 3 159 191 7 254 30 248 123 224 243 247 192 223 3 127 15 124 254 30 248 123 224 239 129 207 223 3 127 15 252 61 240 249 123 224 71 228 239 129 207 223 3 63 34 127 15 124 254 30 248 17 249 123 224 243 247 192 143 200 223 3 159 191 7 126 68 254 30 248 252 61 240 35 242 247 192 231 239 129 31 145 191 7 62 127 15 252 136 252 91 241 249 123 224 71 228 223 138 191 7 254 30 248 17 249 183 226 239 129 191 7 126 68 254 173 248 123 48 224 30 248 95 50 230 223 138 255 125 105 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 175 156 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 93 223 11)! ! !ROBitmapGenerationTest methodsFor: 'ortho lines' stamp: 'AlexandreBergel 12/5/2012 09:43'! testOrthoVerticalAndReversedVerticalArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 4). view shape: (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 0)). view edgesFromAssociations: {1 -> 2 . 1 -> 3 . 1 -> 4}. view treeLayout. view applyLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 77 110 163 80 16 133 209 45 221 56 96 96 255 27 243 36 138 44 255 141 74 22 85 231 140 158 18 6 77 195 119 59 29 41 89 46 199 114 92 183 203 177 250 167 51 156 226 27 195 127 159 253 182 124 126 91 126 91 62 191 45 255 228 183 229 243 223 103 191 45 159 223 214 119 79 219 254 115 36 123 122 159 124 126 163 66 163 157 255 244 62 191 81 191 81 191 81 159 223 168 223 168 223 168 223 168 95 166 223 168 207 111 212 111 212 111 212 231 55 234 55 234 55 234 55 234 55 234 55 234 243 27 245 27 245 27 245 249 141 250 141 250 252 70 253 70 253 70 125 126 163 126 163 126 163 126 163 126 163 126 163 62 191 81 191 81 191 81 159 223 168 223 168 207 111 212 111 212 111 212 231 55 234 55 234 55 234 55 234 159 252 70 125 126 163 126 163 126 163 62 191 81 255 119 165 248 141 250 141 250 167 130 83 182 245 186 46 191 254 239 10 243 219 242 79 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 127 242 219 242 149 23 248 247 22 248 127 23 254 195 247 249 15 223 231 63 124 159 255 240 125 83 158 178 127 154 115 242 223 235 81 251 251 249 193 214 95 232 107 251 15 245 167 7 91 127 161 175 241 87 116 239 31 108 253 133 190 214 95 250 191 123 176 245 23 250 154 255 31 241 245 131 173 191 208 215 254 155 9 175 62 88 127 161 111 192 119 157 158 63 92 127 161 111 192 139 242 252 137 250 11 125 35 94 148 199 79 213 95 232 235 245 162 204 248 17 163 251 119 208 191 167 30 247 228 107 59 21 205 127 98 216 191 21 255 231 184 125 254 30 248 123 224 239 129 207 223 3 127 15 252 61 240 249 123 224 239 129 191 7 62 127 15 252 61 240 247 192 231 239 129 191 7 254 30 248 252 61 240 247 192 223 3 159 191 7 126 68 254 30 248 252 61 240 35 242 247 192 231 239 129 31 145 191 7 62 127 15 252 136 252 61 240 249 123 224 71 228 239 129 207 223 3 63 34 127 15 124 254 30 248 17 249 123 224 243 247 192 143 200 191 21 159 191 7 126 68 254 173 248 123 224 239 129 31 145 127 43 254 30 248 123 224 71 228 223 138 191 7 3 247 160 243 201 191 149 147 222 138 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 157 150 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 253 187 1)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 13:57'! testRemoveShapeWithTreeLayout | edges | view := ROMondrianViewBuilder new. view nodes: #(1 2). edges := ( view edgesFrom: [ :v | v + 1 ]). edges first shapes. edges do: [ :edge | edge - ROLine ]. edges first shapes. view treeLayout. self shouldnt: [ view raw bitmap ] raise: Error ! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'VanessaPena 3/12/2013 15:30'! testRenderingCircle | camera bitmap node | node := ROElement on: 'hello'. node extent: 40 @ 30. node addShape: (ROEllipse new color: Color green). view camera realExtent: 150@150. bitmap := view bitmapForElements: (Array with: node). self assert: (self encodeForm: bitmap) = #(229 208 201 9 0 32 16 4 193 148 22 239 252 35 51 7 5 89 169 122 205 119 58 34 90 153 171 244 94 199 193 202 229 230 201 135 143 95 220 205 157 192 47 224 23 240 11 248 5 180 187 151 143 125 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 36 54)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:28'! testReversedArrow | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 2). view shape: (ROLine new add: (ROReversedArrow new offset: 0)). view edgeFromAssociation: 1 -> 2. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 220 177 21 195 32 16 68 193 150 86 18 8 232 191 49 59 117 3 126 28 51 209 134 10 238 135 168 221 99 94 43 153 169 190 86 70 127 123 123 190 171 173 119 220 171 87 92 241 29 227 231 58 11 222 100 237 175 247 219 242 219 242 219 242 219 242 249 109 249 109 249 252 182 252 182 252 182 252 182 252 182 252 182 124 126 91 126 91 62 191 45 191 45 191 45 191 45 191 45 191 45 159 223 150 223 150 207 111 203 111 203 111 203 111 203 111 203 111 203 231 183 229 183 229 243 219 242 219 242 219 242 219 242 219 242 219 242 249 109 249 109 249 252 182 252 182 252 182 252 182 252 182 252 182 124 126 91 126 91 190 253 218 42 254 166 223 111 203 183 89 91 127 185 156 35 254 101 225 183 229 219 176 45 127 249 109 249 109 249 203 111 203 231 183 229 183 229 243 219 242 151 223 150 223 150 191 252 182 124 126 91 126 91 62 191 45 127 249 109 249 109 249 203 111 203 231 183 229 183 229 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 54 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 75 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 37 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 18 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 223 89 62)! ! !ROBitmapGenerationTest methodsFor: 'straight lines' stamp: 'AlexandreBergel 12/5/2012 09:29'! testReversedArrowOffset1 | bitmap | view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 2). view shape: (ROLine new add: (ROReversedArrow new offset: 1)). view edgeFromAssociation: 1 -> 2. view treeLayout. bitmap := view raw bitmap. self assert: (self encodeForm: bitmap) = #(229 219 177 17 128 32 0 4 193 150 94 5 129 254 27 51 53 215 113 132 221 232 67 2 110 76 176 236 173 111 35 233 153 125 141 50 206 182 143 58 247 138 111 25 179 223 78 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 207 111 203 111 203 231 183 229 183 229 183 229 183 229 183 229 183 229 243 219 242 219 242 249 109 249 109 249 109 249 109 249 109 249 109 249 252 182 110 167 79 171 103 45 135 223 150 207 111 203 255 110 249 109 249 109 249 109 249 109 249 252 182 252 182 124 126 91 126 91 126 91 126 91 126 91 126 91 62 191 45 191 45 159 223 150 223 150 223 150 223 150 223 150 223 150 239 73 91 254 63 253 126 91 190 55 219 250 228 230 44 241 102 194 111 203 247 195 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 111 203 95 126 91 126 91 254 242 219 242 249 109 249 109 249 252 182 252 229 183 229 183 229 47 191 45 159 223 150 223 150 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 251 57 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 137 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 196 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 226 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 241 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 151 248 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 214 114 1)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/23/2013 19:30'! testShorterDistancePointAndInnerNodes | elA elB el1 el2 edge | view := ROView new. el1 := ROElement sprite @ ROPopup. el2 := ROElement sprite @ ROPopup. elA := ROElement sprite @ ROPopup. elB := ROElement sprite @ ROPopup. edge := (ROEdge from: elA to: elB) + (ROLine new color: Color blue). el2 addAll: (Array with: elA with: elB). el1 addAll: (Array with: el2 with: edge ). view add: el1. " view open " el2 translateTo: 50@30. elA translateBy: 60@30. self assert: (self encodeForm: view bitmap) = #(229 221 91 202 26 65 20 70 209 41 157 190 91 243 159 152 79 130 182 34 210 85 88 151 181 32 112 158 164 201 191 63 76 2 209 117 78 107 138 233 216 195 191 252 203 191 252 203 191 252 107 156 203 151 239 244 251 186 31 115 218 252 171 222 213 92 22 62 127 100 254 200 252 145 249 35 243 47 127 100 254 200 252 145 249 35 243 71 230 143 204 31 153 63 50 127 100 254 229 143 204 231 143 204 31 153 63 50 127 100 254 229 143 204 31 153 127 249 35 243 249 35 243 71 230 143 204 31 153 127 249 35 243 71 230 199 238 143 204 31 153 63 50 127 100 254 200 252 145 249 151 63 50 159 63 50 127 100 254 200 252 145 249 35 243 71 230 143 204 191 252 145 249 252 145 249 35 243 71 230 143 204 191 252 145 249 35 243 47 127 100 62 127 100 254 200 252 145 249 35 243 47 127 100 254 200 252 145 249 35 243 71 230 143 204 31 153 63 50 127 100 254 229 143 204 231 143 204 31 153 63 50 127 100 254 229 143 204 31 153 127 249 35 243 249 35 243 71 230 143 172 229 145 229 238 211 191 252 203 191 252 171 147 111 42 242 223 70 154 123 27 105 226 217 253 46 252 46 252 46 252 46 252 46 252 46 252 46 134 235 194 255 227 175 255 21 165 254 196 145 137 87 124 15 241 75 241 75 241 75 241 75 241 75 241 75 241 75 241 75 241 75 241 75 241 75 241 249 165 248 252 82 252 82 252 82 252 82 252 82 252 82 252 82 252 82 252 82 252 82 252 82 252 82 124 126 41 126 41 126 41 126 41 126 41 126 41 126 41 126 41 126 41 126 41 126 41 126 41 62 191 20 159 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 74 254 11 29 183 41 197 178 108 126 41 126 41 126 41 126 41 37 223 125 138 53 227 39 227 39 227 39 227 39 227 39 227 39 83 228 133 222 154 241 63 28 194 255 60 60 127 253 254 250 139 62 159 31 145 31 145 31 145 31 209 151 23 58 87 228 71 228 71 228 71 228 71 228 71 228 235 48 162 115 69 126 68 126 68 126 68 126 68 126 68 190 30 35 58 85 228 71 228 71 228 71 228 71 228 71 228 235 50 162 215 138 252 136 252 136 252 136 252 136 252 136 124 125 70 244 82 145 31 145 31 145 31 145 31 145 31 145 175 211 136 158 43 242 35 242 35 242 35 242 35 186 244 67 242 47 246 203 29 253 245 163 235 207 122 134 71 51 126 50 126 50 126 50 126 50 126 50 126 50 109 124 2 205 229 255 221 235 151 226 151 226 151 226 151 242 175 127 180 241 75 241 75 241 75 241 75 241 75 249 44 162 246 47 191 20 159 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 95 138 207 47 197 231 151 226 151 226 151 226 151 226 151 226 151 226 151 226 151 226 151 226 151 226 151 226 151 226 243 75 241 249 165 248 165 248 165 248 165 248 165 248 165 248 165 248 165 248 165 248 165 248 165 248 165 248 58 41 197 191 252 47 119 244 39 62 224 196 139 60 187 223 133 223 133 223 133 223 133 223 133 223 133 223 197 80 93 248 151 127 249 151 127 245 251 151 86 95 181 183 17 255 185 253 10 252 231 246 43 240 159 219 175 192 127 238 97 43 240 47 255 242 47 255 242 47 255 26 238 91 33 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 126 224 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 47 194 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 95 132 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 8 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 17 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 34 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 62 159 207 231 243 249 124 190 177 221 1)! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 13:57'! testUpdating | node bitmap1 bitmap2 view2 | "We first get a bitmap with a black border" view := ROMondrianViewBuilder new. view shape rectangle width: 40; height: 20. node := view node: $a. bitmap1 := view raw bitmap. "We change the color of the element" (node getShape: ROBox) borderColor: Color red. node signalUpdate. "The bitmap should be different now that there is a red border" self assert: bitmap1 ~= view raw bitmap. " bitmap1 asMorph openInWindow bitmap2 asMorph openInWindow view container bitmap asMorph openInWindow "! ! !ROBitmapGenerationTest methodsFor: 'rendering' stamp: 'AlexandreBergel 9/5/2012 10:19'! testViewRendering | bounds form canvas bitmap | node1 := ROElement on: 'hello'. node1 extent: 40 @ 30. node1 addShape: ROBorder new; addShape: (ROBox new color: Color yellow). node1 addInteraction: RODraggable. node2 := ROElement on: 'hello'. node2 extent: 40 @ 30. node2 addShape: (ROBox new color: Color green). node2 translateBy: 100@30. view := ROView new. view add: node1. view add: node2. view camera realExtent: 100@100. bitmap := view bitmap. self assert: (self encodeForm: bitmap) = #(229 215 187 17 128 32 16 69 209 150 86 228 183 253 55 102 1 6 58 35 9 158 27 189 152 67 0 181 140 121 100 196 140 245 43 107 246 81 178 249 235 253 138 15 221 206 62 234 199 229 91 250 150 254 242 45 125 75 223 210 183 244 45 247 176 220 251 29 59 102 105 237 236 177 106 237 104 249 151 155 237 91 250 150 190 165 111 233 91 250 150 190 165 111 41 89 250 127 18 255 252 124 75 127 249 150 254 242 45 125 75 223 210 183 244 151 111 233 47 223 210 95 190 165 111 233 91 250 150 254 242 45 253 229 91 250 150 190 165 111 233 47 223 210 95 190 165 191 86 91 250 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 249 61 119 1) " bitmap asMorph openInWindow "! ! !ROBlinkTest commentStamp: '' prior: 34278783! A ROBlinkTest is a test class for testing the behavior of ROBlink! !ROBlinkTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 17:32'! testBasic | el | el := ROBox element. self assert: (el getShape: ROBox) color = ROBox defaultColor. ROBlink on: el. self assert: (el getShape: ROBox) color ~= ROBox defaultColor. self assert: (el getShape: ROBox) color = ROBlink defaultColor. ! ! !ROBorderTest methodsFor: 'tests'! testInitialization | border | border := ROBorder new. self assert: border color == ROBorder defaultColor! ! !ROBorderTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/10/2012 22:49'! testSetting | border | border := ROBorder new. border color: Color green. self assert: border color = Color green! ! !ROBoxTest methodsFor: 'tests' stamp: 'DR 1/21/2013 20:24'! testChangingBorderColor | box color | box := ROBox new. color := box borderColorFor: ROElement new. box borderColor: Color red. self assert: (box borderColorFor: ROElement new) = Color red. self assert: (box borderColorFor: ROElement new) ~= color! ! !ROBoxTest methodsFor: 'tests'! testChangingWidthColor | box width | box := ROBox new. width := box borderWidthFor: ROElement new. box borderWidth: 4. self assert: (box borderWidthFor: ROElement new) = 4. self assert: (box borderWidthFor: ROElement new) ~= width! ! !ROBoxTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/14/2012 19:11'! testColorAndCache | el box | el := ROElement on: (Array with: Color blue). box := ROBox new color: [ :element | element model first ]. self assert: (box colorFor: el) = Color blue. "el model at: 1 put: Color red." box color: Color green. self assert: (box colorFor: el) = Color green. ! ! !ROBoxTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/14/2012 19:23'! testComputingWidth | box width | box := ROBox new. width := box borderWidthFor: ROElement new. box borderWidth: 4. self assert: (box borderWidthFor: ROElement new) = 4. self assert: (box borderWidthFor: ROElement new) ~= width! ! !ROBoxTest methodsFor: 'tests' stamp: 'DR 1/21/2013 20:23'! testInitialization self assert: ROBox new color = ROBox defaultColor! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'AlexandreBergel 9/29/2013 21:04'! testReusingShapeWithMultipleShapes | el s1 s2 | el := ROElement new. s1 := ROBox green. s1 extent: 20 @ 20. s2 := ROBox gray. el + s1. self assert: (el extent = (20 @ 20)). el + s2. self assert: (el extent = (20 @ 20)). ! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'AlexandreBergel 9/14/2013 11:46'! testReusingShapes | shape el1 el2 | shape := ROBox new. el1 := ROElement new. el1 + shape. el2 := ROElement new. el2 + shape. self assert: (el1 isShapedAs: ROBox). self assert: (el2 isShapedAs: ROBox). self assert: (el1 getShape: ROBox) == shape. self assert: (el2 getShape: ROBox) == shape. ! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'JurajKubelka 10/11/2013 16:56'! testReusingShapesAndResettingCache | shape el | shape := ROBox new. el := ROElement new. el + shape. self assert: (shape extentFor: el) = (5 @ 5). self assert: el extent = (5 @ 5). shape size: 6. self assert: (shape extentFor: el) = (6 @ 6). self assert: el extent = (5 @ 5). el extent: 7 @ 7. self assert: el extent = (7 @ 7). self assert: (shape extentFor: el) = (6 @ 6).! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'AlexandreBergel 9/14/2013 11:49'! testReusingShapesWithDifferentSize | shape el1 el2 | shape := ROBox new size: [ :el | el model ]. el1 := ROElement on: 10. el1 + shape. el2 := ROElement on: 20. el2 + shape. self assert: (shape extentFor: el1) = (10 @ 10). self assert: (shape extentFor: el2) = (20 @ 20). self assert: (shape extentFor: el1) = (10 @ 10). self assert: (shape extentFor: el2) = (20 @ 20). ! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'JurajKubelka 10/11/2013 16:58'! testReusingShapesWithNesting | shape1 shape2 el1 el2 | shape1 := ROBox new. shape2 := ROBox new. el1 := ROElement on: 10. el1 + shape1. el2 := ROElement on: 20. el2 + shape2. el1 add: el2. self assert: (el1 extent) = (15 @ 15). self assert: (shape1 extentFor: el1) = (5 @ 5). self assert: (shape2 extentFor: el2) = (5 @ 5). ! ! !ROBoxTest methodsFor: 'reusing shapes' stamp: 'AlexandreBergel 9/14/2013 17:54'! testReusingShapesWithSize | shape | shape := ROBox new. shape size: 30. self assert: (shape element extent = (30 @ 30))! ! !ROCameraTest methodsFor: 'running' stamp: 'AlexandreBergel 11/14/2012 11:57'! setUp camera1 := ROCamera new. camera2 := ROCamera new. camera2 altitude: 20.! ! !ROCameraTest methodsFor: 'tests'! testAngle self assert: camera1 angle = ROCamera defaultAngle! ! !ROCameraTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/14/2012 12:01'! testDefaultSize self assert: camera1 extent = (500 @ 500). self assert: camera1 width = 500. self assert: camera1 height = 500.! ! !ROCameraTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/9/2013 10:28'! testInitialization self assert: camera1 angle = ROCamera defaultAngle. self assert: camera1 position = ROCamera defaultPosition. self assert: camera1 windowSize = (500 @ 500)! ! !ROCameraTest methodsFor: 'initializing'! testInitialize self assert: ROCamera new extent = ROCamera defaultExtent ! ! !ROCameraTest methodsFor: 'moving'! testMovingUpAndDownCameraShouldBeCentered | view el b1 b2 | view := ROView new. view add: (el := ROElement sprite). "view open." self assert: (el bounds = ( 0@0 corner: 50@50)). b1 := (view camera virtualToRealRectangle: el bounds). "we move up" view camera moveDown. b2 := (view camera virtualToRealRectangle: el bounds). self assert: b1 extent < b2 extent. "check at the position of the element" self assert: b1 origin < b2 origin ! ! !ROCameraTest methodsFor: 'moving' stamp: 'DR 3/25/2013 21:55'! testMovingUpAndDownCameraShouldBeCentered2 | view el b1 b2 points | view := ROView new. view add: (el := ROElement sprite). el center: 250@250. self assert: el center = (250@250). "view open." b1 := (view camera virtualToRealRectangle: el bounds). self assert: b1 center = (250@250). "we move up" view camera moveUp. b2 := (view camera virtualToRealRectangle: el bounds). points := Array with: 230@230 with: 229@229. self assert: (points includes: b2 center).! ! !ROCameraTest methodsFor: 'resizing' stamp: 'AlexandreBergel 11/14/2012 12:02'! testResizingHeight camera1 height: 30. self assert: camera1 height = 30. self assert: camera1 width = 500! ! !ROCameraTest methodsFor: 'resizing' stamp: 'AlexandreBergel 7/9/2013 10:28'! testResizingView | view | view := ROView new. self assert: view camera windowSize = (500 @ 500). view windowSize: 40 @ 60. self assert: view camera windowSize = (40 @ 60)! ! !ROCameraTest methodsFor: 'resizing' stamp: 'AlexandreBergel 11/14/2012 12:02'! testResizingWidth camera1 width: 30. self assert: camera1 width = 30. self assert: camera1 height = 500! ! !ROCameraTest methodsFor: 'resizing' stamp: 'AlexandreBergel 12/1/2012 17:33'! testResizingWithMorph | cls view camera visualElement | view := ROView new. cls := ROPlatform current hostVisualElement. visualElement := cls on: view. camera := view camera. visualElement extent: (500 @ 500). self assert: visualElement extent = (500 @ 500). self assert: camera extent = (500 @ 500). self assert: camera windowSize = (500 @ 500). visualElement extent: (300 @ 200). self assert: camera extent = (500 @ 500). self assert: camera windowSize = (300 @ 200). ! ! !ROCameraTest methodsFor: 'resizing' stamp: 'AlexandreBergel 12/1/2012 17:38'! testResizingWithMorphAndStack | cls view1 view2 viewStack camera visualElement | view1 := ROView new. view2 := ROView new. viewStack := ROViewStack new. viewStack addView: view1; addView: view2. cls := ROPlatform current hostVisualElement. visualElement := cls on: viewStack. camera := viewStack camera. visualElement extent: (500 @ 500). self assert: visualElement extent = (500 @ 500). self assert: camera extent = (500 @ 500). self assert: camera windowSize = (500 @ 500). self assert: view1 camera windowSize = (500 @ 500). self assert: view1 camera windowSize = (500 @ 500). visualElement extent: (300 @ 200). self assert: camera extent = (500 @ 500). self assert: camera windowSize = (300 @ 200). self assert: view1 camera windowSize = (300 @ 200). self assert: view1 camera windowSize = (300 @ 200). ! ! !ROCameraTest methodsFor: 'translating'! testTranslating self assert: (camera1 virtualToRealPoint: (camera1 realToVirtualPoint: 250@500)) = ( 250@500). self assert: (camera1 realToVirtualPoint: 250@500) = ( 250@500). camera1 translateBy: 50@30. self assert: (camera1 virtualToRealPoint: (camera1 realToVirtualPoint: 250@500)) = ( 250@500). self assert: (camera1 realToVirtualPoint: 250@500) = ( 300@530).! ! !ROCanvasWrapperTest methodsFor: 'tests' stamp: 'VanessaPena 1/4/2013 10:21'! testCreation |wrapper canvas| canvas := RONullCanvas new. wrapper := ROCanvasWrapper onCanvas: canvas. self assert: (wrapper canvas = canvas) ! ! !ROCanvasWrapperTest methodsFor: 'tests' stamp: 'VanessaPena 1/4/2013 10:33'! testDrawing |wrapper canvas view| canvas := ROTracingCanvas new. wrapper := ROCanvasWrapper onCanvas: canvas. view := ROView new. view add: ROElement sprite. self assert: (wrapper canvas = canvas). view drawOn: wrapper. self assert: (wrapper canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(0@0)' '(50@0)' 1 'Color red') #(#line '(50@0)' '(50@50)' 1 'Color red') #(#line '(50@50)' '(0@50)' 1 'Color red') #(#line '(0@50)' '(0@0)' 1 'Color red'))) ! ! !RONoTextCanvasWrapperTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 17:18'! testLabelDrawing |wrapper view canvas| canvas := ROTracingCanvas new. wrapper := RONoTextCanvasWrapper onCanvas: canvas. view := ROView new. view add: ((ROElement new model: 'hola') + ROLabel). view drawOn: canvas. self assert: (canvas trace size = 2). self assert: (canvas trace first = #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white')). self assert: canvas trace second = #(#drawStringColor 'hola' '(3@3)' 'Color black'). canvas initialize. view drawOn: wrapper. self assert: (canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white'))).! ! !ROCircleTest methodsFor: 'running' stamp: 'VanessaPena 3/12/2013 15:30'! setUp node := ROElement on: 'hello'. node extent: 40 @ 30. node addShape: (ROEllipse new color: Color green) ! ! !ROCircleTest methodsFor: 'tests' stamp: 'VanessaPena 3/12/2013 15:30'! testInitialization self assert: (ROEllipse new color = ROEllipse defaultColor)! ! !ROCollectionTest methodsFor: 'interaction' stamp: 'AlexandreBergel 4/18/2012 14:44'! testAddInteraction | elements | elements := ROElement forCollection: (1 to: 20). self assert: (elements allSatisfy: [ :e | (e is: RODraggable) not ]). elements @ RODraggable. self assert: (elements allSatisfy: [ :e | e is: RODraggable ]).! ! !ROColorAlphaFadingTest commentStamp: '' prior: 34278913! A ROColorAlphaFadingTest is a test class for testing the behavior of ROColorAlphaFading! !ROColorAlphaFadingTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/18/2013 08:03'! testInitialize | view shape element | view := ROView new. shape := ROBox black. element := shape element. view add: element. self assert: (element getShape: ROBox) == shape. self assert: shape color alpha = 1.0. ROColorAlphaFading new for: element nbCycles: 200. self assert: shape color alpha = 0.0. ! ! !ROColorTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/11/2012 18:02'! testAdjustBrightness self assert: (((Color gray: 0.7) adjustBrightness: -0.2) brightness - 0.5) < 0.01 ! ! !ROColorTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/11/2012 18:03'! testAdjustBrightnessNegativo self assert: (((Color gray: 0.7) adjustBrightness: -0.2) brightness - 0.5) < 0.01 ! ! !ROColorTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/11/2012 18:03'! testAdjustBrightnessPositivo self assert: (((Color gray: 0.5) adjustBrightness: 0.2) brightness - 0.7) < 0.01 ! ! !ROColorTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/11/2012 17:25'! testBrightness self assert: Color red brightness = 1.0. self assert: Color green brightness = 1.0. self assert: Color blue brightness = 1.0. self assert: ((Color gray: 0.7) brightness - 0.7) < 0.1! ! !ROConstraintTest methodsFor: 'running' stamp: 'AlexandreBergel 11/15/2012 16:30'! setUp super setUp. view := ROView new. element1 := ROElement sprite. element1 extent: 50 @ 50. element2 := ROElement sprite. view add: element1. view add: element2.! ! !ROConstraintTest methodsFor: 'event generations' stamp: 'AlexandreBergel 5/22/2013 11:12'! testEvent | v outer inner innerLabel innerElement t | v := ROView new. outer := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. innerLabel := ROLabel elementOn: 'My sprite'. innerElement := ROElement spriteOn: 'Inner element'. outer add: inner; add: innerLabel. inner add: innerElement. "We layout the things" ROGridLayout on: inner elements. ROVerticalLineLayout on: outer elements. ROConstraint stick: innerLabel below: inner. v add: outer. "-------" t := 0. inner on: ROElementTranslated do: [ :event | t := t + 1 ]. self assert: t = 0. innerElement translateBy: -1 @ 0. self assert: t = 0. ! ! !ROConstraintTest methodsFor: 'event generations' stamp: 'AlexandreBergel 5/22/2013 11:13'! testEvent2 | v outer inner innerLabel innerElement t | v := ROView new. outer := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. innerLabel := ROLabel elementOn: 'My sprite'. innerElement := ROElement spriteOn: 'Inner element'. outer add: inner; add: innerLabel. inner add: innerElement. "We layout the things" ROGridLayout on: inner elements. ROVerticalLineLayout on: outer elements. ROConstraint stick: innerLabel below: inner. v add: outer. "-------" t := 0. inner on: ROElementEvent do: [ :event | t := t + 1 ]. self assert: t = 0. innerElement translateBy: 5 @ 0. self assert: t = 1. ! ! !ROConstraintTest methodsFor: 'event generations' stamp: 'AlexandreBergel 10/1/2012 09:23'! testEventIfNoMoved | el t | el := ROElement new. t := 0. el on: ROElementTranslated do: [ :event | t := t + 1 ]. el translateBy: 0 @ 0. self assert: t = 0.! ! !ROConstraintTest methodsFor: 'event generations' stamp: 'AlexandreBergel 10/1/2012 09:28'! testEventIfResized | el t | el := ROElement new. t := 0. el on: ROElementEvent do: [ :event | t := t + 1 ]. el extent: 10 @ 10. self assert: t = 1.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 9/30/2012 21:07'! testStickAbove ROConstraint stick: element1 above: element2. self assert: (element2 position - (0 @ element1 height)) = element1 position. element2 translateTo: 60 @ 30. self assert: (element2 position - (0 @ element1 height)) = element1 position.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 9/30/2012 21:06'! testStickBelow ROConstraint stick: element1 below: element2. self assert: (element2 position + (0 @ element2 height)) = element1 position. element2 translateTo: 60 @ 30. self assert: (element2 position + (0 @ element2 height)) = element1 position.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 12/18/2012 15:38'! testStickToBottomLeft ROConstraint stickToBottomLeft: element1 offset: 0. element1 translateTo: 60 @ 30. self assert: element1 position = (60 @ 30). element1 view windowSize: 100 @ 80. self assert: element1 position = (0 @ (80 - element1 height)).! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'VanessaPena 3/14/2013 17:11'! testStickToTheCenter ROConstraint stick: element1 onTheCenterOf: element2. self assert: (element1 position - (((element2 width - element1 width) / 2) @ ((element2 height - element1 height) / 2))) = element2 position. element2 translateTo: 60 @ 30. self assert: (element1 position - (((element2 width - element1 width) / 2) @ ((element2 height - element1 height) / 2))) = element2 position.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 9/30/2012 20:35'! testStickToTheLeft ROConstraint stick: element1 onTheLeftOf: element2. self assert: (element1 position + (element1 width @ 0)) = element2 position. element2 translateTo: 60 @ 30. self assert: (element1 position + (element1 width @ 0)) = element2 position.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 9/30/2012 21:01'! testStickToTheRight ROConstraint stick: element1 onTheRightOf: element2. self assert: (element2 position + (element2 width @ 0)) = element1 position. element2 translateTo: 60 @ 30. self assert: (element2 position + (element2 width @ 0)) = element1 position.! ! !ROConstraintTest methodsFor: 'sticking' stamp: 'AlexandreBergel 12/18/2012 15:40'! testStickToTopRight ROConstraint stickToTopRight: element1 offset: 0. element1 translateTo: 60 @ 30. self assert: element1 position = (60 @ 30). element1 view windowSize: 100 @ 80. self assert: element1 position = (50@0)! ! !ROCountingNullCanvasTest methodsFor: 'test' stamp: 'AlexandreBergel 6/21/2013 09:38'! testBasic | rawView view canvas | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. view shape rectangle size: 40. view nodes: (1 to: 20). view gridLayout. canvas := ROCountingNullCanvas new. view raw drawOn: canvas. self assert: canvas numberOfRectangles = 21! ! !RODecoratorTest methodsFor: 'running' stamp: 'AlexandreBergel 4/14/2012 19:40'! setUp box := ROBox new. box2 := ROBox new color: Color blue. label := ROLabel new. element := ROElement new. ! ! !RODecoratorTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/17/2012 08:48'! testAddLast box addLast: box2. box2 addLast: label. self assert: box next == box2. self assert: label next class == RONullShape.! ! !RODecoratorTest methodsFor: 'tests' stamp: 'DR 1/21/2013 20:19'! testExample | el view | view := ROView new. view add: ((el := ROElement on: 10) + (ROBox new color: Color red; borderColor: Color blue)+ ROLabel). " view open " self assert: el shapes second borderColor = Color blue. self assert: el numberOfShapes = 3. ! ! !RODecoratorTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 12:18'! testLinked " self debug: #testLinked " self assert: box next class == RONullShape. self assert: label next class == RONullShape. element addShape: box; addShape: label. self assert: label next == box. self assert: box next class == RONullShape! ! !RODraggableTest methodsFor: 'running' stamp: 'AlexandreBergel 5/7/2012 11:54'! setUp node := ROElement new. node addShape: (ROBox new). draggableNode := ROElement new. draggableNode extent: 50@50. draggableNode + ROBox. draggableNode @ RODraggable.! ! !RODraggableTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2012 11:54'! testAddition | bounds | node := ROElement new. node addShape: (ROBox new). node addInteraction: RODraggable. bounds := node bounds. node announce: (ROMouseDragging new step: 5 @ 5). self assert: (bounds translateBy: 5 @ 5) = node bounds ! ! !RODraggableTest methodsFor: 'tests'! testAnnouncingDraggingWhileBeingRegistered | bounds | bounds := node bounds. node addInteraction: RODraggable. node announce: (ROMouseDragging new step: 4@3). self assert: (bounds translateBy: 4@3) = node bounds. ! ! !RODraggableTest methodsFor: 'tests'! testAnnouncingDraggingWithoutBeingRegistered | bounds | bounds := node bounds. node announce: (ROMouseDragging new step: 4@3). self assert: bounds = node bounds. ! ! !RODraggableTest methodsFor: 'tests'! testDraggable self deny: (node is: RODraggable). self assert: (node numberOfInteractions isZero). node addInteraction: RODraggable new. self assert: (node is: RODraggable). ! ! !RODraggableTest methodsFor: 'tests'! testDraggableByClass self deny: (node is: RODraggable). self assert: (node numberOfInteractions isZero). node addInteraction: RODraggable. self assert: (node is: RODraggable). ! ! !RODraggableTest methodsFor: 'tests'! testDraggingStep | view p1 | view := ROView new. view add: draggableNode. "dragging a node increases its position by the dragging step" p1 := draggableNode position. self assert: (p1 = (0@0)). draggableNode announce: (ROMouseDragging step: 10 @ 6). self assert: (draggableNode position = (10 @ 6)). draggableNode announce: (ROMouseDragging step: -10 @ -6). self assert: (draggableNode position = (0 @ 0)). "take care of real vs virtual steps" view camera bounds: (0@0 corner: 250@250). draggableNode announce: (ROMouseDragging step: 10 @ 6). self assert: (draggableNode position = ( 5@3)).! ! !RODraggableTest methodsFor: 'tests'! testElementToBeAdded | drag | self assert: (RODraggable elementToBeAdded class == RODraggable). drag := RODraggable new. self assert: (drag elementToBeAdded == drag)! ! !RODraggableTest methodsFor: 'nesting' stamp: 'AlexandreBergel 9/5/2012 08:42'! testNesting | view node1 b innerNode | view := ROView new. node1 := ROElement spriteOn: 'hello'. node1 add: (innerNode := ROElement spriteOn: 'world'). view add: node1. node1 translateBy: 10@20. b := node1 bounds. ROAdjustSizeOfNesting on: node1. ROAdjustSizeOfNesting on: node1. self assert: (b = node1 bounds). innerNode extent: 10@10. innerNode translateBy: 1 @ 1. self assert: (b = node1 bounds). innerNode translateBy: 5 @ 5. innerNode translateBy: 5 @ 5. self assert: (b = node1 bounds). innerNode announce: (ROMouseDragging step: 5 @ 5). innerNode announce: (ROMouseDragging step: 5 @ 5). self assert: (b = node1 bounds). " view openInWindow "! ! !ROEaselTest methodsFor: 'running' stamp: 'AlexandreBergel 7/14/2012 14:25'! setUp super setUp. easel := ROEaselMorphic new. ! ! !ROEaselTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2013 13:53'! testExtractingTemporaryVariables | src | src := 'fooOn: rawView | a b c| rawView zork'. self assert: (easel getTempStringOf: src) = '| a b c|'. self assert: (easel getTempsOf: src) = #('a' 'b' 'c'). self assert: (easel removeHeadingOf: src) = ' rawView zork '.! ! !ROEaselTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2013 13:53'! testExtractingTemporaryVariables2 | src | src := 'fooOn: rawView view interaction action: [:cls | | blah | Transcript show: 10 printString ;cr ]'. self assert: (easel getTempStringOf: src) = ''. self assert: (easel getTempsOf: src) = #(). self assert: (easel removeHeadingOf: src) = ' view interaction action: [:cls | | blah | Transcript show: 10 printString ;cr ] '! ! !ROEaselTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/1/2012 17:10'! testOpeningAndClosingWorkspace | allWindows r | allWindows := SystemWindow allInstances. easel open. "We have two windows displayed" self assert: (SystemWindow allInstances copyWithoutAll: allWindows ) size = 2. "If we remove the view window, the workspace should also been removed" easel close ! ! !ROEaselTest methodsFor: 'examples' stamp: 'AlexandreBergel 5/7/2013 13:54'! testScriptPreambuleForSource | src | src := easel scriptPreambuleForSource: (ROExample >> #arrowedLineOn:) sourceCode. self assert: (src = '"Preambule. It includes the initialization. " | rawView view n1 n2 | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "enter your script below" "-------------" "-------------" ')! ! !ROEaselTest methodsFor: 'examples' stamp: 'AlexandreBergel 7/29/2012 10:31'! testSourceExample | src | src := easel getExampleSourceFor: (ROExample >> #arrowedLineOn:). self assert: src = '"Source code: ROExample>>arrowedLineOn:" "Preambule. It includes the initialization. " | view rawView n1 n2 | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "-------------" "-------------" n1 := ROElement sprite. n2 := ROElement sprite. n2 translateBy: 20@60. rawView add: n1; add: n2; add: (ROEdge arrowedLineFrom: n1 to: n2). "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view noLayout. view open'! ! !ROEaselTest methodsFor: 'examples' stamp: 'AlexandreBergel 7/30/2012 00:01'! testSourceMondrianExample | src | src := easel getExampleSourceFor: (ROMondrianExample >> #middleArrowOnEdgesOn:). self assert: src = '"Source code: ROMondrianExample>>middleArrowOnEdgesOn:" "Preambule. It includes the initialization. " | view rawView | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "-------------" "-------------" view shape label. view nodes: #(1 2 3 ). view shape arrowedLineWithOffset: 0.5. view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3 with: 3 -> 1). view circleLayout. "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view open'! ! !ROContainingElementTest methodsFor: 'running' stamp: 'AlexandreBergel 4/19/2013 18:30'! setUp node2 := ROElement on: 'world'. node2 extent: 40@30. node2 addShape: (ROBox new color: Color green). node3 := ROElement on: 'world'. node3 extent: 40@30. node3 addShape: (ROBox new color: Color yellow). node3 translateBy: 40@30. node1 := ROElement on: 'hello'. node1 extent: 100 @ 130. node1 addShape: ROBox new; addShape: ROBorder new.! ! !ROContainingElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2012 00:38'! testAddingWithResize self assert: node3 extent < node1 extent. node3 add: node1. self assert: node3 extent > node1 extent! ! !ROContainingElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/2/2012 14:27'! testAddingWithoutResize self assert: node3 extent < node1 extent. node3 resizeStrategy: ROFixedSizedParent instance. node3 add: node1. self assert: node3 extent < node1 extent! ! !ROContainingElementTest methodsFor: 'blocking and nesting' stamp: 'AlexandreBergel 4/29/2013 16:43'! testBlockingAndNesting | outter inner | outter := ROBox element extent: 50 @ 50; yourself. inner := ROBox green element extent: 20 @ 20; yourself. outter resizeStrategy: (ROFixedSizedParent new). outter add: inner. self assert: outter extent = (50 @ 50). self assert: outter position = (0 @ 0). "Translating the inner node should not modify the outter node at all" inner translateBy: -15 @ -15. self assert: inner position = outter resizeStrategy padding. self assert: inner position = (5 @ 5). self assert: outter extent = (50 @ 50). self assert: outter position = (0 @ 0). ! ! !ROContainingElementTest methodsFor: 'blocking and nesting' stamp: 'AlexandreBergel 4/29/2013 16:15'! testBlockingAndNesting2 | outter inner | outter := ROBox element extent: 50 @ 50; yourself. inner := ROBox green element extent: 20 @ 20; yourself. outter resizeStrategy: (ROFixedSizedParent new). outter add: inner. self assert: outter extent = (50 @ 50). self assert: outter position = (0 @ 0). "Translating the inner node should not modify the outter node at all" inner translateBy: 150 @ 100. self assert: inner position = (25 @ 25). self assert: outter extent = (50 @ 50). self assert: outter position = (0 @ 0). " | view | view := ROView new. view add: outter. view open "! ! !ROContainingElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/24/2013 16:53'! testContainsEdge | view roView nodes edge | view := ROMondrianViewBuilder new. view shape rectangle size: 50. nodes := view nodes: #( 1 2 ). node1 := nodes first. node2 := nodes second. view shape line width: 4. view interaction popupText: 'edge!!'. edge := view edgeFromAssociation: 1 -> 2. view applyLayout. roView := view raw. self assert: (edge contains: 60 @ 30). self assert: (roView elementAt: 60 @ 30) == edge. self assert: (roView elementAt: edge bounds center) == edge. self assert: (roView elementAt: node1 center) == node1. self assert: (roView elementAt: node2 center) == node2. ! ! !ROContainingElementTest methodsFor: 'dragging' stamp: 'AlexandreBergel 4/23/2013 19:33'! testDraggingNestedElement | b | "node1 bounds = 50@50 corner: 150@180 node3 bounds = 190@130 corner: 230@160 " node1 addInteraction: RODraggable. node3 addInteraction: RODraggable. node1 add: node3. node1 translateBy: 50 @ 50. "We move the inner node toward the bottom right corner" node3 translateBy: 150 @ 100. self assert: (node1 extent = (240@170)). "We move the inner node toward the top left corner" b := node1 bounds. node3 translateBy: -200 @ -150. self assert: node1 topLeft ~= b topLeft. self assert: node1 topLeft = (45@35) " view open "! ! !ROContainingElementTest methodsFor: 'translation shape and inner nodes' stamp: 'AlexandreBergel 12/11/2012 12:55'! testElementAt | el view | el := ROElement new + ROBox. el extent: 20 @ 20. view := ROView new. view add: el. el translateTo: 3 @ 3. self assert: (view elementAt: 3 @ 3) == el. ! ! !ROContainingElementTest methodsFor: 'view' stamp: 'AlexandreBergel 4/24/2013 08:46'! testElementAtAfterDragging | view | view := ROView new. node1 add: node2. view add: node1. node1 translateTo: 50@50. self assert: (view elementAt: (node1 extent + node1 absolutePosition)) == view. self assert: (view elementAt: (50 @ 50)) == node1. self assert: (view elementAt: (55 @ 55)) == node2. self assert: (view elementAt: node1 topLeft + (5 @ 5)) == node2 ! ! !ROContainingElementTest methodsFor: 'element from model' stamp: 'AlexandreBergel 9/1/2013 13:30'! testElementFromModel | el1 el2 el3 el4 | el1 := ROElement on: 1. el2 := ROElement on: 2. el3 := ROElement on: 3. el4 := ROElement on: 4. el1 add: el2. el1 add: el4. el2 add: el3. self assert: (el3 elementFromModel: 4) isNil. self assert: (el2 elementFromModel: 1) isNil. self assert: (el2 elementFromModel: 3) == el3. self assert: (el1 elementFromModel: 3) == el3.! ! !ROContainingElementTest methodsFor: 'events' stamp: 'AlexandreBergel 4/24/2013 16:54'! testEventForNested | view circle grid options choice t morph | t := 0. view := ROView new. circle := ROElement new addInteraction: RODraggable; extent: 100@40; addShape: (ROBorder red); addShape: (ROLabel text: 'circle'). circle on: ROMouseClick do: [:e | t := t + 1 ]. grid := ROElement new addInteraction: RODraggable; extent: 100@40; addShape: (ROBorder red); addShape: (ROLabel text: 'grid'). grid on: ROMouseClick do: [:e | t := t + 10 ]. options := (Array with: circle with: grid). choice := ROElement new. choice addAll: (ROHorizontalLineLayout on: options). view add: choice. " view openInWindow. " "grid adjustSizeOfParent " morph := ROPlatform current widgetFactory forView: view. morph extent: 200@200. self assert: choice bounds = ( 0@0 corner: 225@55). "virtual position = 63@29" self assert: (choice contains: 63@29). "real position 32@15" self assert: (morph elementForRealPosition: 32@15) ~~ view. ! ! !ROContainingElementTest methodsFor: 'translating shape' stamp: 'AlexandreBergel 9/25/2012 17:51'! testNoTranslationShape | el | el := ROElement new. el + ROBox. el extent: 50 @ 50. self assert: (el contains: 0 @ 0). self assert: (el contains: 25 @ 25). self deny: (el contains: 50 @ 50).! ! !ROContainingElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/15/2012 10:46'! testRemovingWithResize node3 add: node1. self assert: node3 extent > node1 extent. node3 removeAllElements. ROShrikingSize on: node3. self assert: node3 extent < node1 extent! ! !ROContainingElementTest methodsFor: 'view' stamp: 'AlexandreBergel 9/10/2012 09:14'! testSettingTheView | newNode view | newNode := ROElement new. self assert: (newNode view == ROView nullView). self assert: (node1 view == ROView nullView). view := ROView new. view add: node1. node1 add: newNode. self assert: (newNode view == view)! ! !ROContainingElementTest methodsFor: 'sizing' stamp: 'JurajKubelka 10/11/2013 16:19'! testSize | el el2 | el := ROElement new. self assert: (el extent = (5 @ 5)). el add: (el2 := ROElement sprite). ROAdjustSizeOfNesting on: el. self assert: (el extent = (el2 extent + (10 @ 10))) ! ! !ROContainingElementTest methodsFor: 'sizing'! testSize2 | bounds el | el := ROElement sprite. bounds := el bounds. ROAdjustSizeOfNesting on: el. self assert: (el bounds = bounds) ! ! !ROEdgeTest methodsFor: 'popup' stamp: 'AlexandreBergel 8/20/2012 11:06'! doesNOTWORKtestPopup "Apparently this test run into concurency problems" | t | edge @ ROPopup. edge announce: ROMouseEnter. t := 0. 10 timesRepeat: [ (Delay forMilliseconds: 2) wait. t := t max: view raw elements size. ]. self assert: t = 4.! ! !ROEdgeTest methodsFor: 'running' stamp: 'AlexandreBergel 12/11/2012 14:30'! setUp view := ROMondrianViewBuilder new. view shape rectangle size: 30. view nodes: (1 to: 2). node1 := view raw elements first. node2 := view raw elements second. view interaction popupText: 'FooZork'. edge := view edgeFromAssociation: 1 -> 2. view applyLayout! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/18/2012 09:35'! testArrowedEdge | n1 n2 line | n1 := ROElement new. n2 := ROElement new. edge := ROEdge arrowedLineFrom: n1 to: n2. self assert: edge from == n1. self assert: edge to == n2. line := edge getShape: ROLine. self assert: line numberOfArrows = 1! ! !ROEdgeTest methodsFor: 'building edges' stamp: 'AlexandreBergel 8/11/2013 22:08'! testBuildingEdges | elements | view := ROView new. view addAll: (elements := ROBox green elementsOn: (1 to: 10)). elements do: [ :el | el @ ROPopup ]. view addAll: (ROLine buildEdgesFromElements: view elements from: [ :n | n // 2 ] to: #yourself). ROTreeLayout on: view elementsNotEdge edges: view elementsAsEdge. self assert: view elementsNotEdge size = 10. self assert: view elementsAsEdge size = 9.! ! !ROEdgeTest methodsFor: 'building edges' stamp: 'AlexandreBergel 10/21/2013 14:17'! testBuildingEdgesToAll | elements | view := ROView new. view addAll: (elements := ROBox green elementsOn: (1 to: 3)). elements do: [ :el | el @ ROPopup ]. view addAll: (ROLine buildEdgesFromElement: view elements first from: #yourself toAll: [ :v | (Array with: v + 1 with: v + 2) ]). ROTreeLayout on: view elementsNotEdge edges: view elementsAsEdge. self assert: view elementsNotEdge size = 3. self assert: view elementsAsEdge size = 2.! ! !ROEdgeTest methodsFor: 'building edges' stamp: 'AlexandreBergel 8/12/2013 19:06'! testBuildingEdgesWithEmptyElements self shouldnt: [ ROView new addAll: (ROLine buildEdgesFromElements: #() from: nil to: nil) ] raise: Error. ! ! !ROEdgeTest methodsFor: 'building edges' stamp: 'AlexandreBergel 9/1/2013 13:33'! testBuildingEdgesWithNilModel view := ROView new. view add: (ROElement new). view add: (ROElement on: 1). view add: (ROElement on: 2). self assert: view numberOfElements = 3. ROEdge buildEdgesFromElements: view elements from: #yourself to: [ :v | v + 1 ]. self assert: view numberOfElements = 4. ! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/20/2012 10:03'! testContains self deny: ((ROEdge from: ROElement new to: ROElement new) contains: 10@40)! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2012 14:46'! testCreation self should: [ ROEdge from: Object new to: Object new ] raise: Exception! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/17/2012 12:29'! testEdgeBounds self assert: edge bounds = ( (5@5) corner: (75@35) ). ! ! !ROEdgeTest methodsFor: 'lookup' stamp: 'AlexandreBergel 12/5/2012 17:58'! testElementFromModel edge model: 42. self assert: (edge elementFromModel: 42) isNil. self assert: (edge edgeFromModel: 42) == edge. self assert: (edge edgeFromModel: 43) isNil! ! !ROEdgeTest methodsFor: 'lookup' stamp: 'AlexandreBergel 8/19/2012 21:49'! testGetFromView | roView | roView := view raw. self assert: (roView elementAtRealPosition: edge bounds center) == edge! ! !ROEdgeTest methodsFor: 'popup' stamp: 'AlexandreBergel 8/20/2012 11:07'! testInteraction self assert: edge numberOfInteractions = 1. edge @ ROPopup. self assert: edge numberOfInteractions = 2.! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/20/2013 15:31'! testIsVisibleIn | e1 e2 | e1 := (ROBox size: 20) element. e2 := (ROBox size: 20) element. edge := ROLine elementFrom: e1 to: e2. self assert: (edge isVisibleIn: (0 @ 0 corner: 50 @ 50)). e2 translateTo: 100 @ 100. self assert: (edge isVisibleIn: (0 @ 0 corner: 50 @ 50)). e1 translateTo: 110 @ 110. self deny: (edge isVisibleIn: (0 @ 0 corner: 50 @ 50)). ! ! !ROEdgeTest methodsFor: 'line segment' stamp: 'AlexandreBergel 12/11/2012 14:30'! testLineSegment | shape segments | shape := edge getShape: ROShape. segments := shape lineSegmentsFor: edge. self assert: segments size = 2. self assert: segments first = node1 rightCenter. self assert: segments second = node2 leftCenter! ! !ROEdgeTest methodsFor: 'line segment' stamp: 'AlexandreBergel 8/19/2012 21:05'! testLineSegment2 | shape segments | node2 translateBy: 80 @ 60. shape := edge getShape: ROShape. segments := shape lineSegmentsFor: edge. self assert: segments size = 2. self assert: segments first = node1 rightCenter. self assert: segments second = node2 leftCenter! ! !ROEdgeTest methodsFor: 'orthoHorizontal' stamp: 'AlexandreBergel 8/19/2012 19:11'! testOrthoHorizontalLineSegmentWithTranslation | lineShape segments | node2 translateBy: 50@80. edge + (lineShape := ROOrthoHorizontalLineShape new). segments := lineShape lineSegmentsFor: edge. self assert: segments size = 4. self assert: segments = (Array with: node1 topRight + (0 @ (node1 height / 2)) with: (node2 topLeft x - node1 topRight x) / 2 + node1 topRight x @ (node1 position y + (node1 height / 2)) with: (node2 topLeft x - node1 topRight x) / 2 + node1 topRight x @ (node2 position y + (node2 height / 2)) with: node2 topLeft + (0 @ (node2 height / 2)) )! ! !ROEdgeTest methodsFor: 'orthoHorizontal' stamp: 'miltonmamani 4/16/2013 17:53'! testOrthoHorizontalSamePosition | el1 el2 | view := ROView new. el1 := ROElement sprite. el2 := ROElement sprite. edge := ROEdge from: el1 to: el2. edge + ROOrthoHorizontalLineShape new. view addAll: (Array with: el1 with: el2 with: edge). self shouldnt: [ edge contains: 40 @ 30 ] raise: Error.! ! !ROEdgeTest methodsFor: 'orthoVertical' stamp: 'AlexandreBergel 8/27/2013 21:32'! testOrthoVerticalLineContainsPoint | lineShape segments | edge change: ROLine for: (lineShape := ROOrthoVerticalLineShape new). node2 translateBy: 50@100. segments := lineShape lineSegmentsFor: edge. self assert: (edge contains: (21 @ 52)). self assert: (edge contains: (111 @ 88)). self assert: (edge contains: (64 @ 70)).! ! !ROEdgeTest methodsFor: 'orthoVertical' stamp: 'AlexandreBergel 8/19/2012 21:38'! testOrthoVerticalLineSegmentWithTranslation | lineShape segments | node2 translateBy: 50@100. edge + (lineShape := ROOrthoVerticalLineShape new). segments := lineShape lineSegmentsFor: edge. self assert: segments size = 4. self assert: segments = (Array with: node1 bottomCenter with: node1 bottomCenter x @ ((node2 topCenter y - node1 bottomCenter y) / 2 + node1 bottomCenter y) with: node2 bottomCenter x @ ((node2 topCenter y - node1 bottomCenter y) / 2 + node1 bottomCenter y) with: node2 topCenter) ! ! !ROEdgeTest methodsFor: 'orthoVertical' stamp: 'miltonmamani 4/16/2013 17:54'! testOrthoVerticalSamePosition | el1 el2 | view := ROView new. el1 := ROElement sprite. el2 := ROElement sprite. edge := ROEdge from: el1 to: el2. edge + ROOrthoVerticalLineShape new. view addAll: (Array with: el1 with: el2 with: edge). self shouldnt: [ edge contains: 40 @ 30 ] raise: Error.! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/19/2012 12:12'! testPopupFixture self assert: view raw elements size = 3. ! ! !ROEdgeTest methodsFor: 'tests' stamp: 'AlexandreBergel 1/26/2013 19:13'! testTopLeftAndContaint edge := ROEdge from: ROElement new to: ROElement new. self assert: edge topLeft = (0 @ 0). self deny: (edge contains: 5 @ 5)! ! !ROElementTest methodsFor: 'running' stamp: 'AlexandreBergel 5/7/2012 11:54'! setUp node := ROElement on: 'hello'. node extent: 40 @ 30. node addShape: ROBox new; addShape: ROBorder new. draggableNode := ROElement new. draggableNode @ RODraggable. draggableNode extent: 50@50. draggableNode + ROBorder red.! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 12/11/2012 12:22'! testAddShape | el shape1 shape2 | el := ROElement new. self assert: el numberOfShapes = 1. shape1 := ROBox new. shape2 := ROLabel new. shape1 next: shape2. el addShape: shape1. self assert: el numberOfShapes = 3! ! !ROElementTest methodsFor: 'event' stamp: 'TudorGirba 9/9/2012 21:41'! testAllElementsDo | node1 node2 node21 edge root traversed | root := ROElement new. node1 := ROElement new. node2 := ROElement new. edge := ROEdge from: node1 to: node2. node21 := ROElement new. root add: node1. root add: node2. root add: edge. node2 add: node21. traversed := OrderedCollection new. root allElementsDo: [:each | traversed add: each]. self assert: traversed size = 4. self assert: traversed first = node1. self assert: traversed second = node2. self assert: (traversed at: 3) = node21. self assert: traversed last = edge! ! !ROElementTest methodsFor: 'event'! testAnnounce | node1 node2 bounds | node1 := ROElement new. node2 := ROElement new. node1 on: ROMouseClick do: [ ROGrow on: node2 by: 1 ]. bounds := node2 bounds. node1 announce: ROMouseClick. self assert: (bounds extent < node2 bounds extent)! ! !ROElementTest methodsFor: 'attributes' stamp: 'AlexandreBergel 9/14/2013 12:27'! testAttributes node := ROElement new. self deny: node hasAttributes. node attributes at: #oldColor put: Color black. self assert: node hasAttributes.! ! !ROElementTest methodsFor: 'cache' stamp: 'AlexandreBergel 9/14/2013 12:46'! testCacheOnElement | e | e := ROElement new. self assert: e attributes isEmpty.! ! !ROElementTest methodsFor: 'cache' stamp: 'JurajKubelka 10/11/2013 17:27'! testCacheOnElement2 | e | e := ROElement new. e attributeAt: #anyCache put: 5. self assert: e attributes size = 1 ! ! !ROElementTest methodsFor: 'cache' stamp: 'JurajKubelka 10/11/2013 17:28'! testCacheOnElementAndAddingShape | e | e := ROElement new. e attributeAt: #fooCache put: -1. e + ROBox. self deny: e attributes isEmpty. self assert: (e attributes keys includesAllOf: #(#shapeCache #fooCache)). self assert: e attributes size = 2. ! ! !ROElementTest methodsFor: 'cache' stamp: 'JurajKubelka 10/11/2013 17:28'! testCacheOnElementAndResetcache | e | e := ROElement new. e attributeAt: #anyCache put: 5. e resetCache. self assert: e attributes isEmpty ! ! !ROElementTest methodsFor: 'callback' stamp: 'AlexandreBergel 8/11/2013 21:48'! testCallback | el | el := ROBox green element. el callback: (ROContainerCallbackLayout for: (ROHorizontalLineLayout new)). self assert: el extent = (5 @ 5). el add: ROBox element. self assert: el extent = (15 @ 15). el add: ROBox element. el add: ROBox element. self assert: el extent = (45 @ 15). " ROView new add: el; open " ! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 17:02'! testChangeShape " self debug: #testChangeShape " | element | element := ROEdge new. self deny: (element isShapedAs: ROLine). element + ROLine. element change: ROShape for: ROLine. self assert: (element isShapedAs: ROLine). self assert: (element isShapedAs: ROShape). element change: ROShape for: ROOrthoVerticalLineShape. self assert: (element isShapedAs: ROShape). self assert: (element isShapedAs: ROOrthoVerticalLineShape). ! ! !ROElementTest methodsFor: 'tests'! testContains self assert: (node contains: node position). self deny: (node contains: node position - (1 @ 1)).! ! !ROElementTest methodsFor: 'tests'! testCornerRadius node := ROElement new center: 10@8 radius: 5. self assert: node bounds = (5@3 corner: 15@13)! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 9/25/2012 20:24'! testDecoration | el | el := ROElement bare. self deny: (el isShapedAs: ROShape). self deny: (el isShapedAs: ROLabel). el addShape: ROLabel. self assert: (el isShapedAs: ROShape). self assert: (el isShapedAs: ROLabel).! ! !ROElementTest methodsFor: 'margin' stamp: 'AlexandreBergel 4/24/2013 09:23'! testDefaultMargin self assert: ROElement new padding = (5 @ 5)! ! !ROElementTest methodsFor: 'depth' stamp: 'AlexandreBergel 12/4/2012 08:43'! testDepth self assert: ROElement new depth = 1.! ! !ROElementTest methodsFor: 'depth' stamp: 'AlexandreBergel 12/4/2012 08:44'! testDepthOfElementInView | view el | view := ROView new. view add: (el := ROElement new). self assert: el depth = 1.! ! !ROElementTest methodsFor: 'depth' stamp: 'AlexandreBergel 12/4/2012 08:44'! testDepthOfElementInViewWithNesting | view el1 el2 | view := ROView new. view add: (el1 := ROElement new). el1 add: (el2 := ROElement new). self assert: el1 depth = 1. self assert: el2 depth = 2.! ! !ROElementTest methodsFor: 'depth' stamp: 'AlexandreBergel 12/4/2012 08:45'! testDepthOfView self assert: ROView new depth = 0! ! !ROElementTest methodsFor: 'event' stamp: 'JurajKubelka 10/11/2013 17:07'! testDragAndDropWithInner | view outter inner | view := ROView new. outter := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. self assert: outter bounds = (0@0 corner: 50 @ 50). self assert: inner bounds = ( (0@0) corner: (50@50)). outter add: inner. view add: outter. self assert: outter bounds = (0@0 corner: 60 @ 60). self assert: inner bounds = ( (5@5) corner: (55@55)). inner translateBy: -10 @ -10. self assert: outter bounds = ( (-5@ -5) corner: (60@60)). self assert: inner bounds = (0@0 corner: 50@50). ! ! !ROElementTest methodsFor: 'actions' stamp: 'AlexandreBergel 9/30/2012 18:43'! testEventTranslation | t el | t := 0. el := ROElement new. el on: ROElementTranslated do: [ :event | t := t + 1 ]. self assert: t = 0. el translateTo: 50 @ 50. self assert: t = 1. el translateBy: 50 @ 50. self assert: t = 2.! ! !ROElementTest methodsFor: 'event' stamp: 'AlexandreBergel 10/1/2012 09:10'! testEventTranslation2 | t outter inner1 inner2 | t := 0. outter := ROElement on: 'outter'. inner1 := ROElement on: 'inner1'. inner2 := ROElement on: 'inner1'. inner1 on: ROElementTranslated do: [ :event | t := t + 1 ]. self assert: t = 0. inner1 translateTo: 50 @ 50. self assert: t = 1. inner2 translateBy: 50 @ 50. self assert: t = 1. outter translateBy: 50 @ 50. self assert: t = 1.! ! !ROElementTest methodsFor: 'cache' stamp: 'JurajKubelka 10/11/2013 16:05'! testExtent | el trigger | trigger := OrderedCollection new. el := ROElement new. el + (ROBox green width: [ :e | trigger add: #gw. 10 ]; height: [ :e | trigger add: #gh. 20 ]). el + (ROBox blue width: [ :e | trigger add: #bw. 30 ]; height: [ :e | trigger add: #bh. 40 ]). self assert: el extent = (30 @ 40). self assert: trigger size = 4. self assert: trigger asSet size = 4. trigger := OrderedCollection new. el := ROElement new. el + (ROBox blue width: [ :e | trigger add: #bw. 30 ]; height: [ :e | trigger add: #bh. 40 ]). el + (ROBox green width: [ :e | trigger add: #gw. 10 ]; height: [ :e | trigger add: #gh. 20 ]). self assert: el extent = (30 @ 40). self assert: trigger size = 4. self assert: trigger asSet size = 4. ! ! !ROElementTest methodsFor: 'tests' stamp: 'JurajKubelka 10/11/2013 17:25'! testExtentOnModelChange | sprite | sprite := ROElement sprite. self assert: sprite extent = (50 @ 50). sprite on: 'word'. self assert: sprite extent = (50 @ 50). sprite extent: 30@30. self assert: sprite extent = (30 @ 30). sprite on: 'word'. self assert: sprite extent = (30 @ 30).! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 6/18/2012 13:53'! testForShapeDo | border | border := node getShape: ROBorder. self assert: border color = ROBorder defaultColor. node forShape: ROBorder do: [ :s | s color: Color blue ]. self assert: border color = Color blue! ! !ROElementTest methodsFor: 'interaction'! testForwarding | inner view outter bInner bOutter | outter := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. inner forward. outter add: inner. view := ROView new. view add: outter. bInner := inner bounds. bOutter := outter bounds. inner announce: (ROMouseDragging step: 10@10). self assert: inner bounds = bInner. self assert: outter bounds = (bOutter translateBy: (10@10)).! ! !ROElementTest methodsFor: 'interaction' stamp: 'AlexandreBergel 9/30/2012 18:48'! testForwardingEvent | inner view outter bInner bOutter t | t := 0. outter := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. inner forward. outter add: inner. view := ROView new. view add: outter. bInner := inner bounds. bOutter := outter bounds. outter on: ROMouseDragging do: [ :evt | t := t + 1 ]. self assert: t = 0. inner announce: (ROMouseDragging step: 10@10). self assert: t = 1. ! ! !ROElementTest methodsFor: 'interaction'! testForwardingEventWithView | inner view outter bInner bOutter t | t := 0. view := ROView new. view on: ROEvent do: [ :evt | t := t + 1 ]. outter := ROElement spriteOn: 'outter'. inner := ROElement spriteOn: 'inner'. outter add: inner. view add: outter. inner forward. outter forward. self assert: outter parent == view. self assert: inner parent == outter. self assert: t = 0. inner announce: (ROMouseDragging step: 10@10). self assert: t = 1. ! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 5/7/2012 11:48'! testGetShape | el deco | el := ROElement new. deco := ROBox new. deco color: Color red. el addShape: deco. self assert: (el getShape: ROBox) == deco.! ! !ROElementTest methodsFor: 'group of nodes' stamp: 'DR 1/21/2013 21:05'! testGroupOfNodes | nodes | nodes := ROElement forCollection: (1 to: 20). self assert: (nodes size = 20). self assert: (nodes collect: #model) = (1 to: 20) asArray! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 9/14/2013 12:52'! testHeightAndWidth draggableNode width: 100. self assert: ((draggableNode getShape: ROBorder) width = 5). self assert: (draggableNode width = 100). draggableNode height: 59. self assert: ((draggableNode getShape: ROBorder) height = 5). self assert: (draggableNode height = 59).! ! !ROElementTest methodsFor: 'shapes' stamp: 'JurajKubelka 10/11/2013 16:28'! testInitialSize self assert: ROElement new extent = (5 @ 5)! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 12:23'! testInitialization | aNode | aNode := ROElement new. self assert: aNode bounds = ROElement defaultBounds. self assert: aNode extent = aNode bounds extent. self assert: aNode numberOfShapes = 1! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/11/2012 18:10'! testInitialization2 self assert: ROElement new view camera notNil.! ! !ROElementTest methodsFor: 'initialize-release' stamp: 'AlexandreBergel 9/25/2012 20:25'! testInitializationBare | aNode | aNode := ROElement bare. self assert: aNode bounds = ROElement defaultBounds. self assert: aNode extent = aNode bounds extent. "Just the null shape" self assert: aNode numberOfShapes = 1! ! !ROElementTest methodsFor: 'interaction'! testInteraction | int int2 | self deny: (node is: ROMenuActivable). node @ (int := ROMenuActivable new item: 'act' action: #inspect). self assert: (node is: ROMenuActivable). self assert: int == (node getInteraction: ROMenuActivable). self assert: int numberOfEntries = 1. "We add a new action. We should fill the first interaction only" node @ (int2 := ROMenuActivable new item: 'act2' action: #inspect). self assert: int numberOfEntries = 2. self assert: int == (node getInteraction: ROMenuActivable).! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/27/2012 21:00'! testIsNotEdge self assert: node isNotEdge. self deny: node isEdge. self assert: node isElement! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/20/2013 15:28'! testIsVisibleIn | el | el := (ROBox new size: 40) element. self assert: (el isVisibleIn: (0 @ 0 corner: 50 @ 50)). self assert: (el isVisibleIn: (0 @ 0 corner: 10 @ 10)). self deny: (el isVisibleIn: (41 @ 41 corner: 50 @ 50)). el translateTo: 20 @ 30. self assert: (el isVisibleIn: (50 @ 60 corner: 100 @ 100)). self deny: (el isVisibleIn: (61 @ 71 corner: 100 @ 100)). ! ! !ROElementTest methodsFor: 'iteration'! testIteratingOnEmptyCollections self shouldnt: [ ROElement new interactionsDo: [ :el | ] ] raise: Error! ! !ROElementTest methodsFor: 'margin' stamp: 'AlexandreBergel 4/24/2013 09:21'! testMargin | el1 el2 | el1 := ROBox blue element. el2 := ROBox red element. el2 extent: 20 @ 20. self assert: el1 extent = (5 @ 5). el1 resizeStrategy: (ROShrinkingParent new paddingGap: 0). el1 add: el2. self assert: el1 extent = (20 @ 20). ! ! !ROElementTest methodsFor: 'margin' stamp: 'AlexandreBergel 4/24/2013 09:23'! testMargin2 | el1 el2 | el1 := ROBox blue element. el2 := ROBox red element. el2 extent: 20 @ 20. self assert: el1 extent = (5 @ 5). el1 resizeStrategy: (ROShrinkingParent new paddingGap: 10). el1 add: el2. self assert: el1 extent = (30 @ 30). ! ! !ROElementTest methodsFor: 'tests'! testModel | aNode object | aNode := ROElement new. self assert: aNode model isNil. aNode := ROElement on: (object := Object new). self assert: (aNode model == object)! ! !ROElementTest methodsFor: 'nesting' stamp: 'AlexandreBergel 9/29/2012 16:12'! testMostSpecificParentCommonWith | view el1 el11 el111 el12 el2 el21 | view := ROView new. el1 := ROElement sprite @ ROPopup . el11 := ROElement sprite @ ROPopup . el111 := ROElement sprite @ ROPopup . el12 := ROElement sprite @ ROPopup . el2 := ROElement sprite @ ROPopup . el21 := ROElement sprite @ ROPopup . el1 add: el11; add: el12. el11 add: el111. el2 add: el21. view add: el1; add: el2. self assert: (el1 mostSpecificParentCommonWith: el2) == view. self assert: (el1 mostSpecificParentCommonWith: el21) == view. self assert: (el1 mostSpecificParentCommonWith: el11) == view. self assert: (el12 mostSpecificParentCommonWith: el111) == el1. self assert: (el11 mostSpecificParentCommonWith: el111) == el1.! ! !ROElementTest methodsFor: 'event' stamp: 'VanessaPena 12/2/2012 19:20'! testOnDoOnce | element t | element := ROElement new. t := 0. self assert: element numberOfInteractions = 0. element on: ROMouseClick doOnce: [ :ann | t := t + 1 ]. "self assert: element numberOfInteractions = 1." self assert: t = 0. element announce: ROMouseClick. self assert: t = 1. "self assert: element numberOfInteractions = 0." element announce: ROMouseClick. self assert: t = 1.! ! !ROElementTest methodsFor: 'event' stamp: 'AlexandreBergel 11/25/2012 10:57'! testOnDoOnce2 | element t | element := ROElement new. t := 0. self assert: element numberOfInteractions = 0. element on: ROMouseLeave doOnce: [ :ann | t := t + 1 ]. "self assert: element numberOfInteractions = 1." self assert: t = 0. element announce: ROMouseLeave. self assert: t = 1. "self assert: element numberOfInteractions = 0." element announce: ROMouseLeave. self assert: t = 1. element announce: ROMouseClick. self assert: t = 1.! ! !ROElementTest methodsFor: 'zIndex' stamp: 'AlexandreBergel 7/19/2013 19:53'! testOrderingInTheView | el1 el2 view | el1 := ROBox green element. el2 := ROBox gray element. el1 zIndex: 4. el2 zIndex: 1. view := ROView new. view add: el1; add: el2. self assert: view elements asArray = (Array with: el1 with: el2)! ! !ROElementTest methodsFor: 'interaction' stamp: 'AlexandreBergel 8/2/2012 18:10'! testOverridingIteraction "Ugly test, but we need to get the hand on it. A bug is hidding at the moment we are writting this test" "This test makes some strong assumption on the implementation of Announcement" | eventHandler | eventHandler := node instVarNamed: 'eventHandler'. self assert: eventHandler numberOfSubscriptions = 0. "Two subscription, one for entering and another for leaving" node @ ROPopup. self assert: eventHandler numberOfSubscriptions = 3. node changeInteraction: ROAbstractPopup for: (ROPopupView new view: ROView new). self assert: eventHandler numberOfSubscriptions = 3. ! ! !ROElementTest methodsFor: 'parent' stamp: 'AlexandreBergel 9/10/2012 09:14'! testParentAndNesting | inner outter | inner := ROElement new. outter := ROElement new. self assert: inner parent == ROView nullView. self assert: outter parent == ROView nullView. outter add: inner. self assert: inner parent == outter. self assert: outter parent == ROView nullView! ! !ROElementTest methodsFor: 'parent' stamp: 'AlexandreBergel 9/10/2012 09:14'! testParentAndView | element view | element := ROElement new. self assert: element parent == ROView nullView. view := ROView new. view add: element. self assert: element parent == view.! ! !ROElementTest methodsFor: 'parent' stamp: 'AlexandreBergel 4/22/2013 19:30'! testParentBehavior | element outterElement | element := ROElement new. self assert: element resizeStrategy isExtensible. outterElement := ROElement new. outterElement add: element. self assert: element resizeStrategy isExtensible! ! !ROElementTest methodsFor: 'printing' stamp: 'AlexandreBergel 5/10/2012 16:39'! testPrinting self assert: (#('a ROElement' 'a Roassal.ROElement') includes: ROElement new printString). self assert: (#( 'a ROElement<10>' 'a Roassal.ROElement<10>') includes: (ROElement on: 10) printString). ! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/5/2012 08:47'! testReducingSize | el | el := (ROElement new extent: 90@20) + ROBox green. el extent: 10 @ 12. self assert: el extent = (10 @ 12)! ! !ROElementTest methodsFor: 'actions'! testRemoveElements | elements | elements := node elementsSuchThat: [:e | true ]. self assert: elements isEmpty. node addAll: (ROElement forCollection: (1 to: 20)). elements := node elementsSuchThat: [:e | true ]. self assert: elements notEmpty. node removeAllElements. elements := node elementsSuchThat: [:e | true ]. self assert: elements isEmpty.! ! !ROElementTest methodsFor: 'actions' stamp: 'AlexandreBergel 6/16/2012 00:48'! testRemoveElementsAndError self shouldnt: [ node remove ] raise: Error! ! !ROElementTest methodsFor: 'interaction' stamp: 'AlexandreBergel 4/30/2012 19:57'! testRemoveInteraction | el | el := ROElement new. self deny: (el is: RODraggable). el @ RODraggable. self assert: (el is: RODraggable). el removeInteraction: RODraggable. self deny: (el is: RODraggable).! ! !ROElementTest methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 09:43'! testRemoveInteraction2 self shouldnt: [ ROElement new removeInteraction: ROAbstractPopup ] raise: Error ! ! !ROElementTest methodsFor: 'actions' stamp: 'AlexandreBergel 6/5/2012 10:31'! testRemoveOnElement | view | view := ROView new. view add: node. self assert: (view elements includes: node). node remove. self deny: (view elements includes: node).! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 12/11/2012 12:23'! testRemoveShape self assert: (node numberOfShapes = 3). node - ROBox. self assert: (node shapes size = 2). node + ROBox. self assert: (node shapes size = 3). "No error should happen here" self shouldnt: [ node - ROLine ] raise: Error. node - ROBorder. node - ROBox. self assert: (node shapes size = 1). ! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 7/23/2012 15:23'! testRemoveShapeOnEdges | edge | edge := ROEdge new. self assert: (edge shapes size = 1). edge - ROLine. self assert: (edge shapes size = 1). edge + ROLine. self assert: (edge shapes size = 2). "No error should happen here" self shouldnt: [ edge - ROBox] raise: Error. ! ! !ROElementTest methodsFor: 'shapes' stamp: 'DR 1/15/2013 20:47'! testRemoveSubscription "Ugly test, but we need to get the hand on it. A bug is hidding at the moment we are writting this test" "This test makes some strong assumption on the implementation of Announcement" | eventHandler aPopup | eventHandler := node instVarNamed: 'eventHandler'. self assert: eventHandler numberOfSubscriptions = 0. aPopup := ROPopup new. node @ aPopup. self assert: eventHandler numberOfSubscriptions = 3. eventHandler unsubscribe: aPopup. self assert: eventHandler numberOfSubscriptions = 0.! ! !ROElementTest methodsFor: 'removing' stamp: 'AlexandreBergel 10/18/2012 16:52'! testRemoving | view | view := ROView new. view add: node. node remove. self assert: view numberOfElements = 0.! ! !ROElementTest methodsFor: 'removing' stamp: 'AlexandreBergel 10/18/2012 18:14'! testRemovingNestedNode | innerNode | innerNode := ROElement new. node add: innerNode. self assert: node numberOfElements = 1. innerNode remove. self assert: node numberOfElements = 0.! ! !ROElementTest methodsFor: 'tests'! testRendering | nullCanvas | nullCanvas := ROCountingNullCanvas new. self assert: nullCanvas numberOfRectangles isZero. node drawOn: nullCanvas. self assert: nullCanvas numberOfRectangles = 1. self assert: nullCanvas numberOfLines = 4.! ! !ROElementTest methodsFor: 'group of nodes' stamp: 'AlexandreBergel 8/12/2013 18:45'! testReplacingElement | el1 el2 el3 el20 | el1 := ROElement on: 1. el2 := ROElement on: 2. el3 := ROElement on: 3. el20 := ROElement on: 20. el1 add: el2; add: el3. el1 replace: el2 by: el20. self assert: el1 elements = (Array with: el20 with: el3)! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/17/2012 08:54'! testResizing | t | t := 0. node on: ROElementResized do: [ :event | t := t + 1 ]. node extent: 20 @ 10. self assert: t = 1.! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/17/2012 08:54'! testResizing2 | t | t := 0. node on: ROElementResized do: [ :event | t := t + 1 ]. node extent: node extent. self assert: t = 0.! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/17/2012 08:55'! testResizing3 | t | t := 0. node on: ROElementResized do: [ :event | t := t + 1 ]. node width: 60. self assert: t = 1.! ! !ROElementTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/17/2012 08:55'! testResizing4 | t | t := 0. node on: ROElementResized do: [ :event | t := t + 1 ]. node height: 60. self assert: t = 1.! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/14/2013 15:16'! testSize | el | el := (ROElement new extent: 90@20) + ROBox green. self assert: el extent = (90@20)! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/13/2012 12:26'! testSize2 | el | el := (ROElement new) + ROBox green. el extent: 90@20. self assert: el extent = ( 90 @ 20 )! ! !ROElementTest methodsFor: 'tests' stamp: 'VanessaPena 3/12/2013 15:30'! testSize3 | el | el := ROElement new + ROEllipse. el extent: 30 @ 30. self assert: el extent = ( 30 @ 30 )! ! !ROElementTest methodsFor: 'tests' stamp: 'JurajKubelka 10/11/2013 17:06'! testSprite | sprite | sprite := ROElement sprite. self assert: sprite extent = (50 @ 50).! ! !ROElementTest methodsFor: 'actions' stamp: 'AlexandreBergel 7/23/2012 11:56'! testTranslatingByAFloatPoint | el | el := ROElement new. self assert: el position = (0 @ 0). el translateBy: 0.4 @ 0.3. self assert: el position = (0.4 @ 0.3). ! ! !ROElementTest methodsFor: 'tests'! testTranslatingByFloats self assert: draggableNode position = (0@0). draggableNode translateBy: 4.5 @ 1.3. self assert: draggableNode position = (4.5 @ 1.3). node translateTo: 2.4 @ 6.4. self assert: node position = ( 2.4@6.4). node translateBy: 2.4 @ 6.4. self assert: node position = ( 4.8@12.8)! ! !ROElementTest methodsFor: 'tests'! testTranslatingByRealPoint | view p1 | view := ROView new. view add: draggableNode. "dragging a node increases its position by the dragging step" p1 := draggableNode position. self assert: (p1 = (0@0)). draggableNode translateByRealPoint: 10 @ 6. self assert: (draggableNode position = ( 10 @ 6)). draggableNode translateByRealPoint: -10 @ -6. self assert: (draggableNode position = ( 0 @ 0)). "take care of real vs virtual steps" view camera bounds: (0@0 corner: 250@250). draggableNode translateByRealPoint: 10 @ 6. self assert: (draggableNode position = ( 5@3)).! ! !ROElementTest methodsFor: 'actions' stamp: 'AlexandreBergel 9/16/2012 22:19'! testTranslation | elOutter elInner view | elOutter := ROElement new + ROBorder. elOutter @ RODraggable. elInner := ROElement new + ROBorder. elInner @ RODraggable. elOutter add: elInner . "elInner is now centered" ROHorizontalLineLayout on: (Array with: elInner). "view := ROView new. view add: elOutter. view open." self assert: elInner position = (5 @ 5). elInner translateBy: -5 @ -5. self assert: elInner position = (0 @ 0).! ! !ROElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/10/2012 09:14'! testView self assert: node view == ROView nullView. ROView new add: node. self assert: node view notNil. ! ! !ROElementTest methodsFor: 'event' stamp: 'TudorGirba 9/9/2012 21:42'! testWithAllElementsDo | node1 node2 node21 edge root traversed | root := ROElement new. node1 := ROElement new. node2 := ROElement new. edge := ROEdge from: node1 to: node2. node21 := ROElement new. root add: node1. root add: node2. root add: edge. node2 add: node21. traversed := OrderedCollection new. root withAllElementsDo: [:each | traversed add: each]. self assert: traversed size = 5. self assert: traversed first = root. self assert: (traversed at: 2) = node1. self assert: (traversed at: 3) = node2. self assert: (traversed at: 4) = node21. self assert: traversed last = edge! ! !ROElementTest methodsFor: 'zIndex' stamp: 'AlexandreBergel 7/19/2013 19:31'! testZIndex | el1 el2 view | el1 := ROBox green element size: 40. el2 := ROBox blue element size: 40. el1 zIndex: 2. el2 zIndex: 3. self assert: el1 zIndex = 2. self assert: el2 zIndex = 3. view := ROView new. view add: el1; add: el2. self assert: el1 zIndex = 2. self assert: el2 zIndex = 3. ! ! !ROElementTest methodsFor: 'zIndex' stamp: 'AlexandreBergel 7/19/2013 19:32'! testZIndexElementCreation self assert: ROBox green element zIndex = 0.! ! !ROElementTest methodsFor: 'zIndex' stamp: 'AlexandreBergel 7/19/2013 19:34'! testZIndexElementCreationAndZOrdering | el zOrdering | el := ROBox green element. el zIndex: 5. zOrdering := ROZOrdering new. self assert: (zOrdering zIndexOf: el) = 5.! ! !ROEventTest methodsFor: 'layout' stamp: 'AlexandreBergel 11/16/2012 09:10'! assertLayout: layout | element1 element2 view events | element1 := ROElement sprite. element2 := ROElement sprite. view := ROView new. view add: element1; add: element2. self assert: view elements size = 2. events := OrderedCollection new. layout on: ROLayoutBegin do: [ :event | events add: event ]. layout on: ROLayoutEnd do: [ :event | events add: event ]. self assert: events isEmpty. "------- We do the layout" layout on: view elements. self assert: events size = 2. self assert: events first class == ROLayoutBegin. self assert: events second class == ROLayoutEnd.! ! !ROEventTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 20:47'! testEmitToParent | t spr sprInner | t := 0. spr := ROElement new. spr on: ROMouseEnter do: [ :evt | t := t + 10 ]. sprInner := ROElement new. sprInner on: ROMouseEnter do: [ :evt | t := t + 1. evt emitToParent ]. spr add: sprInner. sprInner announce: ROMouseEnter. self assert: t = 11. ! ! !ROEventTest methodsFor: 'layout' stamp: 'AlexandreBergel 12/1/2012 17:35'! testLayoutEvent | classesToExclude | classesToExclude := OrderedCollection new. classesToExclude add: ROTreeMapLayout. (ROLayout withAllSubclasses reject: [ :cls | classesToExclude includes: cls ] ) do: [ :cls | cls isNotAbstract ifTrue: [ self assertLayout: cls new ] ] ! ! !ROEventTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 20:42'! testNoSentToParent | t spr sprInner | t := 0. spr := ROElement new. spr on: ROMouseEnter do: [ :evt | t := t + 10 ]. sprInner := ROElement new. sprInner on: ROMouseEnter do: [ :evt | t := t + 1. ]. spr add: sprInner. sprInner announce: ROMouseEnter. self assert: t = 1. ! ! !ROEventTest methodsFor: 'tests' stamp: 'AlexandreBergel 1/18/2013 10:46'! testPositionNotNil | event | ROComponentEvent withAllSubclasses do: [ :cls | event := cls new. self assert: event position = (0@0) ]! ! !ROEventTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/15/2013 16:43'! testProperlyInitialized | event | ROEvent withAllSubclasses do: [ :cls | event := cls new. self shouldnt: [ (event class selectors select: [ :k | k ~= #= and: [(k includes: ':' first) not ] ]) do: [ :k | event perform: k ] ] raise: Error ]! ! !ROExpandChildrenOnClickTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 12:26'! testChildrenForModel | expandChildren children elements | expandChildren := ROExpandChildrenOnClick childrenForModel: [ :v | Array with: v with: v + 1 with: v + 2 ]. elements := expandChildren computeChildrenFor: (ROElement on: 10). self assert: elements size = 3. self assert: elements first numberOfShapes = 3. self assert: (elements first shapes collect: #class) asArray = ((Array with: ROBox with: ROLabel with: RONullShape))! ! !ROExpandChildrenOnClickTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/21/2012 15:35'! testClickOnAddedNode | view el elements | view := ROView new. el := (ROElement on: 'hello') + ROLabel. el @ (ROExpandChildrenOnClick childrenBlock: [ :element | Array with: ((ROElement on: (element model, ' world')) + ROBox) ]). view add: el. el announce: ROMouseClick. elements := view elementsSuchThat: [ :e | e model = 'hello world' ]. self assert: elements notEmpty. elements first announce: ROMouseClick. self assert: view numberOfElements = 3.! ! !ROExpandChildrenOnClickTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/21/2012 15:35'! testClickOnRecursiveAddedNode | view el elements | view := ROView new. el := (ROElement on: 'hello') + ROLabel. el @ (RORecursiveExpandOnClick childrenBlock: [ :element | Array with: ((ROElement on: (element model, ' world')) + ROBox) ]). view add: el. el announce: ROMouseClick. elements := view elementsSuchThat: [ :e | e model = 'hello world' ]. self assert: elements notEmpty. elements first announce: ROMouseClick. self assert: view numberOfElements = 5.! ! !ROExpandChildrenOnClickTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/21/2012 15:34'! testClickOnRoot | view el | view := ROView new. el := (ROElement on: 'world') + ROLabel. el @ (ROExpandChildrenOnClick childrenBlock: [ :element | Array with: (ROElement on: (element model, ' World')) ]). view add: el. self assert: view numberOfElements = 1. el announce: ROMouseClick. self assert: view numberOfElements = 3. el announce: ROMouseClick. self assert: view numberOfElements = 5.! ! !ROFixedSizedParentTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/24/2013 09:24'! testMoveInner | outter inner rawView | rawView := ROView new. outter := ROBox element extent: 100 @ 80. inner := (ROEllipse color: Color gray) element size: 20. outter resizeStrategy: (ROFixedSizedParent new paddingGap: 0). outter add: inner. self assert: (inner position = (0 @ 0)). rawView add: outter. "rawView add: inner." outter translateTo: 80 @ 20. ROConstraint constraintInItsParent: inner. self assert: (inner position = (0 @ 0)). inner translateTo: (-20 @ -5). self assert: (outter extent = (100 @ 80)). self assert: (inner position = (0 @ 0)).! ! !ROFocusViewTest methodsFor: 'running' stamp: 'AlexandreBergel 11/19/2012 15:05'! setUp view := ROView new. camera := view camera. view add: (el1 := ROElement sprite). view add: (el2 := ROElement sprite translateBy: 200 @ 20). view @ RODraggable ! ! !ROFocusViewTest methodsFor: 'corner' stamp: 'AlexandreBergel 5/22/2013 18:17'! testBottomLeft self assert: view camera position = (0 @ 0). view windowSize: 500 @ 500. ROFocusView bottomLeftOn: el2. view completeAllAnimations. self assert: view camera position = (200@ -430)! ! !ROFocusViewTest methodsFor: 'corner' stamp: 'AlexandreBergel 5/22/2013 18:17'! testBottomRight self assert: view camera position = (0 @ 0). view windowSize: 500 @ 500. ROFocusView bottomRightOn: el2. view completeAllAnimations. self assert: view camera position = (-250@ -430)! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/6/2012 10:13'! testCamera self assert: camera position = (0 @ 0).! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/22/2013 18:18'! testOnView " self debug: #testOnView " view windowSize: 500 @ 500. ROFocusView on: el2. view completeAllAnimations. "el2 is now in the center of the screen" self assert: camera centerPosition = (el2 position).! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/22/2013 18:18'! testOnViewWithInitialTranslation " self debug: #testOnView " | focus | view windowSize: 500 @ 500. camera translateTo: 10@30. focus := ROFocusView new. focus on: el2. view completeAllAnimations. "el2 is now in the center of the screen" self assert: camera centerPosition = (el2 position).! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/22/2013 18:18'! testOnViewWithoutProcess " self debug: #testOnView " | focus | view windowSize: 500 @ 500. focus := ROFocusView new. focus on: el2. view completeAllAnimations. "el2 is now in the center of the screen" self assert: camera centerPosition = (el2 position).! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/22/2013 18:18'! testPosition view windowSize: 500 @ 500. el1 translateTo: (1650.5@134.0). camera translateTo: (-14656.5@ -72.0). self assert: (camera position = (-14656.5@ -72.0)). self assert: camera == el1 view camera. ROFocusView new on: el1. view completeAllAnimations. self assert: (camera centerPosition - (1651@134)) abs <= (2 @ 2)! ! !ROFocusViewTest methodsFor: 'test' stamp: 'AlexandreBergel 5/22/2013 18:18'! testToPositionView " self debug: #testToPositionView " view windowSize: 500 @ 500. self assert: camera position = (0@ 0). ROFocusView new view: view toPosition: 500@20. view completeAllAnimations. "el2 is now in the center of the screen" self assert: camera position = (250@ -230). ROFocusView new view: view toPosition: 500@250. view completeAllAnimations. "el2 is now in the center of the screen" self assert: camera position = (250@ 0).! ! !ROFocusViewTest methodsFor: 'corner' stamp: 'AlexandreBergel 5/22/2013 18:19'! testTwice view windowSize: 500 @ 500. ROFocusView bottomLeftOn: el2. view completeAllAnimations. self assert: view camera position = (200@ -430). ROFocusView bottomLeftOn: el2. view completeAllAnimations. self assert: view camera position = (200@ -430) ! ! !ROGraphTransformationTest methodsFor: 'obsolete' stamp: 'AlexandreBergel 6/5/2012 11:11'! OLDtestCheckCycleNoCycle | view nodes edges newNode transformation node1 node2 node3 | view := ROMondrianViewBuilder new. nodes := view nodes: (Array with: 1 with: 2 with: 3). edges := view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3 with: 1 -> 3). transformation := ROGraphTransformation new. "self assert: (transformation containsCycleIn: nodes with: edges)" "self deny: (transformation containsCycleIn: nodes first with: edges passedNodes: OrderedCollection new)" self deny: (transformation hasCycleIn: nodes with: edges)! ! !ROGraphTransformationTest methodsFor: 'transforming graph' stamp: 'AlexandreBergel 6/5/2012 10:10'! testFromEdgesToNesting | view nodes edges newNode transformation | view := ROMondrianViewBuilder new. nodes := view nodes: (Array with: 1 with: 2). edges := view edgesFromAssociations: (Array with: 1 -> 2). transformation := ROGraphTransformation new. "Testing utility methods" self assert: (transformation getConnectedNodesFrom: nodes first using: edges) = (Array with: nodes second). "Doing the transformation" newNode := transformation fromEdgesToNesting: nodes edges: edges root: nodes first. self assert: newNode elements size = 1. self assert: newNode model = 1. self assert: newNode elements first model = 2. self assert: newNode == nodes first! ! !ROGraphTransformationTest methodsFor: 'transforming graph' stamp: 'AlexandreBergel 6/9/2012 15:20'! testFromEdgesToNesting2 | view nodes edges newNode transformation | view := ROMondrianViewBuilder new. nodes := view nodes: (Array with: 1 with: 2 with: 3). edges := view edgesFromAssociations: (Array with: 1 -> 2 with: 1 -> 3). transformation := ROGraphTransformation new. "Testing utility methods" self assert: (transformation getConnectedNodesFrom: nodes first using: edges) = (Array with: nodes second with: nodes third). "Doing the transformation" newNode := transformation fromEdgesToNesting: nodes edges: edges root: nodes first. self assert: newNode elements size = 2. self assert: newNode model = 1. self assert: newNode elements first model = 2. self assert: newNode elements second model = 3. "We make sure that the nodes that have been moved are removed from the view" self assert: (view raw elements includes: newNode). self deny: (view raw elements includes: nodes second). self deny: (view raw elements includes: nodes third).! ! !ROGraphTransformationTest methodsFor: 'transforming graph' stamp: 'AlexandreBergel 12/11/2012 15:05'! testFromEdgesToNesting3 | view nodes edges newNode transformation | view := ROMondrianViewBuilder new. nodes := view nodes: (Array with: 1 with: 2 with: 3). edges := view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3). transformation := ROGraphTransformation new. "Testing utility methods" self assert: (transformation getConnectedNodesFrom: nodes first using: edges) = (Array with: nodes second). "Doing the transformation" newNode := transformation fromEdgesToNesting: nodes edges: edges root: nodes first. self assert: newNode elements size = 1. self assert: newNode model = 1. self assert: newNode elements first model = 2. self assert: newNode elements first numberOfElements = 1. self assert: newNode elements first elements first model = 3. ! ! !ROGraphTransformationTest methodsFor: 'removing' stamp: 'AlexandreBergel 5/27/2013 08:58'! testRemovingIntermediateNodesAndEdges | view nodes | view := ROMondrianViewBuilder new. nodes := view nodes: #('a' 'b' 'c'). view edgesFromAssociations: (Array with: 'a' -> 'b' with: 'b' -> 'c'). self assert: (ROGraphTransformation new hasIncomingEdges: nodes second). self assert: (ROGraphTransformation new hasIncomingEdges: nodes third). self deny: (ROGraphTransformation new hasIncomingEdges: nodes first). ROGraphTransformation new removeIntermediaryNodes: nodes. self assert: view raw elements size = 3. self assert: (view raw elementsSuchThat: #isElement) size = 2. self assert: (view raw elementsSuchThat: #isEdge) size = 1.! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/14/2013 19:18'! testColor "el1 and el2 are the same, except el2 is lightly highlightable" | el1 el2 view | el1 := (ROElement on: 1) height: 50; width: 50. el1 + (ROEllipse color: Color green). el2 := (ROElement on: 1) height: 50; width: 50. el2 + (ROEllipse color: Color green) @ ROLightlyHighlightable. view := ROView new @ RODraggable. view add: el1. view add: el2. ROHorizontalLineLayout on: view elements. "view open." self assert: (el1 getShape: ROShape) color = Color green. self assert: (el2 getShape: ROShape) color = Color green. el2 announce: ROMouseEnter. self assert: (el2 getShape: ROShape) color = ROLightlyHighlightable new defaultHighlightColor. self assert: el2 hasAttributes. self assert: (el2 attributes at: #oldColor) = Color green. el2 announce: ROMouseLeave. self assert: (el2 getShape: ROShape) color = Color green. ! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:03'! testHighlightAndUnlight | element shape | element := ROElement new + ROBorder yellow. shape := (element getShape: ROShape). self assert: shape color = Color yellow. self deny: (ROBlink isHighlighted: element). ROBlink highlight: element. self assert: shape color = Color red. self assert: (ROBlink isHighlighted: element). ROBlink unhighlight: element. self assert: shape color = Color yellow. self deny: (ROBlink isHighlighted: element). ! ! !ROHighlightElementTest methodsFor: 'highlight edges' stamp: 'AlexandreBergel 10/2/2012 19:53'! testHighlightEdge | rawView node1 node2 edge lineShape | rawView := ROView new. node1 := ROBox elementOn: 'node1'. node2 := ROBox elementOn: 'node2'. edge := ROEdge from: node1 to: node2. edge + (ROLine red). edge @ ROLightlyHighlightable. rawView add: edge; add: node1; add: node2. node2 translateBy: 100 @ 0. lineShape := edge getShape: ROLine. self assert: (lineShape colorFor: edge) = Color red. self shouldnt: [ edge announce: ROMouseEnter ] raise: Error. self assert: (lineShape colorFor: edge) = ROLightlyHighlightable highlightedColor. self shouldnt: [ edge announce: ROMouseLeave ] raise: Error. self assert: (lineShape colorFor: edge) = Color red.! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 12:49'! testHighlightingShape | shape1 shape2 el | shape1 := ROBox white. shape2 := ROBorder new. el := ROElement new. el + shape1 + shape2. el @ ROLightlyHighlightable. el announce: ROMouseEnter. self assert: el shapes asArray = (Array with: shape2 with: shape1 with: (el getShape: RONullShape)). self assert: (shape1 colorFor: el) = Color white. self assert: (shape2 colorFor: el) = ROLightlyHighlightable highlightedColor.! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:05'! testLeavingWithoutEntering | el shape | el := ROElement new + (shape := ROBox new). self assert: (shape colorFor: el) = ROBox defaultColor. self deny: (ROBlink isHighlighted: el). ROBlink unhighlight: el. self assert: (shape colorFor: el) = ROBox defaultColor. self deny: (ROBlink isHighlighted: el).! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:21'! testMultipleHighlight | el shape | el := ROElement new + (shape := ROBox new). self assert: (shape colorFor: el) = ROBox defaultColor. self deny: (ROBlink isHighlighted: el). ROBlink highlight: el. self assert: (shape colorFor: el) = Color red. self assert: (ROBlink isHighlighted: el). ROBlink highlight: el. self assert: (shape colorFor: el) = Color red. self assert: (ROBlink isHighlighted: el). ROBlink unhighlight: el. self assert: (shape colorFor: el) = ROBox defaultColor. self deny: (ROBlink isHighlighted: el).! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:06'! testOnBox | el | el := ROElement on: 'hello'. el + ROBox. self assert: (el getShape: ROBox) color = ROBox defaultColor. ROBlink highlight: el. self assert: (el getShape: ROBox) color = Color red. ROBlink unhighlight: el. self assert: (el getShape: ROBox) color = ROEllipse defaultColor.! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 18:06'! testOnCircle | el | el := ROElement on: 'hello'. el + ROEllipse. self assert: (el getShape: ROEllipse) color = ROEllipse defaultColor. ROBlink highlight: el. self assert: (el getShape: ROEllipse) color = Color red. ROBlink unhighlight: el. self assert: (el getShape: ROEllipse) color = ROEllipse defaultColor.! ! !ROHighlightElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/24/2012 12:08'! testUnhighlightingShape | shape el | shape := ROBox white. el := ROElement new. el + shape. el @ ROLightlyHighlightable. el announce: ROMouseLeave. self assert: (shape colorFor: el) = Color white. ! ! !ROImageSpecificTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/22/2013 01:16'! testBasic | el form | form := ROEaselMorphic new objectprofileIcon. el := (ROImage new form: form) element. self assert: el width = form width. self assert: el height = form height.! ! !ROImageTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/23/2013 19:39'! testBasic | view el elInner canvas | view := ROView new. el := ROElement new. elInner := ROElement new + (ROImage new form: ((4 @ 6) extent: (10 @ 30))). el add: elInner. view add: el. el translateTo: 50 @ 40. elInner translateBy: 5 @ 4. canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#paintImage '(60@49)'))! ! !ROLayoutSteppingTest methodsFor: 'converting' stamp: 'AlexandreBergel 11/15/2012 17:30'! assertLayout: layout | events | events := OrderedCollection new. layout on: ROLayoutStep do: [ :evt | events add: evt ]. self assert: events size = 0. layout on: elements. self assert: events size = (elements size // layout iterationsToSendEvent). self assert: events size > 0. self assert: (events allSatisfy: [ :evt | evt maxInterations = elements size ]). self assert: (events collect: #currentIteration) asArray = #(100 200 300)! ! !ROLayoutSteppingTest methodsFor: 'running' stamp: 'AlexandreBergel 11/15/2012 17:10'! setUp elements := ROElement forCollection: (1 to: ROLayout new iterationsToSendEvent * 3). view := ROView new. view addAll: elements. ! ! !ROLayoutSteppingTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/16/2013 08:43'! testLayout | classesToExclude | classesToExclude := OrderedCollection new. classesToExclude add: ROTreeMapLayout; add: RONullLayout; add: RONarrowRadialTreeLayout; add: ROForceBasedLayout; add: ROSugiyamaLayout; add: ROVerticalLaggeredTree; add: RORectanglePackingLayout. (Smalltalk includesKey: #ROGraphVizLayout) ifTrue: [ classesToExclude add: (Smalltalk at: #ROGraphVizLayout) ]. (ROLayout withAllSubclasses copyWithoutAll: classesToExclude) do: [ :cls | cls isNotAbstract ifTrue: [ self assertLayout: cls new ] ] ! ! !ROAbstractLayout methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 11/15/2012 13:29'! testAbstract ROLayout withAllSubclasses do: [ :cls | cls subclasses notEmpty ifTrue: [ self assert: cls isAbstract ] ]! ! !ROAbstractLayout methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 11/15/2012 13:28'! testNotAbstract ROLayout withAllSubclasses do: [ :cls | cls subclasses isNil ifTrue: [ self deny: cls isAbstract ] ]! ! !ROCellLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/19/2013 11:51'! testLayout | result | ROCellLayout on: elements. result := ((Array new: 20) at: 1 put: ((5@5)); at: 2 put: ((65@5)); at: 3 put: ((125@5)); at: 4 put: ((185@5)); at: 5 put: ((245@5)); at: 6 put: ((5@65)); at: 7 put: ((65@65)); at: 8 put: ((125@65)); at: 9 put: ((185@65)); at: 10 put: ((245@65)); at: 11 put: ((5@125)); at: 12 put: ((65@125)); at: 13 put: ((125@125)); at: 14 put: ((185@125)); at: 15 put: ((245@125)); at: 16 put: ((5@185)); at: 17 put: ((65@185)); at: 18 put: ((125@185)); at: 19 put: ((185@185)); at: 20 put: ((245@185)); yourself). self assert: (elements collect: #position) = result! ! !ROCircleLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 1/23/2013 15:44'! assertArrayOfPoint: computedArray isCloseTo: result "utility method useful to compare two set of points that are close to each other." self assert: computedArray size = result size. self assert: (computedArray allSatisfy: [ :p | p class = Point ]). computedArray with: result do: [ :e1 :e2 | self assert: ((e1 x - e2 x) abs <= 1 and: [ (e1 y - e2 y) abs <= 1 ]) ] ! ! !ROCircleLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 5/9/2012 16:26'! testAssertArrayOfPoint self assertArrayOfPoint: (Array with: 2@3) isCloseTo: (Array with: 2@3). self assertArrayOfPoint: (Array with: 2@3) isCloseTo: (Array with: 1@3). self assertArrayOfPoint: (Array with: 2@3) isCloseTo: (Array with: 1@2). self assertArrayOfPoint: (Array with: 2@3) isCloseTo: (Array with: 3@2).! ! !ROCircleLayoutTest methodsFor: 'test radius' stamp: 'AlexandreBergel 1/23/2013 15:56'! testComputeRadius self assert: (ROCircleLayout new computeRadiusFor: (Array new: 10)) = (10 * ROCircleLayout new scaleFactor).! ! !ROCircleLayoutTest methodsFor: 'test radius' stamp: 'AlexandreBergel 1/23/2013 15:56'! testComputeRadius2 self assert: (ROCircleLayout new initialRadius: 45; computeRadiusFor: (Array new: 10)) = 45! ! !ROCircleLayoutTest methodsFor: 'test initial angle' stamp: 'AlexandreBergel 1/23/2013 15:04'! testInitialAngleInitialization self assert: ROCircleLayout new initialAngle = 0. self assert: ROCircleLayout new initialAngleInDegree = 0.! ! !ROCircleLayoutTest methodsFor: 'test initial angle' stamp: 'AlexandreBergel 1/23/2013 15:07'! testInitialAngleInitialization2 | layout | layout := ROCircleLayout new. layout initialAngle: (Float pi / 2). self assert: (layout initialAngleInDegree - 90) abs <= 0.1! ! !ROCircleLayoutTest methodsFor: 'test initial angle' stamp: 'AlexandreBergel 1/23/2013 15:08'! testInitialAngleInitialization3 | layout | layout := ROCircleLayout new. layout initialAngleInDegree: 90. self assert: (layout initialAngleInDegree - 90) abs <= 0.1. self assert: (layout initialAngle - (Float pi / 2)) abs <= 0.1. ! ! !ROCircleLayoutTest methodsFor: 'test incremental angle' stamp: 'AlexandreBergel 1/23/2013 15:59'! testInitialIncrementalAngle self assert: ((ROCircleLayout new computeIncrementalAngleFor: elements) - (2 * Float pi / elements size)) abs <= 0.2! ! !ROCircleLayoutTest methodsFor: 'test radius' stamp: 'AlexandreBergel 1/23/2013 15:54'! testInitialRadius self assert: (ROCircleLayout new initialRadius = 0)! ! !ROCircleLayoutTest methodsFor: 'test radius' stamp: 'AlexandreBergel 1/23/2013 15:55'! testInitialRadiusSet self assert: (ROCircleLayout new computeRadiusFor: (Array new: 10)) = (10 * ROCircleLayout new scaleFactor).! ! !ROCircleLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 5/9/2012 14:29'! testLayout | result computedArray | ROCircleLayout on: elements. computedArray := elements collect: #positionAsInteger. result := ((Array new: 20) at: 1 put: ((440@220)); at: 2 put: ((429@287)); at: 3 put: ((397@349)); at: 4 put: ((349@397)); at: 5 put: ((287@429)); at: 6 put: ((220@440)); at: 7 put: ((152@429)); at: 8 put: ((90@397)); at: 9 put: ((42@349)); at: 10 put: ((10@287)); at: 11 put: ((0@220)); at: 12 put: ((10@152)); at: 13 put: ((42@90)); at: 14 put: ((90@42)); at: 15 put: ((152@10)); at: 16 put: ((219@0)); at: 17 put: ((287@10)); at: 18 put: ((349@42)); at: 19 put: ((397@90)); at: 20 put: ((429@152)); yourself). self assertArrayOfPoint: computedArray isCloseTo: result. " view openInWindow " ! ! !ROCircleLayoutTest methodsFor: 'test initial angle' stamp: 'AlexandreBergel 1/23/2013 15:46'! testLayoutWithInitialAngle | result computedArray | ROCircleLayout new initialAngle: Float pi; on: elements. computedArray := elements collect: #positionAsInteger. result := ((Array new: 20) at: 1 put: ((0@220)); at: 2 put: ((10@152)); at: 3 put: ((42@90)); at: 4 put: ((90@42)); at: 5 put: ((152@10)); at: 6 put: ((219@0)); at: 7 put: ((287@10)); at: 8 put: ((349@42)); at: 9 put: ((397@90)); at: 10 put: ((429@152)); at: 11 put: ((440@219)); at: 12 put: ((429@287)); at: 13 put: ((397@349)); at: 14 put: ((349@397)); at: 15 put: ((287@429)); at: 16 put: ((220@440)); at: 17 put: ((152@429)); at: 18 put: ((90@397)); at: 19 put: ((42@349)); at: 20 put: ((10@287)); yourself). self assertArrayOfPoint: computedArray isCloseTo: result. ! ! !ROCircleLayoutTest methodsFor: 'test initial angle' stamp: 'AlexandreBergel 1/23/2013 15:47'! testLayoutWithInitialAngleInDegree | result computedArray | ROCircleLayout new initialAngleInDegree: 90; on: elements. computedArray := elements collect: #positionAsInteger. result := ((Array new: 20) at: 1 put: ((220@440)); at: 2 put: ((152@429)); at: 3 put: ((90@397)); at: 4 put: ((42@349)); at: 5 put: ((10@287)); at: 6 put: ((0@220)); at: 7 put: ((10@152)); at: 8 put: ((42@90)); at: 9 put: ((90@42)); at: 10 put: ((152@10)); at: 11 put: ((219@0)); at: 12 put: ((287@10)); at: 13 put: ((349@42)); at: 14 put: ((397@90)); at: 15 put: ((429@152)); at: 16 put: ((440@219)); at: 17 put: ((429@287)); at: 18 put: ((397@349)); at: 19 put: ((349@397)); at: 20 put: ((287@429)); yourself). self assertArrayOfPoint: computedArray isCloseTo: result. " view openInWindow " ! ! !ROFlowLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/20/2012 18:08'! testLayout | result resultVW computed | ROFlowLayout on: elements. result := ((Array new: 20) at: 1 put: ((5@5)); at: 2 put: ((65@5)); at: 3 put: ((5@65)); at: 4 put: ((65@65)); at: 5 put: ((5@125)); at: 6 put: ((65@125)); at: 7 put: ((5@185)); at: 8 put: ((65@185)); at: 9 put: ((5@245)); at: 10 put: ((65@245)); at: 11 put: ((5@305)); at: 12 put: ((65@305)); at: 13 put: ((5@365)); at: 14 put: ((65@365)); at: 15 put: ((5@425)); at: 16 put: ((65@425)); at: 17 put: ((5@485)); at: 18 put: ((65@485)); at: 19 put: ((5@545)); at: 20 put: ((65@545)); yourself). self assert: (elements collect: #position) = result! ! !ROFlowLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/20/2012 18:16'! testLayoutASet | set | set := Set new. set addAll: elements. ROFlowLayout on: set! ! !ROForceBasedLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 5/17/2013 10:36'! testLayout ROForceBasedLayout new on: elements. ! ! !ROGridLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/17/2012 17:06'! testLayout | result | ROGridLayout on: elements. result := ((Array new: 20) at: 1 put: ((5@5)); at: 2 put: ((65@5)); at: 3 put: ((125@5)); at: 4 put: ((185@5)); at: 5 put: ((245@5)); at: 6 put: ((5@65)); at: 7 put: ((65@65)); at: 8 put: ((125@65)); at: 9 put: ((185@65)); at: 10 put: ((245@65)); at: 11 put: ((5@125)); at: 12 put: ((65@125)); at: 13 put: ((125@125)); at: 14 put: ((185@125)); at: 15 put: ((245@125)); at: 16 put: ((5@185)); at: 17 put: ((65@185)); at: 18 put: ((125@185)); at: 19 put: ((185@185)); at: 20 put: ((245@185)); yourself). self assert: (elements collect: #position) = result! ! !ROGridLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 6/30/2012 01:23'! testLayoutLineItemCount | result | ROGridLayout on: elements withLineItemsCount: 5. result := ((Array new: 20) at: 1 put: ((5@5)); at: 2 put: ((65@5)); at: 3 put: ((125@5)); at: 4 put: ((185@5)); at: 5 put: ((245@5)); at: 6 put: ((5@65)); at: 7 put: ((65@65)); at: 8 put: ((125@65)); at: 9 put: ((185@65)); at: 10 put: ((245@65)); at: 11 put: ((5@125)); at: 12 put: ((65@125)); at: 13 put: ((125@125)); at: 14 put: ((185@125)); at: 15 put: ((245@125)); at: 16 put: ((5@185)); at: 17 put: ((65@185)); at: 18 put: ((125@185)); at: 19 put: ((185@185)); at: 20 put: ((245@185)); yourself). self assert: (elements collect: #position) = result! ! !ROGridLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 6/30/2012 01:23'! testLayoutLineItemCount2 | result | ROGridLayout on: elements withLineItemsCount: 3. result := (((Array new: 20) at: 1 put: ((5@5)); at: 2 put: ((65@5)); at: 3 put: ((125@5)); at: 4 put: ((5@65)); at: 5 put: ((65@65)); at: 6 put: ((125@65)); at: 7 put: ((5@125)); at: 8 put: ((65@125)); at: 9 put: ((125@125)); at: 10 put: ((5@185)); at: 11 put: ((65@185)); at: 12 put: ((125@185)); at: 13 put: ((5@245)); at: 14 put: ((65@245)); at: 15 put: ((125@245)); at: 16 put: ((5@305)); at: 17 put: ((65@305)); at: 18 put: ((125@305)); at: 19 put: ((5@365)); at: 20 put: ((65@365)); yourself)). self assert: (elements collect: #position) = result! ! !ROGridLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/23/2013 14:56'! testLayoutOnEmptyList self shouldnt: [ ROGridLayout on: #() ] raise: Error! ! !ROGridLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/24/2013 09:24'! testLayoutWithMargin | element result | element := ROBox blue element. element resizeStrategy: (ROExtensibleParent new paddingGap: 25). element addAll: elements. ROGridLayout on: elements. view := ROView new. view add: element. result := ((Array new: 20) at: 1 put: ((25@25)); at: 2 put: ((85@25)); at: 3 put: ((145@25)); at: 4 put: ((205@25)); at: 5 put: ((265@25)); at: 6 put: ((25@85)); at: 7 put: ((85@85)); at: 8 put: ((145@85)); at: 9 put: ((205@85)); at: 10 put: ((265@85)); at: 11 put: ((25@145)); at: 12 put: ((85@145)); at: 13 put: ((145@145)); at: 14 put: ((205@145)); at: 15 put: ((265@145)); at: 16 put: ((25@205)); at: 17 put: ((85@205)); at: 18 put: ((145@205)); at: 19 put: ((205@205)); at: 20 put: ((265@205)); yourself). self assert: (elements collect: #position) = result! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/22/2013 11:36'! testLayout | previous | ROHorizontalLineLayout on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position x > previous position x ]. previous := el ]! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/23/2013 15:41'! testLayoutOnEmptyCollection self shouldnt: [ ROHorizontalLineLayout on: #() ] raise: Error. self shouldnt: [ ROHorizontalLineLayout on: #() edges: #() ] raise: Error. self shouldnt: [ ROHorizontalLineLayout new on: #() edges: #() ] raise: Error! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/8/2013 12:20'! testLayoutWithAlignment | previous | ROHorizontalLineLayout new alignment: #bottom; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position x > previous position x ]. previous := el ]. ! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/24/2013 09:24'! testLayoutWithMargin | element result | element := ROBox blue element. element resizeStrategy: (ROExtensibleParent new paddingGap: 25). element addAll: elements. ROHorizontalLineLayout on: elements. view := ROView new. view add: element. result := (((Array new: 20) at: 1 put: ((25@25)); at: 2 put: ((85@25)); at: 3 put: ((145@25)); at: 4 put: ((205@25)); at: 5 put: ((265@25)); at: 6 put: ((325@25)); at: 7 put: ((385@25)); at: 8 put: ((445@25)); at: 9 put: ((505@25)); at: 10 put: ((565@25)); at: 11 put: ((625@25)); at: 12 put: ((685@25)); at: 13 put: ((745@25)); at: 14 put: ((805@25)); at: 15 put: ((865@25)); at: 16 put: ((925@25)); at: 17 put: ((985@25)); at: 18 put: ((1045@25)); at: 19 put: ((1105@25)); at: 20 put: ((1165@25)); yourself)). self assert: (elements collect: #position) = result! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/22/2013 13:57'! testStretch | previous | ROHorizontalLineLayout new stretch; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position x > previous position x ]. previous := el ].! ! !ROHorizontalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 5/6/2013 18:04'! testStretchInsideElement | previous random rootElement | elements := ROElement forCollection: (1 to: 10). random := #(23 53 60 50). elements do: [ :n | n extent: (random anyOne) @ (random anyOne); addShape: (ROBox new); addShape: (ROBorder new) ]. rootElement := ROElement on: 11. rootElement size: (11 * 55). rootElement addShape: ROBorder black. rootElement addAll: elements. view := ROView new. view add: rootElement. ROHorizontalLineLayout new stretch; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position x > previous position x. self assert: el height = previous height. ]. previous := el ].! ! !ROHorizontalNarrowTreeLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/2/2013 11:27'! testLayout | result | ROHorizontalNarrowTreeLayout on: elements. result := ((Array new: 20) at: 1 put: ((3.0@480.0)); at: 2 put: ((73.0@3.0)); at: 3 put: ((73.0@56.0)); at: 4 put: ((73.0@109.0)); at: 5 put: ((73.0@162.0)); at: 6 put: ((73.0@215.0)); at: 7 put: ((73.0@268.0)); at: 8 put: ((73.0@321.0)); at: 9 put: ((73.0@374.0)); at: 10 put: ((73.0@427.0)); at: 11 put: ((73.0@480.0)); at: 12 put: ((73.0@533.0)); at: 13 put: ((73.0@586.0)); at: 14 put: ((73.0@639.0)); at: 15 put: ((73.0@692.0)); at: 16 put: ((73.0@745.0)); at: 17 put: ((73.0@798.0)); at: 18 put: ((73.0@851.0)); at: 19 put: ((73.0@904.0)); at: 20 put: ((73.0@957.0)); yourself). self assert: (elements collect: #position) = result.! ! !ROHorizontalTreeLayoutTest methodsFor: 'test layout' stamp: 'DR 1/15/2013 21:20'! testLayout | result edges firstEdge shape | ROHorizontalTreeLayout on: elements. result := (((Array new: 20) at: 1 put: ((5@482.0)); at: 2 put: ((75@747.0)); at: 3 put: ((75@800.0)); at: 4 put: ((75@429.0)); at: 5 put: ((75@482.0)); at: 6 put: ((75@111.0)); at: 7 put: ((75@164.0)); at: 8 put: ((75@853.0)); at: 9 put: ((75@906.0)); at: 10 put: ((75@535.0)); at: 11 put: ((75@588.0)); at: 12 put: ((75@217.0)); at: 13 put: ((75@270.0)); at: 14 put: ((75@959.0)); at: 15 put: ((75@5.0)); at: 16 put: ((75@641.0)); at: 17 put: ((75@694.0)); at: 18 put: ((75@323.0)); at: 19 put: ((75@376.0)); at: 20 put: ((75@58.0)); yourself)). self assert: ((elements collect: #position) includesAll: result). edges := view elements select: #isEdge. edges do: [ :e | (e getShape: ROLine) attachPoint: ROHorizontalAttachPoint new ]. firstEdge := edges first. shape := firstEdge getShape: ROLine. self assert: (shape startingPointOf: firstEdge) = (firstEdge from bounds topRight + (0 @ (firstEdge from bounds height / 2))). self assert: (shape endingPointOf: firstEdge) = (firstEdge to bounds topLeft + (0 @ (firstEdge to bounds height / 2))).! ! !ROLayoutTest class methodsFor: 'testing'! isAbstract ^ self name == #ROLayoutTest ! ! !ROLayoutTest methodsFor: 'running' stamp: 'AlexandreBergel 5/22/2012 21:01'! setUp elements := ROElement forCollection: (1 to: 20). elements do: [ :n | n extent: 50@50; addShape: (ROBox new) ]. view := ROView new. view addAll: elements. elements allButFirst do: [:e | view add: (ROEdge lineFrom: elements first to: e) ]! ! !ROLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 11/19/2012 15:15'! testLayout ! ! !RORadialTreeLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 10/21/2013 15:17'! testLayout | result | RORadialTreeLayout on: elements. result := ((Array new: 20) at: 1 put: ((45.6731671849421@45.502730559964284)); at: 2 put: ((91.6731671849421@45.502730559964284)); at: 3 put: ((89.24910941249867@60.23830855950853)); at: 4 put: ((82.23241679447895@73.42084775986837)); at: 5 put: ((71.36260534295066@83.66099004760149)); at: 6 put: ((57.785285968090804@89.87948774864242)); at: 7 put: ((42.931424172489685@91.42094965928986)); at: 8 put: ((28.366525135991928@88.12291522626424)); at: 9 put: ((15.625639150522602@80.33297688439866)); at: 10 put: ((6.051576811772698@68.87214596345201)); at: 11 put: ((0.6533850860945876@54.94832317092781)); at: 12 put: ((0.0@40.02899332692796)); at: 13 put: ((4.1602843011561745@25.686561538756553)); at: 14 put: ((12.695769750615597@13.432631426059558)); at: 15 put: ((24.70686896379831@4.558691446778802)); at: 16 put: ((38.92768635795192@0.0)); at: 17 put: ((53.85943571852003@0.23701497414644734)); at: 18 put: ((67.92840299795213@5.244756456597926)); at: 19 put: ((79.65180604477166@14.49543946200992)); at: 20 put: ((87.79407067310345@27.01409920604854)); yourself). (elements collect: #position) with: result do: [ :e1 :e2 | self assert: (e1 closeTo: e2) ]! ! !RORadialTreeLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 10/21/2013 15:10'! testLayout2 RORadialTreeLayout on: elements. self assert: (elements allSatisfy: [ :e | e position >= (0 @ 0) ])! ! !ROSugiyamaLayoutTest methodsFor: 'test layout' stamp: 'DR 3/25/2013 21:52'! testLayout | result | ROSugiyamaLayout on: elements. result := ((Array new: 20) at: 1 put: ((497.0@3.0)); at: 2 put: ((974.0@73.0)); at: 3 put: ((921.0@73.0)); at: 4 put: ((868.0@73.0)); at: 5 put: ((815.0@73.0)); at: 6 put: ((762.0@73.0)); at: 7 put: ((709.0@73.0)); at: 8 put: ((656.0@73.0)); at: 9 put: ((603.0@73.0)); at: 10 put: ((550.0@73.0)); at: 11 put: ((497.0@73.0)); at: 12 put: ((444.0@73.0)); at: 13 put: ((391.0@73.0)); at: 14 put: ((338.0@73.0)); at: 15 put: ((285.0@73.0)); at: 16 put: ((232.0@73.0)); at: 17 put: ((179.0@73.0)); at: 18 put: ((126.0@73.0)); at: 19 put: ((73.0@73.0)); at: 20 put: ((20.0@73.0)); yourself). self assert: (result includesAll: (elements collect: #position))! ! !ROTreeLayoutTest methodsFor: 'test layout' stamp: 'DR 1/15/2013 21:20'! testLayout | result | ROTreeLayout on: elements. result := ((Array new: 20) at: 1 put: ((482@5)); at: 2 put: ((5@75)); at: 3 put: ((58@75)); at: 4 put: ((111@75)); at: 5 put: ((164@75)); at: 6 put: ((217@75)); at: 7 put: ((270@75)); at: 8 put: ((323@75)); at: 9 put: ((376@75)); at: 10 put: ((429@75)); at: 11 put: ((482@75)); at: 12 put: ((535@75)); at: 13 put: ((588@75)); at: 14 put: ((641@75)); at: 15 put: ((694@75)); at: 16 put: ((747@75)); at: 17 put: ((800@75)); at: 18 put: ((853@75)); at: 19 put: ((906@75)); at: 20 put: ((959@75)); yourself). self assert: (result includesAll: (elements collect: #positionAsInteger))! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/22/2013 17:50'! testLayout | previous | ROVerticalLineLayout on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position y > previous position y ]. previous := el ]! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/23/2013 15:43'! testLayoutOnEmptyCollection self shouldnt: [ ROVerticalLineLayout on: #() ] raise: Error. self shouldnt: [ ROVerticalLineLayout on: #() edges: #() ] raise: Error. self shouldnt: [ ROVerticalLineLayout new on: #() edges: #() ] raise: Error! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/22/2013 17:50'! testLayoutWithAlignment | previous | ROVerticalLineLayout new alignment: #bottom; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position y > previous position y ]. previous := el ]. ! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 4/24/2013 09:24'! testLayoutWithMargin | element result | element := ROBox blue element. element resizeStrategy: (ROExtensibleParent new paddingGap: 25). element addAll: elements. ROVerticalLineLayout on: elements. view := ROView new. view add: element. result := (((Array new: 20) at: 1 put: ((25@25)); at: 2 put: ((25@85)); at: 3 put: ((25@145)); at: 4 put: ((25@205)); at: 5 put: ((25@265)); at: 6 put: ((25@325)); at: 7 put: ((25@385)); at: 8 put: ((25@445)); at: 9 put: ((25@505)); at: 10 put: ((25@565)); at: 11 put: ((25@625)); at: 12 put: ((25@685)); at: 13 put: ((25@745)); at: 14 put: ((25@805)); at: 15 put: ((25@865)); at: 16 put: ((25@925)); at: 17 put: ((25@985)); at: 18 put: ((25@1045)); at: 19 put: ((25@1105)); at: 20 put: ((25@1165)); yourself)). self assert: (elements collect: #position) = result! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/22/2013 17:50'! testStretch | previous | ROVerticalLineLayout new stretch; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position y > previous position y ]. previous := el ].! ! !ROVerticalLineLayoutTest methodsFor: 'test layout' stamp: 'AlexandreBergel 5/6/2013 18:03'! testStretchInsideElement | previous random rootElement | elements := ROElement forCollection: (1 to: 10). random := #(23 53 60 50). elements do: [ :n | n extent: (random anyOne) @ (random anyOne); addShape: (ROBox new); addShape: (ROBorder new) ]. rootElement := ROElement on: 11. rootElement size: (11 * 55). rootElement addShape: ROBorder black. rootElement addAll: elements. view := ROView new. view add: rootElement. ROVerticalLineLayout new stretch; on: elements. previous := nil. elements do: [ :el | previous notNil ifTrue: [ self assert: el position y > previous position y. self assert: el width = previous width. ]. previous := el ].! ! !ROVerticalNarrowTreeLayoutTest methodsFor: 'test layout' stamp: 'JurajKubelka 4/2/2013 12:02'! testLayout | result | ROVerticalNarrowTreeLayout on: elements. result := ((Array new: 20) at: 1 put: ((480.0@3.0)); at: 2 put: ((3.0@73.0)); at: 3 put: ((56.0@73.0)); at: 4 put: ((109.0@73.0)); at: 5 put: ((162.0@73.0)); at: 6 put: ((215.0@73.0)); at: 7 put: ((268.0@73.0)); at: 8 put: ((321.0@73.0)); at: 9 put: ((374.0@73.0)); at: 10 put: ((427.0@73.0)); at: 11 put: ((480.0@73.0)); at: 12 put: ((533.0@73.0)); at: 13 put: ((586.0@73.0)); at: 14 put: ((639.0@73.0)); at: 15 put: ((692.0@73.0)); at: 16 put: ((745.0@73.0)); at: 17 put: ((798.0@73.0)); at: 18 put: ((851.0@73.0)); at: 19 put: ((904.0@73.0)); at: 20 put: ((957.0@73.0)); yourself). self assert: (elements collect: #position) = result.! ! !ROAbsorbLayoutTranslatorTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/17/2012 17:28'! testLayout layout translator: ROAbsorbLayoutTranslator new. layout applyOn: elements. self assert: ((elements collect: #position) asSet asArray first = (0@0))! ! !RODirectLayoutTranslatorTest methodsFor: 'tests' stamp: 'DR 3/25/2013 22:03'! testLayout | result | layout translator: RODirectLayoutTranslator new. layout applyOn: elements. result := ((Array new: 7) at: 1 put: (31@5); at: 2 put: (31@75); at: 3 put: (58@145); at: 4 put: (111@5); at: 5 put: (5@145); at: 6 put: (32@5); at: 7 put: (32@75); yourself). self assert: (result includesAll: (elements collect: #positionAsInteger))! ! !ROLayoutTranslatorTest methodsFor: 'running' stamp: 'AlexandreBergel 12/1/2012 10:14'! setUp | edges | view := ROView new. elements := ROElement spritesOn: (1 to: 5). view addAll: elements. view addAll: (edges := ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third )). layout := ROTreeLayout new! ! !ROLayoutTranslatorTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/18/2012 15:33'! testDefault " Commented out because isAbstractClass is not in VW self assert: ROLayoutTranslator isAbstractClass. self assert: ROLayoutTranslator defaultClass isAbstractClass not. " self assert: (ROLayoutTranslator withAllSubclasses select: #isDefault) size = 1. self assert: ROLayoutTranslator default class == ROLayoutTranslator defaultClass! ! !ROSmoothLayoutTranslatorTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 17:42'! testLayout | result | layout translator: ROSmoothLayoutTranslator new. self deny: view hasAnimation. layout applyOn: elements. self assert: view hasAnimation. self assert: ((elements collect: #positionAsInteger) asSet asArray first = (0@0)). self assert: layout translator hasCompleted not. view doAllAnimationCycles. self assert: layout translator hasCompleted. result := ((Array new: 5) at: 1 put: (31@5); at: 2 put: (31@75); at: 3 put: (58@145); at: 4 put: (110@5); at: 5 put: (4@145); yourself). self assert: ((result with: (elements collect: #positionAsInteger) collect: [ :v1 :v2 | v1 - v2 ]) allSatisfy: [ :v | v <= (1 @ 1) ])! ! !ROLineTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/14/2012 19:14'! testColorBlockTakesTheElement | edge line | line := ROLine new color: #model. edge := ROEdge on: 42. self assert: (line colorFor: edge) = 42! ! !ROLineTest methodsFor: 'tests creation' stamp: 'AlexandreBergel 4/7/2013 01:02'! testCreation | shape | shape := ROLine arrowed color: Color blue. self assert: (shape elementOn: 123) model = 123. self assert: (shape elementOn: 123) class == ROEdge. ! ! !ROLineTest methodsFor: 'tests creation' stamp: 'AlexandreBergel 4/7/2013 01:02'! testCreation2 | el1 el2 edge shape | shape := ROLine arrowed color: Color blue. el1 := ROBox element. el2 := ROBox element. edge := shape elementFrom: el1 to: el2. self assert: edge class == ROEdge. self assert: edge from == el1. self assert: edge to == el2.! ! !ROLineTest methodsFor: 'tests' stamp: 'AlexandreBergel 10/14/2012 19:15'! testWidthBlockTakesTheElement | edge line | line := ROLine new width: #model. edge := ROEdge on: 42. self assert: (line widthFor: edge) = 42! ! !ROLinearMoveTest commentStamp: '' prior: 34279059! A ROLinearMoveTest is a test class for testing the behavior of ROLinearMove! !ROLinearMoveTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/7/2013 14:52'! testCallingAfter | move | move := ROLinearMove for: ROElement new by: 50 @ 50. move after.! ! !ROMenuElementTest methodsFor: 'running' stamp: 'AlexandreBergel 9/1/2012 19:54'! setUp emptyMenu := ROMenuElement new. menu := ROMenuElement new. menu item: 'reset' action: [ :v | counter := 0. ]. menu item: 'increase' action: [ :v | counter := counter + 1 ].! ! !ROMenuElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/1/2012 19:55'! testEvaluateCallback self assert: counter isNil. menu evaluate: 'reset'. self assert: counter = 0. menu evaluate: 'increase'. self assert: counter = 1. menu evaluate: 'increase'. menu evaluate: 'increase'. self assert: counter = 3. ! ! !ROMenuElementTest methodsFor: 'test-initialization' stamp: 'AlexandreBergel 9/1/2012 23:35'! testInitialization self assert: emptyMenu targetObject == emptyMenu. ! ! !ROMenuElementTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/1/2012 19:49'! testNumberOfActions self assert: emptyMenu numberOfActions = 0. self assert: menu numberOfActions = 2. ! ! !ROMenuElementTest methodsFor: 'test-rendering' stamp: 'JurajKubelka 10/11/2013 16:49'! testRendering self assert: menu numberOfElements = 0. self assert: menu extent = ROMenuElement defaultBounds extent. menu create. self assert: menu numberOfElements = menu numberOfActions. self assert: menu extent >= (50@50). "ROView new add: menu; open "! ! !ROMenuElementTest methodsFor: 'test-rendering' stamp: 'JurajKubelka 10/11/2013 16:50'! testRenderingEmpty self assert: emptyMenu numberOfElements = 0. self assert: emptyMenu extent = emptyMenu class defaultBounds extent. emptyMenu create. self assert: emptyMenu numberOfElements = 0. self assert: emptyMenu extent = emptyMenu class defaultBounds extent.! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:24'! testCameraTranslation | view miniMap | view := ROView new. view addAll: ((ROBox new size: 50) elementsOn: (1 to: 100)). ROGridLayout on: view elements. view @ ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: (miniMap lupa position = (0 @ 0)). self assert: (view camera position = (0 @ 0)). self assert: (miniMap miniMapDisplayer camera realExtent) = (3 @ 3). view camera translateBy: 100 @ 100. view announce: (ROCameraTranslated new step: 100 @ 100). self assert: (miniMap miniMapDisplayer camera realExtent) = (3 @ 3). self assert: (view camera position = (100 @ 100)). self assert: (miniMap lupa position = (0 @ 0))! ! !ROMiniMapTest methodsFor: 'creation' stamp: 'AlexandreBergel 9/15/2013 00:43'! testCreation | view miniMap | view := ROView new. self deny: (view hasAttribute: #miniMap). view @ ROMiniMap. self assert: (view hasAttribute: #miniMap). miniMap := (view attributeAt: #miniMap). self assert: miniMap notNil. self assert: (miniMap lupa position = (0 @ 0)). self assert: (miniMap lupa extent = (5 @ 5)). self assert: (miniMap camera position = (0 @ 0)). "self assert: (miniMap miniMap extent = (200 @ 200))" ! ! !ROMiniMapTest methodsFor: 'creation' stamp: 'AlexandreBergel 9/14/2013 20:03'! testGetsizeOfView | view map | view := ROView new. self assert: view encompassingRectangle extent = (1 @ 1). map := ROMiniMap new. self assert: (map getEncompassingRectangleOfView: view) = map minimumViewRectangle ! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'VanessaPena 1/5/2013 21:14'! testLupaCreation |view miniMap| view := ROView new. view @ROMiniMap. view windowSize: (300@300). miniMap := (view attributes at: #miniMap). self assert: (miniMap lupa extent = (1500@1500)). ! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'VanessaPena 1/5/2013 21:14'! testLupaTranslation |view miniMap| view := ROView new. view add: ROElement sprite. view @ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: (miniMap lupa position = (0@0)). self assert: (view camera position = (0@0)). miniMap lupa announce: (ROMouseDragging new step: 10@10). self assert: (miniMap lupa position = (10@10)). self assert: (view camera position = (100@100)).! ! !ROMiniMapTest methodsFor: 'minimap' stamp: 'VanessaPena 1/5/2013 21:13'! testMiniMapCameraAfterContainerResize |view miniMap| view := ROView new. view add: ROElement sprite. view @ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: miniMap isNil not. self assert: (miniMap miniMap extent = (200@200)). self assert: (miniMap camera realExtent = (50@50)). miniMap container windowSize: (300@300). self assert: (miniMap miniMap extent = (300@300)). self assert: (miniMap camera realExtent = (3000@3000)).! ! !ROMiniMapTest methodsFor: 'minimap' stamp: 'VanessaPena 1/5/2013 21:13'! testMiniMapContainerResize |view miniMap| view := ROView new. view add: ROElement sprite. view @ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: miniMap isNil not. self assert: (miniMap containerSize = (200@200)). self assert: (miniMap miniMap extent = (200@200)). miniMap container windowSize: (300@300). self assert: (miniMap containerSize = (300@300)). self assert: (miniMap miniMap extent = (300@300)). ! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'VanessaPena 1/5/2013 21:12'! testMiniMapOnClik |view miniMap| view := ROView new. view add: ROElement sprite. view @ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: (miniMap lupa position = (0@0)). self assert: (view camera position = (0@0)). miniMap container announce: (ROMouseLeftClick new position: 10@10). self assert: (miniMap lupa position = (10@10)). self assert: (view camera position = (100@100)).! ! !ROMiniMapTest methodsFor: 'minimap' stamp: 'AlexandreBergel 9/15/2013 00:35'! testMiniMapPosition | view miniMap | view := ROView new. view add: ROElement sprite. view add: ROElement sprite. ROVerticalLineLayout new on: view elements. view @ ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: miniMap isNil not. self assert: (miniMap miniMap extent = (100@200)). self assert: (miniMap miniMap position = (50@0)). ! ! !ROMiniMapTest methodsFor: 'minimap' stamp: 'AlexandreBergel 9/15/2013 00:40'! testMiniMapPositionAfterContainerResize | view miniMap | view := ROView new. view add: ROElement sprite. view add: ROElement sprite. ROVerticalLineLayout new on: view elements. view @ ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: miniMap isNil not. self assert: (miniMap miniMap extent = (100 @ 200)). self assert: (miniMap miniMap position = (50 @ 0)). miniMap container windowSize: (300 @ 300). self assert: (miniMap miniMap extent = (150 @ 300)). self assert: (miniMap miniMap position = (75 @ 0)). ! ! !ROMiniMapTest methodsFor: 'minimap' stamp: 'VanessaPena 1/5/2013 21:10'! testMiniMapSizeAdjustment |view miniMap| view := ROView new. view add: ROElement sprite. view @ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: miniMap isNil not. self assert: (miniMap containerSize = (200@200)). self assert: (miniMap miniMap extent = (200@200)). self assert: (miniMap miniMap position = (0@0) ). self assert: (miniMap camera realExtent = (50@50)). ! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:43'! testViewZoomIn | view miniMap | view := ROView new. view @ ROMiniMap. view windowSize: 500 @ 500. miniMap := (view attributeAt: #miniMap). self assert: (miniMap lupa position = (0 @ 0)). self assert: (miniMap lupa extent = (2500 @ 2500)). ROZoomInMove new on: view. view doAllAnimationCycles. self assert: (miniMap lupa position = (297 @ 297)). self assert: (miniMap lupa extent = (2100 @ 2100)).! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:38'! testViewZoomOut | view miniMap | view := ROView new. view @ ROMiniMap. view windowSize: 500 @ 500. miniMap := (view attributes at: #miniMap). self assert: (miniMap lupa position = (0 @ 0)). self assert: (miniMap lupa extent = (2500 @ 2500) ). ROZoomOutMove new on: view. view doAllAnimationCycles. self assert: (miniMap lupa position = (-103@ -103)). self assert: (miniMap lupa extent = (2900@2900)).! ! !ROMiniMapTest methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:39'! testWindowResize | view miniMap | view := ROView new. view @ ROMiniMap. miniMap := (view attributes at: #miniMap). self assert: (miniMap miniMap extent = (5 @ 5)). view windowSize: 1000 @ 1000. self assert: (miniMap miniMap extent = (1000 @ 1000)). ! ! !ROMondrianCacheTest methodsFor: 'test cache shapes' stamp: 'AlexandreBergel 6/14/2013 12:19'! expectedFailures ^ #(#testCacheShapeAndInnerElements)! ! !ROMondrianCacheTest methodsFor: 'running' stamp: 'AlexandreBergel 12/11/2012 15:48'! setUp super setUp. view := ROMondrianViewBuilder new! ! !ROMondrianCacheTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 18:48'! testCache | t | t := OrderedCollection new. view shape rectangle height: [ :v | t add: (Array with: v with: #height). 10 ]; width: [ :v | t add: (Array with: v with: #width). 20 ]; fillColor: [ :v | t add: (Array with: v with: #width). Color blue ]. view nodes: #(1 2). view raw drawOn: RONullCanvas new. self assert: t size = 6. view raw drawOn: RONullCanvas new. view raw drawOn: RONullCanvas new. self assert: t size = 6. ! ! !ROMondrianCacheTest methodsFor: 'test cache shapes' stamp: 'AlexandreBergel 4/11/2013 15:54'! testCacheShapeAndInnerElements | element canvas | view := ROMondrianViewBuilder new. element := view node: 'hello' forIt: [ view nodes: (1 to: 20) ]. element translateBy: -200 @ 0. view noLayout. self assert: view raw numberOfElementsToRender = 21. view raw windowSize: 500 @ 500. canvas := ROTracingCanvas new. view raw drawOn: canvas. self assert: view raw numberOfElementsToRender = 1. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white'))! ! !ROMondrianCacheTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 19:22'! testCacheWithInner | t | t := OrderedCollection new. view node: 'foo' forIt: [ view shape rectangle height: [ :v | t add: (Array with: v with: #height). 10 ]; width: [ :v | t add: (Array with: v with: #width). 20 ]; fillColor: [ :v | t add: (Array with: v with: #color). Color blue ]. view nodes: #(1 2) ]. view raw drawOn: RONullCanvas new. self assert: t size = 6. view raw drawOn: RONullCanvas new. view raw drawOn: RONullCanvas new. self assert: t size = 6. ! ! !ROMondrianScatterLayoutTest methodsFor: 'running' stamp: 'AlexandreBergel 5/21/2012 22:41'! tearDown window ifNotNil: [ window delete ]! ! !ROMondrianScatterLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/21/2012 22:39'! testScatterplotLayout | nodes | view := ROMondrianViewBuilder new. nodes := view nodes: #(#(10 20) #(30 40)). view layout: (ROScatterplotLayout new x: [:entity | entity first ]; y: [:entity | entity last ]). window := view open. self assert: nodes first bounds topLeft x = 10. self assert: nodes first bounds topLeft y = 20. self assert: nodes last bounds topLeft x = 30. self assert: nodes last bounds topLeft y = 40. ! ! !ROMondrianScatterLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/21/2012 22:39'! testScatterplotLayoutBounds " self debug: #testScatterplotLayoutBounds " | nodes | view := ROMondrianViewBuilder new. view node: #foo forIt: [ view layout: (ROScatterplotLayout new x: #first ; y: #last). nodes := view nodes: #(#(10 20) #(30 40)). ]. window := view open. self assert: nodes first bounds topLeft x = 10. self assert: nodes first bounds topLeft y = 20. self assert: nodes last bounds topLeft x = 30. self assert: nodes last bounds topLeft y = 40. ! ! !ROMondrianScatterLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/21/2012 22:45'! testScatterplotLayoutOffset | nodes | view := ROMondrianViewBuilder new. nodes := view nodes: #(#(10 20) #(30 40)). view layout: (ROScatterplotLayout new offset: 2; x: [:entity | entity first ]; y: [:entity | entity last ]). window := view open. self assert: nodes first bounds topLeft x = 12. self assert: nodes first bounds topLeft y = 22. self assert: nodes last bounds topLeft x = 32. self assert: nodes last bounds topLeft y = 42. ! ! !ROMondrianScatterLayoutTest methodsFor: 'tests' stamp: 'DR 3/25/2013 21:58'! testScatterplotLayoutScalled | nodes | view := ROMondrianViewBuilder new. view node: #foo forIt: [ view layout: (ROScatterplotLayout new x: #first ; y: #last ; scaledToWidth: 20; scaledToHeight: 15 ). nodes := view nodes: #(#(10 20) #(30 40)). ]. window := view open. self assert: nodes first bounds topLeft x >= 6. self assert: nodes first bounds topLeft x <= 7. self assert: nodes first bounds topLeft y >= 7. self assert: nodes first bounds topLeft y <= 8. self assert: nodes last bounds topLeft x = 20. self assert: nodes last bounds topLeft y = 15. ! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'edgesDefinedFromOutside' stamp: 'AlexandreBergel 7/25/2012 17:19'! buildScenario view := ROMondrianViewBuilder new. view nodes: #(1 2) forEach: [ :each | view nodes: (Array with: each * 10 with: (each * 100)). view treeLayout. ]. view edgesFromAssociations: (Array with: 10 -> 100 with: 20 -> 200). view applyLayout. ! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'running' stamp: 'AlexandreBergel 7/25/2012 11:24'! setUp view := ROMondrianViewBuilder new.! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'running' stamp: 'AlexandreBergel 5/21/2012 22:36'! tearDown window ifNotNil: [ window delete ]! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'edgesDefinedFromOutside' stamp: 'AlexandreBergel 7/24/2012 15:00'! testEdgesDefinedOutside | firstNode secondNode | self buildScenario. firstNode := view raw elements first. secondNode := view raw elements second. "We check who has the edge" self assert: (firstNode elements size = 3). self assert: (secondNode elements size = 3). self assert: view raw elements size = 2.! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'edgesDefinedFromOutside' stamp: 'AlexandreBergel 12/10/2012 20:12'! testEdgesDefinedOutsideLayout | firstNode secondNode | self buildScenario. firstNode := view raw elements first. secondNode := view raw elements second. "We check the layout" self assert: (firstNode elementsNotEdge collect: #position) asArray reverse = (Array with: 5 @ 30 with: 5 @ 5). self assert: (secondNode elementsNotEdge collect: #position) asArray reverse = (Array with: 5 @ 30 with: 5 @ 5). ! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'edgesDefinedFromOutside' stamp: 'AlexandreBergel 7/25/2012 11:02'! testEdgesDefinedOutsideLayoutStructure | firstInnerFrame secondInnerFrame | self buildScenario. self assert: view numberOfFrames = 3. "Outter frame" self assert: view structureTree elements size = 2. self assert: view structureTree nodes size = 2. "First inner frame" firstInnerFrame := view structureTree children first. self assert: firstInnerFrame elements size = 3. self assert: firstInnerFrame nodes size = 2. self assert: firstInnerFrame edges size = 1. "Second inner frame" secondInnerFrame := view structureTree children second. self assert: secondInnerFrame elements size = 3. self assert: secondInnerFrame nodes size = 2. self assert: secondInnerFrame edges size = 1.! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/25/2012 11:26'! testEdgesFrom | outterFrame firstInnerFrame secondInnerFrame | view nodes: #(1 10) forEach: [ :v | view nodes: (Array with: v +1 with: v + 2 with: v + 3). view shape line. view edgesFrom: [ :el | v + 1 ]. view treeLayout ]. view horizontalLineLayout. view applyLayout. self assert: view structureTree numberOfFrames = 3. outterFrame := view structureTree . firstInnerFrame := outterFrame children first. secondInnerFrame := outterFrame children second. self assert: (outterFrame nodes size = 2). self assert: (outterFrame edges size = 0). self assert: (firstInnerFrame nodes size = 3). self assert: (firstInnerFrame edges size = 2). self assert: (secondInnerFrame nodes size = 3). self assert: (secondInnerFrame edges size = 2).! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/25/2012 11:23'! testLayouts | l | l := OrderedCollection new. l add: #treeLayout. l add: #gridLayout. l add: #forceBasedLayout. l add: #circleLayout. l add: #verticalLineLayout. l add: #horizontalLineLayout. l add: #sugiyamaLayout. l add: #bottomFlowLayout. l add: #flowLayout. l add: #radialTreeLayout. l add: #scatterPlotLayout. l add: #noLayout. view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. l do: [ :sel | self shouldnt: [ view perform: sel. view applyLayout ] raise: Error ]! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'tests' stamp: 'JurajKubelka 6/3/2013 21:36'! testTreeLayoutAndColor "Strange bug http://code.google.com/p/objectprofile/issues/detail?id=86&thanks=86&ts=1341240917" | edges | view shape rectangle size: 50. view nodes: (1 to: 5). view shape line color: Color blue. edges := view edgesFromAssociations: (Array with: 1 -> 5 with: 1 -> 2 with: 3 -> 4). self assert: (edges allSatisfy: [ :edge | ((edge getShape: ROLine) colorFor: edge) = Color blue ]). view treeLayout . "view open"! ! !ROMondrianViewBuilderLayoutTest methodsFor: 'user defined edges' stamp: 'AlexandreBergel 12/11/2012 12:31'! testUserDefinedEdges " to address: http://code.google.com/p/moose-technology/issues/detail?id=834 " | edges layout | view nodes: #(1 2 3). edges := view edgesFrom: [ :each | each - 1 ]. view shape line color: Color red. view edges: #(3) from: [ :each | each - 2 ] to: #yourself. layout := view treeLayout userDefinedEdges: edges; yourself. "We check the user defined edges before doing the layout" self assert: (layout userDefinedEdges = edges). "We do the layout" view applyLayout. "We first check whether the edges have been well defined." self assert: edges size = 2. self assert: (edges last from model = 2). self assert: (edges last to model = 3). self assert: (edges first from model = 1). self assert: (edges first to model = 2). "We then checked if the edges are defined in the layout" self assert: (layout userDefinedEdges = edges). self assert: (layout edges = edges). ! ! !ROMondrianViewBuilderTest commentStamp: '' prior: 34279202! A ROMondrianViewBuilderTest is a test class for testing the behavior of ROMondrianViewBuilder! !ROMondrianViewBuilderTest methodsFor: 'running'! setUp view := ROMondrianViewBuilder new! ! !ROMondrianViewBuilderTest methodsFor: 'running'! tearDown super tearDown. window ifNotNil: [window delete. window := nil]! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes'! testAbsolutePosition | inner2 outter inner | outter := view node: 'outter' forIt: [ inner := view node: 'inner' forIt: [ inner2 := view node: 'inner2' ] ]. view applyLayout. self assert: outter absolutePosition = outter position. self assert: outter absolutePosition = (5@5). self assert: inner absolutePosition = (inner position + outter position). self assert: inner absolutePosition = (10@10). self assert: inner2 absolutePosition = (inner2 position + outter position + inner position). self assert: inner2 absolutePosition = ( 15@15).! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes'! testAbsolutePositionAfterTranslation | inner2 outter inner | outter := view node: 'outter' forIt: [ inner := view node: 'inner' forIt: [ inner2 := view node: 'inner2' ] ]. view applyLayout. outter translateBy: 10@3. self assert: outter absolutePosition = outter position. self assert: outter absolutePosition = (5@5 + (10@3)). self assert: inner absolutePosition = (inner position + outter position). self assert: inner absolutePosition = (10@10 + (10@3)). self assert: inner2 absolutePosition = (inner2 position + outter position + inner position). self assert: inner2 absolutePosition = ( 15@15 + (10@3)).! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'AlexandreBergel 6/9/2012 15:18'! testAddingNode view node: 123. self assert: (view raw numberOfElements = 1)! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'AlexandreBergel 6/9/2012 15:18'! testAddingNodes view nodes: (1 to: 20). self assert: (view raw numberOfElements = 20)! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/17/2012 12:18'! testBorderColor | nodes b | view shape rectangle borderColor: (b := [ :model | model + 1]). nodes := view nodes: #(2 3 4). self assert: (nodes collect: [ :n | (n getShape: ROBox) borderColorFor: n]) = #(3 4 5)! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/15/2012 13:11'! testBorderColorWithNormalizer view shape rectangle borderColor: (RONIdentityNormalizer new). view nodes: (1 to: 10). self shouldnt: [view raw drawOn: RONullCanvas new] raise: Error! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/17/2012 12:14'! testBorderWidth | nodes b | view := ROMondrianViewBuilder new. view shape rectangle borderWidth: (b := [ :model | model + 1 ]). nodes := view nodes: #(2 3 4). self assert: (nodes collect: [ :n | (n getShape: ROBox) borderWidthFor: n]) = #(3 4 5)! ! !ROMondrianViewBuilderTest methodsFor: 'interaction'! testChangeInteraction | el | el := ROElement new. self deny: (el is: ROAbstractPopup). self deny: (el is: ROPopup). self deny: (el is: ROPopupView). el changeInteraction: ROPopup for: (ROPopupView new). self deny: (el is: ROPopup). self assert: (el is: ROPopupView). el changeInteraction: ROPopupView for: (ROPopup new). self assert: (el is: ROPopup). self deny: (el is: ROPopupView). ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction'! testChangeInteraction2 | el | el := ROElement new. self deny: (el is: ROAbstractPopup). self deny: (el is: ROPopup). self deny: (el is: ROPopupView). el changeInteraction: ROAbstractPopup for: (ROPopupView new). self deny: (el is: ROPopup). self assert: (el is: ROPopupView). el changeInteraction: ROAbstractPopup for: (ROPopup new). self assert: (el is: ROPopup). self deny: (el is: ROPopupView). ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'VanessaPena 3/12/2013 15:30'! testCircle | element | view shape circle. element := view node: 'hello'. self assert: (element isShapedAs: ROEllipse). "view raw bitmap."! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'VanessaPena 3/12/2013 15:30'! testCircleWithBorderedColor | element | view shape circle borderColor: [ :v | Color r: 255 g: 255 b: v]. element := view node: 255. self assert: (element isShapedAs: ROEllipse). ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:32'! testColor | model edge | view shape rectangle. view nodes: #(1 2). view shape line color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: ROLine) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:10'! testColor2 | model | view shape rectangle color: [ :m | model := m. Color blue ]. node := view node: Object. self assert: model == nil. self assert: ((node getShape: ROBox) colorFor: node) = Color blue. self assert: model == Object.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:32'! testColorOfArrowedLine | model edge | view shape rectangle. view nodes: #(1 2). view shape arrowedLine color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: ROLine) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:33'! testColorOfArrowedLineReversed | model edge | view shape rectangle. view nodes: #(1 2). view shape arrowedLineReversed color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: ROLine) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:33'! testColorOfBezierLine | model edge | view shape rectangle. view nodes: #(1 2). view shape bezierLine color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: RORadialBezierCurve) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:33'! testColorOfOrthoHorizontalLine | model edge | view shape rectangle. view nodes: #(1 2). view shape orthoHorizontalLine color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: ROOrthoHorizontalLineShape) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 15:33'! testColorOfOrthoVerticalLine | model edge | view shape rectangle. view nodes: #(1 2). view shape orthoVerticalLine color: [ :m | model := m. Color blue ]. edge := view edge: #edge from: 1 to: 2. self assert: model == nil. self assert: ((edge getShape: ROOrthoVerticalLineShape) colorFor: edge) = Color blue. self assert: model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 7/23/2012 15:23'! testColoredEdges | edge1 edge2 | view nodes: #(1 2 3). edge1 := view edgeFromAssociation: 1 -> 2. view shape line color: Color red. edge2 := view edgeFromAssociation: 2 -> 3. view treeLayout. self assert: (edge1 numberOfShapes = 2). self assert: (edge2 numberOfShapes = 2)! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 15:36'! testColoredEdges2 | edges | view shape rectangle size: 50. view nodes: (1 to: 5). view shape line color: [ :assoc | (assoc key + assoc value) odd ifTrue: [ Color red ] ifFalse: [ Color black ] ]. edges := view edgesFromAssociations: (Array with: 1 -> 5 with: 1 -> 2 with: 3 -> 4). view treeLayout. self assert: ((edges first getShape: ROLine) color roValue: edges first) = Color black. self assert: ((edges second getShape: ROLine) color roValue: edges second) = Color red.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 21:34'! testColoredEdgesUponCondition | edges firstEdge secondEdge | view nodes: (1 to: 3). view shape line color: [ :model | (model = 1) ifTrue: [ Color red ] ifFalse: [ Color lightGray ] ]. edges := view edges: (1 to: 3) from: #yourself to: [ :v | v + 1 ]. view circleLayout. self assert: edges size = 2. "First edge" firstEdge := edges first. self assert: firstEdge model = 1. self assert: firstEdge from model = 1. self assert: firstEdge to model = 2. self assert: ((firstEdge getShape: ROLine) colorFor: firstEdge) = Color red. "Second edge" secondEdge := edges second. self assert: secondEdge model = 2. self assert: secondEdge from model = 2. self assert: secondEdge to model = 3. self assert: ((secondEdge getShape: ROLine) colorFor: secondEdge) = Color lightGray.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 7/23/2012 15:23'! testColoredEdgesWithoutLayout | edge1 edge2 | view nodes: #(1 2 3). edge1 := view edgeFromAssociation: 1 -> 2. view shape line color: Color red. edge2 := view edgeFromAssociation: 2 -> 3. self assert: (edge1 numberOfShapes = 2). self assert: (edge2 numberOfShapes = 2)! ! !ROMondrianViewBuilderTest methodsFor: 'constraining inner nodes' stamp: 'AlexandreBergel 4/29/2013 16:50'! testConstrainingInnerNodes node := view node: 1 forIt: [ view nodes: (1 to: 9). view gridLayout ]. view horizontalLineLayout on: ROLayoutEnd do: [ :event | view raw elementsDo: [ :el | el resizeStrategy: (ROFixedSizedParent instance) ] ]. view applyLayout. self assert: node extent = (33@33). node elements first translateBy: 100 @ 100. "The size does not change" self assert: node extent = (33@33).! ! !ROMondrianViewBuilderTest methodsFor: 'statusbar' stamp: 'AlexandreBergel 5/31/2013 13:50'! testCreateStatusBar self deny: (view stack hasAttribute: #statusBar). self assert: view stack numberOfElements = 0. view interaction createStatusBarIfNecessary. self assert: (view stack hasAttribute: #statusBar). self assert: view stack numberOfElements = 1 ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 5/7/2012 12:01'! testDefaultShapeForEdge | edge | view nodes: #(1 2 3). edge := view edgeFromAssociation: 1 -> 2. self assert: (edge isShapedAs: ROLine) ! ! !ROMondrianViewBuilderTest methodsFor: 'statusbar' stamp: 'AlexandreBergel 6/12/2013 11:40'! testDefaultStatusBar | nodes statusBarElement | statusBarElement := view interaction statusBar. nodes := view nodes: (1 to: 4). self assert: view stack numberOfElements = 1. self assert: view stack firstView numberOfElements = 4. self assert: (statusBarElement getShape: ROLabel) text = ''. nodes first announce: ROMouseEnter. self assert: (statusBarElement getShape: ROLabel) text = '1' ! ! !ROMondrianViewBuilderTest methodsFor: 'instantiating' stamp: 'AlexandreBergel 5/17/2012 20:52'! testDefaultTitle | builder | builder := ROMondrianViewBuilder new. window := builder open. [ self assert: window labelString = ROView defaultWindowTitle. ] ensure: [ window delete ]! ! !ROMondrianViewBuilderTest methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/17/2013 18:24'! testDynamicEdges | firstNode | view interaction dynamicEdgeToAll: [ :model | (Array with: 10 with: 20 with: 30) copyWithout: model ] using: (ROLine arrowed color: Color red). view shape rectangle size: 20. view nodes: (Array with: 10 with: 20 with: 30). view circleLayout. view applyLayout. self assert: view raw numberOfElements = 3. self assert: (view raw elementsSuchThat: #isEdge) isEmpty. firstNode := view raw elements first. self assert: firstNode numberOfInteractions = 3. self assert: (firstNode is: RODynamicEdge). firstNode announce: ROMouseEnter. self assert: view raw numberOfElements = 5. self assert: (view raw elementsSuchThat: #isEdge) size = 2. ! ! !ROMondrianViewBuilderTest methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/17/2013 18:24'! testDynamicEdgesMultiple | firstNode | view interaction dynamicEdgeToAll: [ :model | ((Array with: 10 with: 20 with: 30) copyWithout: model) allButFirst ] using: (ROLine arrowed color: Color red); dynamicEdgeToAll: [ :model | ((Array with: 30 with: 20 with: 10) copyWithout: model) allButFirst ] using: (ROLine arrowed color: Color blue). view shape rectangle size: 20. view nodes: (Array with: 10 with: 20 with: 30). view circleLayout. view applyLayout. self assert: view raw numberOfElements = 3. self assert: (view raw elementsSuchThat: #isEdge) isEmpty. firstNode := view raw elements first. self assert: firstNode numberOfInteractions = 3. self assert: (firstNode is: RODynamicEdge). firstNode announce: ROMouseEnter. self assert: view raw numberOfElements = 5. self assert: (view raw elementsSuchThat: #isEdge) size = 2. ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 8/27/2013 21:32'! testEdgeAndInteraction | edge | view := ROMondrianViewBuilder new. view shape rectangle size: 30. view nodes: (1 to: 2). edge := view edgeFromAssociation: 1 -> 2. self assert: edge numberOfInteractions = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 8/27/2013 21:32'! testEdgeAndInteraction2LowLevel | edge | view := ROMondrianViewBuilder new. view shape line. edge := view buildEdgeFrom: (ROElement on: 1) to: (ROElement on: 2) for: 'zork'. self assert: edge numberOfInteractions = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:22'! testEdgeFromAllTo | edges | view nodes: #(1 2). view edges: #(1 2) fromAll: [ :v | Array with: 1 ] to: #yourself. self assert: (view raw elementsSuchThat: [ :n | n class == ROElement ]) size = 2. edges := view raw elementsSuchThat: [ :n | n class == ROEdge ]. self assert: edges size = 1. self assert: edges first source model = 1. self assert: edges first target model = 2.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:24'! testEdgeFromAndToItself " self debug: #testEdgeFromAndToItself " | edges | view nodes: #(1 2). view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 2 with: 1 -> 1). self assert: (view raw elementsSuchThat: [ :n | n class == ROElement ]) size = 2. edges := view raw elementsSuchThat: [ :n | n class == ROEdge ]. self assert: edges size = 1. self assert: edges first source model = 1. self assert: edges first target model = 2. ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:25'! testEdgeFromAndToItself2 " self debug: #testEdgeFromAndToItself2 " | edges | view nodes: #(1 2). view edges: #(1 2) from: #yourself toAll: [ :v | Array with: 1 ]. self assert: (view raw elementsSuchThat: [ :n | n class == ROElement ]) size = 2. edges := view raw elementsSuchThat: [ :n | n class == ROEdge ]. self assert: edges size = 1. self assert: edges first source model = 2. self assert: edges first target model = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 14:40'! testEdgeFromAssociation | nodes edges ass m | nodes := view nodes: #(1 2 3 4). view edge: (1 -> 2) from: #key to: #value. edges := view root edges. self assert: edges size = 1. self assert: edges first from = nodes first. self assert: edges first to = nodes second.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 14:42'! testEdgeFromAssociation2 | nodes edges ass m | nodes := view nodes: #(1 2 3 4). view edge: (1 -> 20) from: #key to: #value. edges := view root edges. self assert: edges isEmpty ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 15:53'! testEdgeFromTo | edge | view nodes: (1 to: 5). edge := view edge: #edge from: 1 to: 2. self assert: edge source model = 1. self assert: edge target model = 2. self assert: edge model = (1 -> 2).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 12/11/2012 12:32'! testEdgesAndInnerNodes "Node extremities should be looked up with the nesting" | outterNode1 edges innerNode1 innerNode2 innerNode3 | outterNode1 := view node: 'outter1' forIt: [ innerNode1 := view node: 1 ]. view node: 'outter2' forIt: [ innerNode2 := view node: 2 ]. view node: 'outter3' forIt: [ innerNode3 := view node: 3 ]. view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3 with: 1 -> 3). self assert: (view nestedLookup: 1 in: outterNode1) = innerNode1. self assert: (view nestedLookup: 2 in: outterNode1) isNil. self assert: (view lookup: 1) == innerNode1. self assert: (view lookup: 2) == innerNode2. self assert: (view lookup: 3) == innerNode3. edges := view root edges. self assert: edges size = 3. self assert: (edges last from == innerNode1). self assert: (edges last to == innerNode3).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 8/8/2013 14:30'! testEdgesFrom view := ROMondrianViewBuilder new. view interaction on: ROMouseClick do: [ :event | view shape rectangle. view interaction on: ROMouseClick do: [ :otherEvent | view shape rectangle. view nodes: otherEvent model subclasses. view edgesFrom: #superclass. view treeLayout. view applyLayout ]. view nodes: event model subclasses. view edgesFrom: #superclass. view treeLayout. view applyLayout ]. node := view node: Collection. view applyLayout. node announce: ROMouseClick. self should: [ view raw elements first announce: ROMouseClick ] raise: Exception.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 14:42'! testEdgesFromAssociation | nodes edges m | nodes := view nodes: #(1 2 3 4). view edges: (Array with: 1 -> 2 with: 2 -> 10 with: 10 -> 3) from: #key to: #value. edges := view root edges. self assert: edges size = 1. self assert: edges first from = nodes first. self assert: edges first to = nodes second.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 21:37'! testEdgesFromTo | edges | view nodes: (1 to: 5). edges := view edgesFrom: 1 to: 2. self assert: edges size = 1. self assert: edges first source model = 1. self assert: edges first target model = 2. self assert: edges first model = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 21:39'! testEdgesFromTo2 | edges | view nodes: (1 to: 5). edges := view edgesFrom: #yourself to: 1. self assert: edges size = 4. self assert: (edges collect: [ :edge | edge from model ]) asArray = #(2 3 4 5). self assert: (edges collect: [ :edge | edge to model ]) asArray = #(1 1 1 1). self assert: (edges collect: [ :edge | edge model ]) asArray = #(2 3 4 5).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 21:40'! testEdgesFromTo3 | edges | view nodes: (1 to: 5). edges := view edges: #edges from: 1 to: 2. self assert: edges size = 1. self assert: edges first source model = 1. self assert: edges first target model = 2. self assert: edges first model = $e.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'TudorGirba 7/29/2012 23:07'! testEdgesFromToHaveNonNilModel | edges | view nodes: #(4 2). edges := view edges: (Array with: 42) from: 4 to: 2. self assert: edges first model = 42! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:30'! testEdgesFromToWithSameModelsAsTheNodes | edges | view nodes: (Array with: 4 with: 2). self shouldnt: [edges := view edges: (Array with: 4 with: 2) from: 4 to: 2] raise: Error. self assert: edges size = 1. self assert: edges first from model = 4. self assert: edges first to model = 2. ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 5/7/2013 15:03'! testEdgesToAll view shape rectangle. view nodes: #(1 2 3). self assert: view edges size equals: 0. view shape arrowedLine. view edgesToAll: #(2). self assert: view edges size equals: 2. (view edges collect: #target) do: [ :eachTarget | self assert: eachTarget model equals: 2 ]. (view edges collect: #source) do: [ :eachSource | self deny: eachSource model = 2 ].! ! !ROMondrianViewBuilderTest methodsFor: 'accessing' stamp: 'AlexandreBergel 12/5/2012 17:20'! testElementFromModel | nodes edges | view shape rectangle size: 30. nodes := view nodes: (Array with: Collection with: Collection superclass). edges := view edgesFrom: #superclass. self assert: edges size = 1. self assert: nodes size = 2. self assert: (view raw elementFromModel: Collection) == nodes first. self assert: (view raw elementFromModel: Collection superclass) == nodes second.! ! !ROMondrianViewBuilderTest methodsFor: 'accessing' stamp: 'AlexandreBergel 12/5/2012 09:35'! testElementsFromModels " self debug: #testElementsFromModels " | container node1To6 node7 nodeInner10To20 node8 nodeInner1To6 | node1To6 := view nodes: (1 to: 6). node7 := view node: 7 forIt: [ nodeInner10To20 := view nodes: (10 to: 20) ]. node8 := view node: 8 forIt: [ nodeInner1To6 := view nodes: (100 to: 106) ]. container := view raw. "Looking up individual nodes" self assert: (container elementFromModel: 1) == node1To6 first. self assert: (container elementFromModel: 7) == node7. self assert: (container elementFromModel: 8) == node8. self assert: (node7 elementFromModel: 7) == node7. self assert: (node7 elementFromModel: 70) isNil. "------" "Group of nodes" "Checking the outter nodes" self assert: (container elementsFromModels: (1 to: 6)) asArray = node1To6. self assert: (container elementsFromModels: (Array with: 7)) asArray first == node7. self assert: (container elementsFromModels: (Array with: 8)) asArray first == node8. "Looking up the inner nodes" self assert: (container elementsFromModels: (10 to: 20)) asArray = nodeInner10To20. "Looking up unexisting nodes" self assert: (container elementsFromModels: (Array with: 2000)) isEmpty ! ! !ROMondrianViewBuilderTest methodsFor: 'layout' stamp: 'AlexandreBergel 5/6/2013 18:05'! testExtensibleSizeWithPaddingGap | element1 element2 | view extensibleSizeWithPaddingGap: 0. element1 := view node: 100 forIt: [ view shape rectangle size: 50. element2 := view node: 10. ]. self assert: element1 padding = (0 @ 0). self assert: element1 width = element2 width. self assert: element1 height = element2 height.! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/14/2012 19:41'! testFillColor | nodes | view shape rectangle fillColor: [ :model | model + 1]. nodes := view nodes: #(2 3 4). self assert: (nodes collect: [ :n | (n getShape: ROBox) colorFor: n]) = #(3 4 5)! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 4/22/2013 19:22'! testFixedSize | variableNode fixedSizedNode | view shape rectangle width: 50; height: 50. variableNode := view node: 'Variable size' forIt: [ view nodes: (1 to: 100). view gridLayout ]. view shape rectangle width: 50; height: 50; fixedSize. fixedSizedNode := view node: 'Fixed size' forIt: [ view nodes: (1 to: 100). view gridLayout ]. self assert: fixedSizedNode resizeStrategy isFixed. self assert: variableNode extent >= (50 @ 50). self assert: fixedSizedNode extent = (50 @ 50).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 6/3/2013 14:58'! testFontColor | model | view shape label fontColor: [ :m | model := m. Color black ]. node := view node: Object. self assert: model == nil. self assert: ((node getShape: ROLabel) colorFor: node) = Color black. self assert: model == Object.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 4/19/2013 16:19'! testFontSize | node | view shape label text: [ :o | o name, ' class']; fontSize: 10. node := view node: Object. self assert: ((node getShape: ROLabel) fontSizeFor: node) = 10.! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'TudorGirba 8/24/2013 22:58'! testForItAndShape | n | view shape rectangle width: [ :v | v ]. view node: 50. view shape rectangle withoutBorder. n := view node: Object new. self assert: n width = view defaultWidth. self assert: n height = view defaultHeight.! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 1/18/2013 14:05'! testForwarding | t outterNode innerNode | t := 0. "Only the outter node should be a forwarder" view interaction forwarder. outterNode := view node: 'outter' forIt: [ innerNode := view node: 'inner'. ]. view raw on: ROEvent do: [ :e | t := t + 1 ]. self assert: t = 0. outterNode announce: ROComponentEvent. self assert: t = 1. "Since the inner node is not declared has a forwarder, it should not forward" innerNode announce: ROComponentEvent. self assert: t = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 4/23/2013 15:54'! testFromInsideToOutside | node1 node2 edge attachPoint points | node1 := view node: 'zork'. view node: 'foo' forIt: [ node2 := view node: 'bar'. view raw add: (edge := ROEdge lineFrom: node1 to: node2). ]. view applyLayout. attachPoint := edge shapes first attachPoint. points := Array with: (10@7) with: (25@12). self assert: (points includes: (attachPoint startingPointOf: edge)). self assert: (points includes: (attachPoint endingPointOf: edge)). node2 translateTo: 100 @ 50. points := Array with: (10@7) with: 5@3. self assert: (points includes: (attachPoint startingPointOf: edge)). points := Array with: 100@52 with: (120@57). self assert: (points includes: (attachPoint endingPointOf: edge)).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 4/23/2013 15:56'! testFromInsideToOutside2 | edge attachPoint edges points | view node: 'foo' forIt: [ view node: 'bar' forIt: [ view nodes: #(1 2). edges := view edgesFrom: 1 to: 2. ] ]. view applyLayout. edge := edges first. attachPoint := edge shapes first attachPoint. points := Array with: (20@17) with: (30@17). self assert: (points includes: (attachPoint startingPointOf: edge)). self assert: (points includes: (attachPoint endingPointOf: edge)). view applyLayout. points := Array with: 20@17 with: 20@18. self assert: (points includes: (attachPoint startingPointOf: edge)). points := Array with: 30@17 with: 30@18. self assert: (points includes: (attachPoint endingPointOf: edge)).! ! !ROMondrianViewBuilderTest methodsFor: 'edges'! testGraph "No error should be raised" view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 9/14/2013 13:10'! testHeight | nodes heightBlock shape | heightBlock := [ :model | model + 1 ]. view shape rectangle height: heightBlock. "self assert: view height == heightBlock." nodes := view nodes: #(2 30 40). shape := nodes first getShape: ROBox. self assert: (shape height roValue: nodes first) = 3. self assert: (shape height roValue: nodes second) = 31. self assert: (nodes collect: [ :n | n height ]) = #(5 31 41)! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 8/27/2013 21:40'! testHighlight | el | view interaction highlightNodesWhenOver: [ :v | { v } ]. view shape rectangle size: 50. view nodes: (1 to: 20). el := view raw elements first. self assert: ((el getShape: ROBox) colorFor: el) = Color white. el announce: ROMouseEnter. self assert: ((el getShape: ROBox) colorFor: el) = Color red. el announce: ROMouseLeave. self assert: ((el getShape: ROBox) colorFor: el) = Color white.! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/14/2012 19:45'! testIfBorderColor | nodes | view shape rectangle if: #odd borderColor: [ :model | model + 1]; if: #even borderColor: [ :model | model + 10]. nodes := view nodes: #(2 3 4 5 6). self assert: (nodes collect: [ :n | (n getShape: ROBox) borderColorFor: n]) = #(12 4 14 6 16)! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/15/2012 10:05'! testIfFillColor | nodes | view shape rectangle if: #odd fillColor: [ :model | model + 1]; if: #even fillColor: [ :model | model + 10]. nodes := view nodes: #(2 3 4 5 6). self assert: (nodes collect: [ :n | (n getShape: ROBox) colorFor: n]) = #(12 4 14 6 16)! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 5/7/2012 11:49'! testIfborderColor | nodes result | view shape rectangle if: #odd borderColor: Color red; if: #even borderColor: Color blue. nodes := view nodes: #(1 2 3 4). result := ((Array new: 4) at: 1 put: Color red; at: 2 put: Color blue; at: 3 put: Color red; at: 4 put: Color blue; yourself). self assert: (nodes collect: [ :n | (n getShape: ROBox) borderColorFor: n]) = result! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 6/9/2012 15:17'! testInitialization | builder | builder := ROMondrianViewBuilder new. self assert: (builder raw class == ROView)! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 6/9/2012 15:17'! testInitializationWithView | builder v | v := ROView new. builder := ROMondrianViewBuilder titled: 'hello' view: v . self assert: (builder raw == v). self assert: (builder raw class == ROView).! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 12/11/2012 12:34'! testInnerNodesAndEvents | outter inner inner2 | outter := view node: 'outter' forIt: [ inner := view node: 'inner' forIt: [ inner2 := view node: 'inner2' ] ]. view applyLayout. self assert: (view raw elementAt: outter absolutePosition) == outter. self assert: (view raw elementAt: inner absolutePosition) == inner. self assert: (view raw elementAt: inner2 absolutePosition) == inner2. self assert: (view raw elementAtRealPosition: outter absolutePosition) == outter. self assert: (view raw elementAtRealPosition: inner absolutePosition) == inner. self assert: (view raw elementAtRealPosition: inner2 absolutePosition) == inner2. self assert: (view raw elementAtRealPosition: 18@18) == inner2. "We simulate a drag and drop" outter translateTo: 67@32. self assert: (view raw elementAtRealPosition: 80@45) == inner2. ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 12/11/2012 12:35'! testInnerNodesAndLayout | nodes | nodes := view nodes: #(1 10) forEach: [ :v | view nodes: (Array with: v +1 with: v + 2) ]. view applyLayout. self assert: (nodes collect: #bounds) = (Array with: (5@5 corner: 35@20) with: (45@5 corner: 75@20)). self assert: (nodes first elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (20@5 corner: 25@10)). self assert: (nodes second elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (20@5 corner: 25@10)) ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 12/11/2012 12:37'! testInnerNodesAndLayout2 | nodes | nodes := view nodes: #(1 10) forEach: [ :v | view nodes: (Array with: v +1 with: v + 2). view verticalLineLayout ]. view applyLayout. self assert: (nodes collect: #bounds) = (Array with: (5@5 corner: 20@35) with: (30@5 corner: 45@35)). self assert: (nodes first elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (5@20 corner: 10@25)). self assert: (nodes second elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (5@20 corner: 10@25)) ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 12/11/2012 12:37'! testInnerNodesAndLayout3 | nodes | nodes := view nodes: #(1 10) forEach: [ :v | view nodes: (Array with: v+ 1 with: v +2). ]. view verticalLineLayout. view applyLayout. self assert: (nodes collect: #bounds) = (Array with: (5@5 corner: 35@20) with: (5@30 corner: 35@45)). self assert: (nodes first elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (20@5 corner: 25@10)). self assert: (nodes second elementsCollect: #bounds) asArray = (Array with: (5@5 corner: 10@10) with: (20@5 corner: 25@10)) ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'DR 1/15/2013 21:21'! testInnerNodesAndLayout4 | nodes | nodes := view nodes: #(1 10) forEach: [ :v | view nodes: (Array with: v +1 with: v + 2 with: v + 3). view shape line. view edgesFrom: [ :el | v + 1 ]. view treeLayout ]. view horizontalLineLayout. view applyLayout. "Sanity check begin" self deny: ((nodes second elementFromModel: 13) isShapedAs: ROLine). self assert: (nodes first elementsSuchThat: #isEdge) size = 2. "Sanity check end" self assert: (nodes collect: #bounds) = (Array with: (5@5 corner: 28.0@45) with: (38.0@5 corner: 61.0@45)). self assert: (((Array new: 5) at: 1 put: (9.0@5 corner: 14.0@10); at: 2 put: (5.0@30 corner: 10.0@35); at: 3 put: (13.0@30 corner: 18.0@35); at: 4 put: (0@0 corner: 5@5); at: 5 put: (0@0 corner: 5@5); yourself) includesAll: (nodes first elementsNotEdge collect: #bounds) asArray). self assert: (((((Array new: 5) at: 1 put: (9.0@5 corner: 14.0@10); at: 2 put: (5.0@30 corner: 10.0@35); at: 3 put: (13.0@30 corner: 18.0@35); at: 4 put: (0@0 corner: 5@5); at: 5 put: (0@0 corner: 5@5); yourself))) includesAll: (nodes second elementsNotEdge collect: #bounds) asArray)! ! !ROMondrianViewBuilderTest methodsFor: 'interaction'! testInteraction | t nodes | t := OrderedCollection new. view interaction item: 'act' action: [ :v | t add: t ]. nodes := view nodes: #(1 2). ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'AlexandreBergel 4/11/2013 14:08'! testInteraction1 " self debug: #testInteraction1 " | nodes firstNode | view interaction highlightWhenOver: [ :e | (Array with: 123) ]. view shape rectangle size: 60; fillColor: Color green. nodes := view nodes: #(123 456 789). firstNode := nodes first. self assert: ((firstNode getShape: ROBox) colorFor: firstNode) = Color green. nodes first announce: ROMouseEnter. self assert: ((firstNode getShape: ROBox) colorFor: firstNode) = Color red. nodes first announce: ROMouseLeave. self assert: ((firstNode getShape: ROBox) colorFor: firstNode) = Color green.! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'AlexandreBergel 10/15/2012 10:03'! testInteraction2 " self debug: #testInteraction2 " | nodes firstNode | view node: 'foo' forIt: [ view interaction highlightWhenOver: [ :e | (Array with: 123) ]. view shape rectangle size: 60; fillColor: Color green. nodes := view nodes: #(123 456 789) ]. firstNode := nodes first. self assert: ((firstNode getShape: ROShape) colorFor: firstNode) = Color green. nodes first announce: ROMouseEnter. self assert: ((firstNode getShape: ROShape) colorFor: firstNode) = Color red. nodes first announce: ROMouseLeave. self assert: ((firstNode getShape: ROShape) colorFor: firstNode) = Color green. ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'TudorGirba 10/18/2012 09:36'! testInteraction2HighlightWhenOver " self debug: #testInteraction2HighlightWhenOver " | nodes shape1 shape2 t aNode node5 node2 | t := 0. view interaction highlightWhenOver: [ :v | t := t + 1. ((Array new: 4) at: 1 put: v - 1; at: 2 put: v + 1; at: 3 put: v + 4; at: 4 put: v - 4; yourself)]. view interaction highlightWhenOver: [ :v | Array with: v ] color: Color blue. view shape rectangle width: 40; height: 30. nodes := view nodes: (1 to: 16). view gridLayout gapSize: 2. aNode := nodes first. node5 := nodes fifth. node2 := nodes second. shape1 := aNode getShape: ROBox. self assert: (shape1 borderColor == Color black). nodes first announce: (ROMouseEnter new). self assert: (aNode getShape: ROBox) == shape1. self assert: (shape1 color = Color blue). shape2 := aNode getShape: ROBox. self assert: (t = 1). self assert: (shape1 == shape2). self assert: ((node2 getShape: ROBox) color = Color red). self assert: ((node5 getShape: ROBox) color = Color red). nodes first announce: (ROMouseLeave new). self assert: ((Array with: aNode with: node2 with: node5) allSatisfy: [ :n | ((n getShape: ROBox) colorFor: n) = Color white ]). ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'TudorGirba 10/18/2012 09:36'! testInteraction2HighlightWhenOverOnInnerNodes " self debug: #testInteraction2HighlightWhenOverOnInnerNodes " | nodes shape1 shape2 t aNode node5 node2 | t := 0. view node: 'outterNode' forIt: [ view interaction highlightWhenOver: [ :v | t := t + 1. ((Array new: 4) at: 1 put: v - 1; at: 2 put: v + 1; at: 3 put: v + 4; at: 4 put: v - 4; yourself)]. view interaction highlightWhenOver: [ :v | Array with: v ] color: Color blue. view shape rectangle width: 40; height: 30. nodes := view nodes: (1 to: 16). view gridLayout gapSize: 2 ]. aNode := nodes first. node5 := nodes fifth. node2 := nodes second. shape1 := aNode getShape: ROBox. self assert: (shape1 borderColor == Color black). nodes first announce: (ROMouseEnter new). self assert: (aNode getShape: ROBox) == shape1. self assert: (shape1 color = Color blue). shape2 := aNode getShape: ROBox. self assert: (t = 1). self assert: (shape1 == shape2). self assert: ((node2 getShape: ROBox) color = Color red). self assert: ((node5 getShape: ROBox) color = Color red). nodes first announce: (ROMouseLeave new). self assert: ((Array with: aNode with: node2 with: node5) allSatisfy: [ :n | ((n getShape: ROBox) colorFor: n) == Color white ]). ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'AlexandreBergel 7/4/2012 00:10'! testInteraction3 " self debug: #testInteraction2 " | nodes firstNode shape secondNode | view node: 'foo' forIt: [ view interaction highlightWhenOver: [ :e | (Array with: 123) ]. view shape rectangle size: 60; if: true fillColor: Color green. nodes := view nodes: #(123 456 789) ]. firstNode := nodes first . secondNode := nodes second . shape := firstNode getShape: ROShape. self assert: (shape color roValue: firstNode) = Color green. firstNode announce: ROMouseEnter. self assert: (shape color roValue: firstNode) = Color red. firstNode announce: ROMouseLeave. self assert: (shape color roValue: firstNode) = Color green. "----" self assert: (shape color roValue: firstNode) = Color green. secondNode announce: ROMouseEnter. self assert: (shape color roValue: firstNode) = Color red. secondNode announce: ROMouseLeave. self assert: (shape color roValue: firstNode) = Color green. ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction updating' stamp: 'AlexandreBergel 4/11/2013 12:56'! testInteraction4 " self debug: #testInteraction4 " | firstNode shape secondNode nodes1 nodes2 firstShape secondShape | view node: 'foo' forIt: [ view interaction highlightWhenOver: [ :e | Array with: 123 with: 123 ]. view shape rectangle size: 60; if: true fillColor: Color green. nodes1 := view nodes: #(456 789) ]. view node: 'bar' forIt: [ view shape rectangle size: 60; if: true fillColor: Color green. nodes2 := view nodes: #(123) ]. firstNode := nodes1 first . secondNode := nodes2 first . firstShape := firstNode getShape: ROBox. secondShape := secondNode getShape: ROBox. "----" self assert: (secondShape color roValue: secondNode) = Color green. firstNode announce: ROMouseEnter. self assert: (secondShape color roValue: secondNode) = Color red. firstNode announce: ROMouseLeave. self assert: (secondShape color roValue: secondNode) = Color green. ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 1/1/2013 13:12'! testItemAction | t nodes menuActivable block | t := OrderedCollection new. view interaction item: 'foo' action: [ :aModelObject | t add: aModelObject ]. nodes := view nodes: (1 to: 5). menuActivable := nodes first getInteraction: ROMenuActivable. block := (menuActivable actionNamed: 'foo'). block value value: nodes first. self assert: t size = 1. self assert: t first == nodes first model ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 5/6/2013 17:57'! testLabel | builder element | builder := ROMondrianViewBuilder titled: 'Finding nodes'. builder shape label. node := builder node: 'hello'. self assert: ((node getShape: ROLabel) textFor: node) = 'hello'. view := builder raw. self assert: view numberOfElements = 1. element := view elementDetect: [ :el | true ]. self assert: (element isShapedAs: ROLabel). self assert: node bounds extent = (ROLabel new preferedExtentFor: node)! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 4/2/2013 16:15'! testLabelLinearFontSize "MOViewRendererTest>>testLabel1" | nodes | view shape label linearFontSize: #yourself within: (1 to: 40). nodes := view nodes: (1 to: 40). window := view open. self assert: (((nodes at: 10) getShape: ROLabel) fontSizeFor: (nodes at: 10)) = 14. self assert: (((nodes at: 20) getShape: ROLabel) fontSizeFor: (nodes at: 20)) = 24. ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'TudorGirba 10/18/2012 09:34'! testLabelText | node | view shape label text: [:o | o name, ' class']. node := view node: Object. self assert: ((node getShape: ROLabel) textFor: node) = 'Object class'.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 12/11/2012 12:37'! testLabelWithTwoNodes "Just to make sure that the view does not initialize a shape that later stays one" | node1 node2 | view shape label text: #printString. node1 := view node: Object. self assert: (node1 shapes size = 2). view shape label text: #printString. node2 := view node: Object. self assert: (node1 shapes size = 2)! ! !ROMondrianViewBuilderTest methodsFor: 'layout' stamp: 'AlexandreBergel 4/23/2013 15:14'! testLayoutAfterRemoveAndAddNode |result| view nodes: (1 to: 4). view gridLayout. view applyLayout . result := ((Array new: 4) at: 1 put: ((5@5)); at: 2 put: ((14@5)); at: 3 put: ((5@14)); at: 4 put: ((14@14)); yourself). self assert: ((view raw elements collect: #position) = result). view removeNodes: (2 to: 4). view nodes: (2 to: 4). view gridLayout. view applyLayout. self assert: ((view raw elements collect: #position) = result).! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 9/28/2012 11:24'! testLinearFillColor self shouldnt: [view shape rectangle linearFillColor: #foo within: #(). view nodes: #()] raise: Error.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 6/12/2013 12:11'! testLinearFillColor2 | nodes colors | view shape rectangle linearFillColor: #yourself within: #(0 0 0); size: 50. nodes := view nodes: #(0 0 0). self assert: nodes size = 3. colors := (nodes collect: [ :e | (e getShape: ROBox) colorFor: e ]) asSet. self assert: colors size = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 6/12/2013 12:11'! testLinearFillColor3 | nodes colors | view shape rectangle linearFillColor: #yourself within: #(1 2 3); size: 50. nodes := view nodes: #(1 2 3). self assert: nodes size = 3. colors := (nodes collect: [ :e | (e getShape: ROBox) colorFor: e ]) asSet. self assert: colors size = 3.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 6/12/2013 17:45'! testLinearFillColor4 | nodes colors colorsAfter | "We compute the colors" view shape rectangle linearFillColor: #yourself within: #(1 2 3). nodes := view nodes: #(1 2 3). colors := nodes collect: [ :e | (e getShape: ROBox) colorFor: e ]. "We do the same view, but we do not use the within: clause" view shape rectangle linearFillColor: #yourself. nodes := view nodes: #(1 2 3). colorsAfter := nodes collect: [ :e | (e getShape: ROBox) colorFor: e ]. "The two should be the same" self assert: colors = colorsAfter! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/18/2012 09:48'! testLogHeight | nodes | view shape rectangle logHeight: [ :model | model + 1]. nodes := view nodes: #(2 30 40). (nodes do: [ :n | self assert: n height class == Float ]) ! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/18/2012 09:49'! testLogWidth | nodes | view shape rectangle logWidth: [ :model | model + 1]. nodes := view nodes: #(2 30 40). (nodes do: [ :n | self assert: n width class == Float ]) ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction'! testMenu | nodes | view node: 30 forIt: [ view interaction action: #inspect; action: #foo; action: #bar. nodes := view nodes: (1 to: 20) ]. self assert: (nodes first getInteraction: ROMenuActivable) numberOfEntries = 3! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 4/23/2013 15:25'! testMouseEvent | nodes thirdNode secondNode | nodes := view nodes: (1 to: 3) forEach: [ :v | view nodes: (1 to: 30). view gridLayout. ]. "For debugging purpose" view raw on: ROMouseClick do: [ :event | event inspect ]. " view open " view applyLayout. thirdNode := nodes third. secondNode := nodes second. self assert: (thirdNode model = 3). self assert: (thirdNode bounds = ( (145@5) corner: (205@56))). self assert: (thirdNode bounds containsPoint: (166@49)). self assert: (thirdNode contains: 166 @ 49). self assert: (secondNode bounds = ( (75@5) corner: (135@56))). self deny: (secondNode bounds containsPoint: (166@49)). self assert: (91@44) = (166@49 - secondNode topLeft). self deny: (secondNode shapes first boundsFor: secondNode containsPoint: 94@44). self deny: (secondNode shapes second boundsFor: secondNode containsPoint: 94@44). self deny: (secondNode contains: (166 @ 49)). self assert: (view raw elementAt: (166@49)) == nodes third. ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 9/10/2012 09:09'! testNesting | firstNode | view nodes: (1 to: 20) forEach: [ :v | view nodes: (1 to: 2) ]. view applyLayout. firstNode := (view raw elementsSuchThat: [:el | el model = 1]) first. self assert: firstNode extent = (30@15) ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 7/25/2012 10:08'! testNestingForIt | firstNode | view node: 123 forIt: [ view nodes: (1 to: 2). ]. view applyLayout. firstNode := (view raw elementsSuchThat: [:el | el model = 123]) first. self assert: firstNode extent = ( 30@15) ! ! !ROMondrianViewBuilderTest methodsFor: 'inner nodes' stamp: 'AlexandreBergel 7/25/2012 10:09'! testNestingWithExplicitLayout | firstNode | view nodes: (1 to: 20) forEach: [ :v | view nodes: (1 to: 2) . view treeLayout ]. view applyLayout. self assert: (view raw numberOfElements = 20). firstNode := (view raw elementsSuchThat: [:el | el model = 1]) first. self assert: firstNode numberOfElements = 2. self assert: firstNode extent = ( 23@15). ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 6/9/2012 15:17'! testNilKeyOrValue " self debug: #testNilKeyOrValue " view nodes: #(1 2). view edgesFromAssociations: (Array with: 1 -> 2 with: nil -> 2 with: 1 -> nil). view edgeFromAssociation: nil -> nil. view edges: #(1 2) from: #yourself to: [ :v | nil ]. view edges: #(1 2) from: [ :v | nil ] to: [ :v | nil ]. view edges: #(1 2) from: [ :v | nil ] to: #yourself. self assert: (view root raw elementsSuchThat: [ :n | n class == ROElement ]) size = 2. self assert: (view root raw elementsSuchThat: [ :n | n class == ROEdge ]) size = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 4/30/2012 19:58'! testNoDraggable | el b | view interaction nodraggable. el := view node: 123. b := el position. self deny: (el is: RODraggable). el announce: (ROMouseDragging step: 40@50). self assert: el position = b! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 7/6/2012 14:15'! testNoPopup | el1 el2 el3 | view interaction noPopup. el1 := view node: 1. el2 := view node: 2. view interaction noPopup. el3 := view node: 3. self deny: (el1 is: ROPopupView). self assert: (el2 is: ROPopupView). self deny: (el3 is: ROPopupView).! ! !ROMondrianViewBuilderTest methodsFor: 'statusbar' stamp: 'AlexandreBergel 5/31/2013 13:51'! testNoStatusBar view nodes: (1 to: 4). self assert: view stack numberOfElements = 0. self assert: view stack firstView numberOfElements = 4 ! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 5/25/2013 17:58'! testNumberOfDefinedInteractions self assert: view interaction numberOfDefinedInteractions = 1! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 5/25/2013 17:58'! testNumberOfDefinedInteractions2 view nodes: (1 to: 20). self assert: view interaction numberOfDefinedInteractions = 1. ! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 5/25/2013 17:58'! testNumberOfDefinedInteractions3 view interaction action: #inspect. self assert: view interaction numberOfDefinedInteractions = 2. view nodes: (1 to: 20). self assert: view interaction numberOfDefinedInteractions = 1. ! ! !ROMondrianViewBuilderTest methodsFor: 'initializing' stamp: 'AlexandreBergel 5/25/2013 17:59'! testNumberOfDefinedInteractions4 view interaction if: #odd popupText: 'hello'; if: #even popupText: 'world'. self assert: view interaction numberOfDefinedInteractions = 3. view nodes: (1 to: 20). self assert: view interaction numberOfDefinedInteractions = 1. ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 6/9/2012 15:17'! testOddLine view node: 4. view edges: (Array with: 4) from: #yourself toAll: [ :m | #() ]. self assert: view root raw numberOfElements = 1.! ! !ROMondrianViewBuilderTest methodsFor: 'open' stamp: 'AlexandreBergel 11/30/2012 16:17'! testOpenInWindowSized [ window := view openInWindowSized: 400@30. self assert: window extent >= (400@30).] ensure: [ window delete ]! ! !ROMondrianViewBuilderTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 15:17'! testOverlappingObjects | canvas | view shape rectangle size: 30. view node: 'foo'. view shape circle size: 30; fillColor: Color blue. view node: 'bar'. view noLayout. canvas := ROTracingCanvas new. view raw drawOn: canvas. self assert: canvas trace = #( #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@30)' 'Color white' 1 'Color black') #(#fillOval: '(0@0) corner: (30@30)' 1 'Color blue')) ! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 7/6/2012 14:15'! testPopupOnInnerInnerNodes | node1 node2 node3 | node1 := view node: 1 forIt: [ node2 := view node: 2 forIt: [ node3 := view node: 3 forIt: [ ] ] ]. self assert: (node1 is: ROPopupView). self assert: (node2 is: ROPopupView). self assert: (node3 is: ROPopupView).! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 6/2/2012 17:42'! testPopupView | t el | t := false. view interaction popupView: [ :myView :ell | t := true ] delay: 0. el := view node: 'hello'. el announce: ROMouseEnter. self assert: t! ! !ROMondrianViewBuilderTest methodsFor: 'interaction' stamp: 'AlexandreBergel 9/14/2013 13:10'! testPopupViewSize | el popup elRef | view interaction popupView: [ :ell :myView | myView shape rectangle fillColor: Color blue. myView node: '' forIt: [ myView node: 'world' ] ] delay: 0. el := view node: 'hello'. elRef := view node: 'h' forIt: [ view node: 'w' ]. view applyLayout. self assert: view stack numberOfElements = 0. el announce: ROMouseEnter. self assert: view stack numberOfElements = 1. popup := view stack elements first. self assert: popup extent = (21 @ 21).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 12/6/2012 16:53'! testPopupWithEdges2 | rawView nodes firstNode secondNode virtualPoint outterNode edge | outterNode := view node: 'foo' forIt: [ nodes := view nodes: #(1 2). edge := view edge: 1 from: 1 to: 2. view treeLayout. ]. view applyLayout. " view open. " self assert: (view raw elementAt: 14 @ 39) == nodes second. ! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'AlexandreBergel 7/25/2012 10:09'! testPositionRelativeTo | outterNode1 innerNode1 innerNode2 innerNode3 | outterNode1 := view node: 'outter1' forIt: [ innerNode1 := view node: 1 forIt: [ innerNode2 := view node: 2] ]. view applyLayout. self assert: innerNode2 bounds = ( (5@5) corner: (10@10) ). self assert: (innerNode2 positionRelativeTo: innerNode2) = (0 @ 0). self assert: (innerNode2 positionRelativeTo: innerNode1) = innerNode2 topLeft. self assert: (innerNode2 positionRelativeTo: outterNode1) = (innerNode2 topLeft + innerNode1 topLeft).! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:32'! testRawEdgesFrom | nodes edges ass m assoc | nodes := view nodes: #(1 2 3 4). self assert: view raw numberOfElements = 4. assoc := 1 -> 2. edges := view rawEdges: (Array with: assoc) from: #key to: #value. self assert: edges size = 1. self assert: edges first from = nodes first. self assert: edges first to = nodes second.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:33'! testRawEdgesFrom2 | nodes edges assoc | nodes := view nodes: #(1 2 3 4). self assert: view raw numberOfElements = 4. assoc := 1 -> 1. edges := view rawEdges: (Array with: assoc) from: #key to: #value. self assert: edges size = 0.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 15:46'! testRawEdgesFromTo | edges assoc | view nodes: #(1 2 3 4). self assert: view raw numberOfElements = 4. assoc := 1 -> 2. edges := view rawEdges: (Array with: assoc) from: #key to: #value. self assert: edges size equals: 1. self assert: edges first from model equals: 1. self assert: edges first to model equals: 2. self assert: edges first model = assoc.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:38'! testRawEdgesFromTo2 | edges assoc | view nodes: #(1 2 3 4). self assert: view raw numberOfElements = 4. assoc := 1 -> 1. edges := view rawEdges: (Array with: assoc) from: #key to: #value. self assert: edges size equals: 0.! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 5/6/2013 13:50'! testRawEdgesToAll | edges | view nodes: #(1 2 3 4). self assert: view raw numberOfElements = 4. edges := view rawEdgesToAll: #(1 2 3 4). self assert: edges size equals: 12. edges do: [ :eachEdge | self deny: eachEdge source == eachEdge target ].! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 5/22/2012 18:43'! testRectangleWithText view shape rectangle withText: [ :v | v ]. view node: Object. ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:15'! testRemoveAllEdgesFromNode view nodes: (1 to: 2). view edgesFromAssociations: (Array with: 1->2). self assert: (view raw numberOfElements = 3). view removeAllEdgesFrom: 1. self assert: (view raw numberOfElements = 2). ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:37'! testRemoveAllEdgesFromNodes view nodes: (1 to: 3). view edgesFromAssociations: (Array with: 2->1 with: 3->2). self assert: (view raw numberOfElements = 5). view removeAllEdgesFromNodes: (2 to: 3). self assert: (view raw numberOfElements = 3). ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:30'! testRemoveAllEdgesToNode view nodes: (1 to: 2). view edgesFromAssociations: (Array with: 2->1). self assert: (view raw numberOfElements = 3). view removeAllEdgesTo: 1. self assert: (view raw numberOfElements = 2). ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:36'! testRemoveAllEdgesToNodes view nodes: (1 to: 3). view edgesFromAssociations: (Array with: 2->1 with: 3->2). self assert: (view raw numberOfElements = 5). view removeAllEdgesToNodes: (1 to: 2). self assert: (view raw numberOfElements = 3). ! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 12:47'! testRemoveAndAddNode view nodes: (1 to: 4). self assert: view raw numberOfElements = 4. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 4. view removeNodes: (2 to: 4). self assert: view raw numberOfElements = 1. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 1. view nodes: (2 to: 4). self assert: view raw numberOfElements = 4. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 4. ! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 10:49'! testRemoveNode |node| node := view node: 1. self assert: (view raw numberOfElements = 1). self assert: ((view elementFromModel: 1) = node). view removeNode: 1. self assert: (view raw numberOfElements = 0). ! ! !ROMondrianViewBuilderTest methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 10:53'! testRemoveNodes view nodes: (1 to: 3). self assert: (view raw numberOfElements = 3). view removeNodes: (1 to: 3). self assert: (view raw numberOfElements = 0). ! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'JurajKubelka 6/3/2013 21:40'! testShapeAndEdges | edges | view nodes: (1 to: 5). view shape line color: Color blue. edges := view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. self assert: edges size = 5. edges do: [ :edge | self assert: ((edge getShape: ROLine) colorFor: edge) = Color blue. ] ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes'! testShapeAreProperlyInitialized | node1 node2 | view shape rectangle width: 20. node1 := view node: 123. self assert: node1 bounds width = 20. node2 := view node: 1234. self assert: node1 bounds width = 20. self assert: node2 bounds width = 5.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/17/2012 13:46'! testSize | element | view shape rectangle size: 30. element := view node: 'hello'. self assert: element extent = (30 @ 30)! ! !ROMondrianViewBuilderTest methodsFor: 'statusbar' stamp: 'AlexandreBergel 5/31/2013 17:51'! testStatusBar | nodes statusBar | statusBar := view interaction statusBar: [ :aNumber | aNumber + 10 ]. nodes := view nodes: (1 to: 4). self assert: view stack numberOfElements = 1. self assert: view stack firstView numberOfElements = 4. nodes first announce: ROMouseEnter. self assert: (statusBar getShape: ROLabel) text = '11'. nodes first announce: ROMouseLeave. self assert: (statusBar getShape: ROLabel) text = '11'. nodes second announce: ROMouseEnter. self assert: (statusBar getShape: ROLabel) text = '12' ! ! !ROMondrianViewBuilderTest methodsFor: 'statusbar' stamp: 'AlexandreBergel 5/31/2013 15:21'! testStatusBarWithEdge | nodes statusBar edges | statusBar := view interaction statusBar: [ :t4 | t4 + 10]. nodes := view nodes: (1 to: 4). view interaction statusBar: [ :assoc | assoc key + 20]. edges := view edgesFromAssociations: (Array with: 1 -> 2). self assert: view stack numberOfElements = 1. self assert: view stack firstView numberOfElements = 5. nodes first announce: ROMouseEnter. self assert: (statusBar getShape: ROLabel) text = '11'. edges first announce: ROMouseEnter. self assert: (statusBar getShape: ROLabel) text = '21'! ! !ROMondrianViewBuilderTest methodsFor: 'layout' stamp: 'AlexandreBergel 7/25/2012 10:09'! testSugiyamaLayout | nodes result | view node: 'foo' forIt: [ view node: 'foo' forIt: [ nodes := view nodes: (1 to: 5). view edgesFromAssociations: (Array with: 1 -> 2 with: 3 -> 5 with: 2-> 5). view sugiyamaLayout ] ]. view applyLayout. result := ((Array new: 5) at: 1 put: ((24.0@3.0) corner: (29.0@8.0)); at: 2 put: ((20.0@28.0) corner: (25.0@33.0)); at: 3 put: ((28.0@28.0) corner: (33.0@33.0)); at: 4 put: ((28.0@53.0) corner: (33.0@58.0)); at: 5 put: ((20.0@53.0) corner: (25.0@58.0)); yourself). self assert: (nodes collect: #bounds) = result.! ! !ROMondrianViewBuilderTest methodsFor: 'instantiating' stamp: 'AlexandreBergel 5/17/2012 20:53'! testTitle | builder | builder := ROMondrianViewBuilder titled: 'hello world'. window := builder open. [ self assert: window labelString = 'hello world'. ] ensure: [ window delete ]! ! !ROMondrianViewBuilderTest methodsFor: 'edges' stamp: 'AlexandreBergel 6/12/2013 06:14'! testTwiceDefiningEdges view nodes: (1 to: 20). view shape line color: [ :edge | (edge from model = 2) ifTrue: [ Color red. ] ifFalse: [ Color lightGray ] ]. view edgeFromAssociation: 2 -> 18. self shouldnt: [view edgesToAll: [ :v | Array with: v + 3 with: v + 5 with: v *2 ] ] raise: Error! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/14/2012 19:43'! testWidth | nodes | view shape rectangle width: [ :model | model + 1]. nodes := view nodes: #(2 30 40). self assert: (nodes collect: [ :n | n width ]) = #(5 31 41)! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'AlexandreBergel 10/23/2012 09:00'! testWithBorderWidth "Related to http://code.google.com/p/objectprofile/issues/detail?id=198" | classesToDraw | classesToDraw := Collection withAllSubclasses. view shape rectangle borderWidth: 1; borderColor: Color blue. view nodes: classesToDraw. view gridLayout. self shouldnt: [ view raw drawOn: RONullCanvas new ] raise: Error ! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 5/27/2013 20:21'! testWithCenteredText view shape rectangle withCenteredText. node := view node: Object. self assert: ((node getShape: ROCenteredLabel) textFor: node) = 'Object'.! ! !ROMondrianViewBuilderTest methodsFor: 'shapes' stamp: 'JurajKubelka 5/27/2013 20:21'! testWithCenteredText2 view shape rectangle withCenteredText: [:o | o name, ' class']. node := view node: Object. self assert: ((node getShape: ROCenteredLabel) textFor: node) = 'Object class'.! ! !ROMondrianViewBuilderTest methodsFor: 'using model' stamp: 'AlexandreBergel 10/15/2012 10:12'! testWithText | nodes | view shape rectangle withText: [ :model | model + 1]. nodes := view nodes: #(2 30 40). self assert: (nodes collect: [ :n | (n getShape: ROLabel) textFor: n]) = #('3' '31' '41')! ! !ROMondrianViewBuilderTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/10/2012 19:11'! testZOrderingAndNesting "(ROZOrdering new at: [:edge | ((edge source depth * 2) max: (edge target depth * 2)) - 1 ] put: #isEdge; at: [ :element | element depth * 2 ] put: #isNotEdge)." | map | view node: 1 forIt: [ view node: 11 ]. view node: 2 forIt: [ view node: 22 ]. view node: 3 forIt: [ view node: 33 ]. view edgeFromAssociation: 11 -> 33. map := OrderedCollection new add: 1 -> 2; add: 11 -> 4; add: 2 -> 2; add: 22 -> 4; add: 3 -> 2; add: 33 -> 4; yourself. self assert: (view elementFromModel: 11) parent == (view raw elementFromModel: 1). self assert: view zOrdering numberOfEntries = 2. map do: [ :assoc | self assert: (view elementFromModel: assoc key) zIndex = assoc value ]. self assert: (view edgeFromModel: (11 -> 33)) zIndex = 3 ! ! !ROMondrianViewBuilderTest methodsFor: 'nodes'! testlookup | nodes | nodes := view nodes: #(1 2 3 4). self assert: (view lookup: 1) == nodes first. self assert: (view lookup: 4) == nodes fourth. self assert: (view lookup: 6) == nil! ! !ROMorphTest methodsFor: 'util' stamp: 'AlexandreBergel 4/14/2013 12:01'! keyboardEvent | evt | evt := KeyboardEvent new. evt setType: #keystroke buttons: 0 position: 0@0 keyValue: 0 charCode: 0 hand: nil stamp: Time now. ^ evt ! ! !ROMorphTest methodsFor: 'util' stamp: 'AlexandreBergel 4/14/2013 12:01'! mouseEvent | mouseEvent | mouseEvent := MouseButtonEvent new. mouseEvent setHand: (HandMorph new). mouseEvent setType: nil position: 2@3 which: MouseEvent blueButton buttons: MouseEvent blueButton hand: nil stamp: Time now. mouseEvent setPosition: 50 @ 30. ^ mouseEvent! ! !ROMorphTest methodsFor: 'running' stamp: 'AlexandreBergel 5/7/2012 11:54'! setUp "We initialize a simple scene" node1 := ROElement on: 'hello'. node1 extent: 40 @ 30. node1 addShape: (ROBox new color: Color yellow); addShape: ROBorder new. node2 := ROElement on: 'hello'. node2 extent: 40 @ 30. node2 addShape: (ROBox new color: Color green). node2 translateBy: 100@30. view := ROView new. view addAll: {node1 . node2}. morph := ROMorph on: view. "We initialize simple events" mouseEventOnNode1 := MouseButtonEvent new. mouseEventOnNode1 setHand: (HandMorph new). mouseEventOnNode1 setType: nil position: 2@3 which: MouseEvent blueButton buttons: MouseEvent blueButton hand: nil stamp: Time now. mouseEventOnNode1 setPosition: (morph canvas virtualToRealPoint: node1 bounds center). mouseEventOnNode2 := MouseButtonEvent new. mouseEventOnNode2 setHand: (HandMorph new). mouseEventOnNode2 setType: nil position: 2@3 which: MouseEvent blueButton buttons: MouseEvent blueButton hand: nil stamp: Time now. "mouseEventOnNode2 setType: nil position: 2@3 buttons: MouseEvent blueButton hand: nil." mouseEventOnNode2 setPosition: (morph canvas virtualToRealPoint: node2 bounds center). mouseEventWithoutButton := MouseButtonEvent new. mouseEventWithoutButton setHand: (HandMorph new). mouseEventWithoutButton setType: nil position: 2@3 which: MouseEvent blueButton buttons: MouseEvent blueButton hand: nil stamp: Time now. mouseEventWithoutButton setPosition: (morph canvas virtualToRealPoint: node2 bounds center). ! ! !ROMorphTest methodsFor: 'running'! tearDown window ifNotNil: [ window delete ]! ! !ROMorphTest methodsFor: 'bitmap' stamp: 'AlexandreBergel 9/10/2012 09:40'! testBitmapSize self assert: morph bounds extent = view defaultWindowSize. self assert: morph bitmap extent = (500@500) ! ! !ROMorphTest methodsFor: 'bitmap' stamp: 'AlexandreBergel 9/10/2012 10:03'! testBitmapSize2 self assert: ROView new bitmap extent = (ROView new defaultWindowSize)! ! !ROMorphTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/17/2012 20:54'! testClickingScenario | counter | counter := 0. node1 on: ROMouseClick do: [ :evt | counter := counter + 1 ]. node2 on: ROMouseClick do: [ :evt | counter := counter + 10 ]. self assert: counter = 0. morph roMouseClick: mouseEventOnNode1. self assert: counter = 1. morph roMouseClick: mouseEventOnNode1. self assert: counter = 2. morph roMouseClick: mouseEventOnNode2. self assert: counter = 12. morph roMouseClick: mouseEventOnNode2. self assert: counter = 22. ! ! !ROMorphTest methodsFor: 'tests'! testDragging mouseEventOnNode1 setPosition: (morph canvas virtualToRealPoint: node1 bounds center). mouseEventOnNode1 setHand: (HandMorph new). morph mouseDown: mouseEventOnNode1. mouseEventOnNode2 setPosition: (morph canvas virtualToRealPoint: node2 bounds center + (5 @ 5)). mouseEventOnNode2 setHand: (HandMorph new). morph mouseDown: mouseEventOnNode2. self assert: (node1 bounds = (0@0 corner: 40@30))! ! !ROMorphTest methodsFor: 'tests'! testElementForEvent self assert: (morph elementForEvent: mouseEventOnNode1) == node1. self assert: (morph elementForEvent: mouseEventOnNode2) == node2. ! ! !ROMorphTest methodsFor: 'tests'! testGeneratingBitmap self assert: morph bitmap bits = (view bitmapForRealSize: morph extent) bits! ! !ROMorphTest methodsFor: 'tests'! testHandleMouseDown self assert: (morph handlesMouseDown: (MouseEvent new wasHandled: false; yourself) )! ! !ROMorphTest methodsFor: 'bitmap' stamp: 'AlexandreBergel 9/10/2012 09:40'! testImageForm "Used when you try to export the morph in a .png file" self assert: morph imageForm extent = (500 @ 500) ! ! !ROMorphTest methodsFor: 'event generation'! testMouseDown mouseEventOnNode1 setHand: HandMorph new. morph mouseDown: mouseEventOnNode1. mouseEventWithoutButton setHand: HandMorph new. morph mouseDown: mouseEventWithoutButton! ! !ROMorphTest methodsFor: 'event generation'! testMouseMove morph mouseMove: mouseEventOnNode1. morph mouseMove: mouseEventWithoutButton! ! !ROMorphTest methodsFor: 'event generation'! testMouseUp morph mouseUp: mouseEventOnNode1. morph mouseUp: mouseEventWithoutButton! ! !ROMorphTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/10/2012 08:41'! testMovingUpAndDown | el b bitmap1 bitmap2 cameraExtent1 | view add: (el := ROElement sprite). "view open." "We do a visu" b := el bounds. self assert: (el extent = b extent). self assert: (view camera virtualToRealRectangle: b) = ( 0@0 corner: 50@50). cameraExtent1 := view camera bounds. bitmap1 := view bitmap. "we move up" view camera moveUp; moveUp; moveUp. view signalUpdate. self assert: (el extent = b extent). self assert: (view camera virtualToRealRectangle: b) extent < b extent. self assert: (view camera bounds ~= cameraExtent1). bitmap2 := view bitmap. "The bitmap should be different" self assert: (bitmap1 bits ~= bitmap2 bits). " bitmap1 asMorph openInWindow bitmap2 asMorph openInWindow"! ! !ROMorphTest methodsFor: 'event generation'! testROMouseDragBegin morph roMouseDragBegin: mouseEventOnNode1. morph roMouseDragBegin: mouseEventWithoutButton! ! !ROMorphTest methodsFor: 'resizing window' stamp: 'AlexandreBergel 11/23/2012 08:35'! testResizingTheWindow "Resizing the window should not change the fisical size of the element" window := view open. "self assert: view camera visibleBounds = ( 9@9 corner: 190@190). " window extent: 200 @ 300. view camera moveToSee: (0@0 corner: 200 @ 300). self assert: view camera bounds ~= (-199@ -199 corner: 199@199). ! ! !ROMorphTest methodsFor: 'event generation' stamp: 'AlexandreBergel 4/14/2013 12:02'! testUsingMorph | stack t mouseEvent | view := ROMondrianViewBuilder new. stack := view stack. morph := ROMorph on: stack. t := 0. view raw on: ROMouseClick do: [ :evvt | t := t + 1 ]. view raw on: ROKeyDown do: [ :evvt | t := t + 10 ]. self assert: t = 0. morph roMouseClick: self mouseEvent. self assert: t = 1. morph roKeyStroke: self keyboardEvent. self assert: t = 11.! ! !ROMotionMoveTest methodsFor: 'tests' stamp: 'VanessaPena 3/12/2013 15:30'! test | view element | view := ROView new. element := ROElement new. element extent: 20@20; + ROEllipse blue; @ RODraggable; @ RODraggableWithVelocity. view add: element. self deny: view hasAnimation. ROMotionMove new for: element initialSpeed: 40 @ 30. self assert: view hasAnimation. ! ! !RONativeExampleUtilityTest methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 7/16/2012 08:00'! current ^ RONativeExampleUtility current ! ! !RONativeExampleUtilityTest methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 7/16/2012 08:06'! testGetMethods self assert: (self current getMethodsForClass: Object) isCollection! ! !RONativeExampleUtilityTest methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 7/16/2012 08:05'! testSubstrings self assert: (self current substringsFor: 'ab cd ef') = #('ab' 'cd' 'ef')! ! !RONormalizerSpecificTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/4/2012 00:19'! testBlockContext | normalizer | normalizer := RONColorLinearNormalizer inContext: [:entity | #(1 2 3 4 5 6 7 8)] withCommand: [:entity | entity]. self assert: (normalizer maximumValue: nil) = 8. self assert: (normalizer roValue: 1) = ( Color white). self assert: (normalizer roValue: 8) = Color black.! ! !RONormalizerSpecificTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/4/2012 00:50'! testLinearNormalizer | normalizer | normalizer := RONColorLinearNormalizer inContext: #(#Zuerich #Bern) withCommand: [:entity | entity size]. self assert: (normalizer maximumValue: nil) = 7. self assert: (normalizer roValue: #Zuerich) = Color black. self assert: (normalizer roValue: #Bern) = ( Color white). normalizer := RONLinearNormalizer inContext: #('Luzern' 'Basel') withCommand: [:entity | entity size]. self assert: (normalizer maximumValue: nil) = 6. normalizer := RONLinearNormalizer inContext: #('Luzern' 'Basel') withCommand: 99. self assert: (normalizer maximumValue: nil) = 99.! ! !RONormalizerSpecificTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/4/2012 00:47'! testThreshold | normalizer skyBlue | skyBlue := (Color r: 0.529361 g: 0.807838 b: 0.921621). normalizer := RONColorLinearNormalizer inContext: #(0 1 2 3 4 5 6 7 8 9 10) lowColor: skyBlue lowThreshold: 0.3 highColor: Color brown highThreshold: 0.7. self assert: (normalizer maximumValue: nil) = 10. self assert: (normalizer roValue: 10) = ( (Color r: 0.579 g: 0.382 b: 0.277)). self assert: (normalizer roValue: 1) = ( (Color r: 0.553 g: 0.601 b: 0.608)). self assert: (normalizer roValue: 0) = ( (Color r: 0.551 g: 0.626 b: 0.645)). "The adapted VW version. Differences with Squeak propably lay in different variable initialization. For example, brown in Squeak is different from VW skyBlue := (Color r: 0.529361 g: 0.807838 b: 0.921621). normalizer := MONColorLinearNormalizer inContext: #(0 1 2 3 4 5 6 7 8 9 10) lowColor: skyBlue lowThreshold: 0.3 highColor: Color brown highThreshold: 0.7. self assert: (normalizer maximumValue: nil) = 10. self assert: (normalizer moValue: 10) = (Color r: 0.611769 g: 0.357588 b: 0.391771). self assert: (normalizer moValue: 1) = (Color r: 0.569405 g: 0.589183 b: 0.664266). self assert: (normalizer moValue: 0) = (Color r: 0.564644 g: 0.614943 b: 0.694543)."! ! !RONormalizerTest methodsFor: 'identity' stamp: 'AlexandreBergel 7/14/2012 10:43'! testBeginingAtBlue | n | n := RONIdentityNormalizer beginingAtBlue. self assert: n nextColor = Color blue! ! !RONormalizerTest methodsFor: 'identity' stamp: 'AlexandreBergel 7/14/2012 10:40'! testBeginingAtRed | n | n := RONIdentityNormalizer beginingAtRed. self assert: n nextColor = Color red! ! !RONormalizerTest methodsFor: 'explicit identity' stamp: 'DR 1/15/2013 21:12'! testExplicitIdentity | normalizer colorOne colorTwo | normalizer := RONExplicitIdentityNormalizer withCommand: #last withColors: (Array with: Color blue with: Color white with: Color red) withDefaultColor: Color green. colorOne := normalizer roValue: 'alex'. colorTwo := normalizer roValue: 'suffix'. self assert: (colorOne = colorTwo) ! ! !RONormalizerTest methodsFor: 'explicit identity' stamp: 'DR 1/15/2013 21:12'! testExplicitIdentity2 | normalizer colorOne colorTwo | normalizer := RONExplicitIdentityNormalizer withCommand: #yourself withColors: (Array with: Color blue with: Color white with: Color red) withDefaultColor: Color green. self assert: (normalizer roValue: 1) = Color blue. self assert: (normalizer roValue: 2) = Color white. self assert: (normalizer roValue: 3) = Color red. self assert: (normalizer roValue: -1) = Color green. self assert: (normalizer roValue: 1000) = Color green.! ! !RONormalizerTest methodsFor: 'explicit identity' stamp: 'DR 1/15/2013 21:11'! testExplicitIdentity3Initialization | normalizer colorOne colorTwo colors | colors := Array with: Color blue with: Color white with: Color red. normalizer := RONExplicitIdentityNormalizer withCommand: #yourself withColors: colors withDefaultColor: Color green. self assert: (normalizer roValue: 1) = Color blue. self assert: (normalizer roValue: 2) = Color white. self assert: (normalizer roValue: 3) = Color red. self assert: (normalizer roValue: 4) = Color green.! ! !RONormalizerTest methodsFor: 'linear' stamp: 'AlexandreBergel 7/4/2012 00:49'! testGradient | normalizer | normalizer := RONColorLinearNormalizer inContext: #(0 1 2 3 4 5 6 7 8 9 10) lowColor: Color yellow highColor: Color red. self assert: (normalizer maximumValue: nil) = 10. self assert: (normalizer roValue: 10) = (Color r: 1.0 g: 0.0 b: 0.0). self assert: (normalizer roValue: 1) = (Color r: 1.0 g: 0.900012 b: 0.0). self assert: (normalizer roValue: 0) = (Color r: 1.0 g: 1.0 b: 0.0)! ! !RONormalizerTest methodsFor: 'identity' stamp: 'AlexandreBergel 7/2/2012 16:15'! testIdentity | colorOne colorTwo normalizer | normalizer := RONIdentityNormalizer new. colorOne := normalizer roValue: 1. colorTwo := normalizer roValue: 2. self deny: colorOne = colorTwo. colorOne := normalizer roValue: 12. colorTwo := normalizer roValue: 12. self assert: colorOne = colorTwo.! ! !RONormalizerTest methodsFor: 'identity' stamp: 'AlexandreBergel 7/2/2012 16:15'! testIdentityModulo "This checks that there is no exception if there are more identities than colors" 1 to: 150 do: [:index | RONIdentityNormalizer new roValue: index]! ! !RONormalizerTest methodsFor: 'identity' stamp: 'AlexandreBergel 7/2/2012 16:15'! testIdentityWithCommand | colorOne colorTwo normalizer | normalizer := RONIdentityNormalizer withCommand: #last. colorOne := normalizer roValue: 'bob'. colorTwo := normalizer roValue: 'tom'. self deny: colorOne = colorTwo. colorOne := normalizer roValue: 'anna'. colorTwo := normalizer roValue: 'maria'. self assert: colorOne = colorTwo.! ! !RONormalizerTest methodsFor: 'multiple' stamp: 'AlexandreBergel 7/4/2012 00:54'! testMultipleLinearNormalizer | normalizer | normalizer := ROMultipleColorLinearNormalizer valueRange: #(5 10 15) colorRange: (Array with: Color blue with: Color white with: Color red) . self assert: (normalizer roValue: 5) = (Color r: 0.0 g: 0.0 b: 1.0). self assert: (normalizer roValue: 6) = ( (Color r: 0.2 g: 0.2 b: 1.0)). self assert: (normalizer roValue: 15) = (Color r: 1.0 g: 0.0 b: 0.0)! ! !RONormalizerTest methodsFor: 'linear' stamp: 'AlexandreBergel 7/2/2012 16:16'! testNumberLinearNormalizer | normalizer | normalizer := RONumberLinearNormalizer inContext: (1 to: 10) withCommand: [:entity | entity * 1000 ]. self assert: (normalizer roValue: 100) = 10. normalizer := RONumberLinearNormalizer inContext: (1 to: 100) withCommand: [:entity | entity * 1000 ]. self assert: (normalizer roValue: 100) = 1. normalizer := RONumberLinearNormalizer inContext: (1 to: 100) withCommand: [:entity | entity ]. self assert: (normalizer roValue: 100) = 1. ! ! !RONormalizerTest methodsFor: 'linear' stamp: 'AlejandroInfante 1/11/2013 15:01'! testValueLinearNormalizer | normalizer | normalizer := ROValueLinearNormalizer inContext: (0 to: 10) withCommand: [:entity | entity ]. self assert: (normalizer roValue: 10) = 1. normalizer := ROValueLinearNormalizer inContext: (0 to: 10) withCommand: [:entity | entity * 1000 ]. self assert: (normalizer roValue: 100) = 10. normalizer := ROValueLinearNormalizer inContext: (99 to: 100) withCommand: [:entity | entity ]. self assert: (normalizer roValue: 101) = 2.! ! !ROOrderedCollection methodsFor: 'tests' stamp: 'AlexandreBergel 1/2/2013 16:06'! testBasic self assert: ((#(5 4 1 5 2) sortedAs: #squared) asArray = #(1 2 4 5 5) )! ! !ROOrderedCollection methodsFor: 'tests' stamp: 'AlexandreBergel 8/6/2013 06:13'! testReverseBasic self assert: ((#(5 4 1 5 2) reverseSortedAs: #squared) asArray = #(1 2 4 5 5) reverse )! ! !ROOrthoHorizontalLineShapeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 12:12'! testDrawOnFor | view el1 el2 edge | view := ROView new. el1 := ROBox element. el2 := ROBox element. edge := ROEdge from: el1 to: el2. edge + (ROOrthoHorizontalLineShape new color: [:e | Color red ]). view add: el1; add: el2; add: edge. ROGridLayout on: (Array with: el1 with: el2). self shouldnt: [ view drawOn: ROTracingCanvas new ] raise: Error.! ! !ROOrthoVerticalLineShapeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 12:12'! testDrawOnFor | view el1 el2 edge | view := ROView new. el1 := ROBox element. el2 := ROBox element. edge := ROEdge from: el1 to: el2. edge + (ROOrthoVerticalLineShape new color: [:e | Color red ]). view add: el1; add: el2; add: edge. ROGridLayout on: (Array with: el1 with: el2). self shouldnt: [ view drawOn: ROTracingCanvas new ] raise: Error.! ! !ROParentElementResizeStrategyTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/14/2013 19:22'! testFixedSized | el1 el2 | el1 := ROBox element. el1 resizeStrategy: ROFixedSizedParent instance. el1 addAll: (ROGridLayout on: ((1 to: 5) collect: [ :i | ROElement new ])). el2 := ROBox element. el2 resizeStrategy: ROExtensibleParent instance. el2 addAll: (ROGridLayout on: ((1 to: 5) collect: [ :i | ROBox element ])). self assert: el1 bounds = ( (0@0) corner: (5 @ 5)). self assert: el2 bounds = ( (0@0) corner: (50 @ 35)).! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 16:51'! testNoPadding | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox elementOn: 'bundle'. el1 := ROBox green elementOn: 'el1'. el2 := ROBox blue elementOn: 'el2'. bundle resizeStrategy: (ROExtensibleParent new padding: 0 @ 0). bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (5@20)' 'Color veryLightGray' 0 'Color black') #(#frameAndFillRectangle: '(0@0) corner: (5@5)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(0@15) corner: (5@20)' 'Color blue' 0 'Color black'))! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 17:04'! testNoPadding2 | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox gray elementOn: 'bundle'. el1 := (ROBox green extent: 30 @ 20) elementOn: 'el1'. el2 := ROBox blue elementOn: 'el2'. bundle resizeStrategy: (ROExtensibleParent new padding: 0 @ 0). bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@35)' 'Color gray' 0 'Color black') #(#frameAndFillRectangle: '(0@0) corner: (30@20)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(0@30) corner: (5@35)' 'Color blue' 0 'Color black'))! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 17:08'! testNoPadding3 | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox gray elementOn: 'bundle'. el1 := (ROBox green extent: 30 @ 20) elementOn: 'el1'. el2 := ROBox blue elementOn: 'el2'. bundle resizeStrategy: (ROExtensibleParent new padding: 0 @ 0). bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout new gapSize: 0; on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@25)' 'Color gray' 0 'Color black') #(#frameAndFillRectangle: '(0@0) corner: (30@20)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(0@20) corner: (5@25)' 'Color blue' 0 'Color black'))! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 17:08'! testNoPadding4 | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox gray elementOn: 'bundle'. el1 := (ROBox green extent: 30 @ 20) elementOn: 'el1'. el2 := ROBox blue elementOn: 'el2'. bundle resizeStrategy: (ROExtensibleParent new padding: 0 @ 0). bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout new gapSize: 0; stretchHorizontally; on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@25)' 'Color gray' 0 'Color black') #(#frameAndFillRectangle: '(0@0) corner: (30@20)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(0@20) corner: (30@25)' 'Color blue' 0 'Color black'))! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 17:10'! testNoPadding5 | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox gray elementOn: 'bundle'. el1 := (ROBox green extent: 30 @ 20) elementOn: 'el1'. el2 := ROBox blue elementOn: 'el2'. bundle resizeStrategy: (ROExtensibleParent new padding: 0 @ 0). bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout new gapSize: 0; stretchHorizontally; alignCenter; on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@25)' 'Color gray' 0 'Color black') #(#frameAndFillRectangle: '(0@0) corner: (30@20)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(0.0@20) corner: (30.0@25)' 'Color blue' 0 'Color black')) ! ! !ROParentElementResizeStrategyTest methodsFor: 'padding' stamp: 'AlexandreBergel 8/11/2013 16:49'! testPadding | view bundle el1 el2 canvas | view := ROView new. bundle := ROBox elementOn: 'bundle'. el1 := ROBox green elementOn: 'el1'. el2 := ROBox blue elementOn: 'el1'. bundle add: el1; add: el2. view add: bundle. ROVerticalLineLayout on: (Array with: el1 with: el2). canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (15@30)' 'Color veryLightGray' 0 'Color black') #(#frameAndFillRectangle: '(5@5) corner: (10@10)' 'Color green' 0 'Color black') #(#frameAndFillRectangle: '(5@20) corner: (10@25)' 'Color blue' 0 'Color black'))! ! !ROPlatformTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/25/2012 18:01'! testAddingAPlatform | platform s | platform := ROPlatform new. platform name: 'test'. platform canvasClass: ROAbstractCanvas subclasses anyOne. platform fontOrganizerClass: ROFontOrganizer subclasses anyOne. platform widgetFactory: RONativeWidgetFactory subclasses anyOne. platform timeOrganizerClass: ROTimeOrganizer subclasses anyOne. platform hostVisualElement: Object. "We pick any class" ROPlatform removeNamed: 'test' ifAbsent: []. s := ROPlatform numberOfPlatforms. ROPlatform add: platform. self assert: (s + 1) = ROPlatform numberOfPlatforms. platform remove. self assert: s = ROPlatform numberOfPlatforms.! ! !ROPlatformTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/25/2012 15:19'! testCurrent self assert: ROPlatform current notNil. self assert: (ROPlatform current isKindOf: ROPlatform).! ! !ROPopupMondrianTest methodsFor: 'running' stamp: 'AlexandreBergel 7/3/2012 13:28'! setUp view := ROMondrianViewBuilder new.! ! !ROPopupMondrianTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/9/2012 07:57'! testIfPopupText | nodes targetView | view interaction if: #odd popupText: 'hello'; if: #even popupText: 'world'. nodes := view nodes: #(1 2 3). targetView := view stack. self assert: (nodes allSatisfy: [ :node | node is: ROPopupView ]). self assert: targetView numberOfElements isZero. nodes first announce: ROMouseEnter. self assert: targetView numberOfElements = 1. nodes first announce: ROMouseLeave. self assert: targetView numberOfElements isZero. nodes third announce: ROMouseEnter. self assert: targetView numberOfElements = 1. nodes third announce: ROMouseLeave. self assert: targetView numberOfElements isZero. nodes second announce: ROMouseEnter. self assert: targetView numberOfElements = 1. nodes second announce: ROMouseLeave. self assert: targetView numberOfElements isZero.! ! !ROPopupMondrianTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/14/2012 09:36'! testInteractionAndPopup | nodes node | view interaction action: #browse. view shape rectangle size: 15. nodes := view nodes: (Array with: 10). node := nodes first. self assert: (node is: RODraggable). self assert: (node is: ROMenuActivable). self assert: (node is: ROPopupView) ! ! !ROPopupMondrianTest methodsFor: 'popupText per default' stamp: 'AlexandreBergel 7/14/2012 09:37'! testInteractionAndPopup2 | nodes node | view shape rectangle size: 15. nodes := view nodes: (Array with: 10). node := nodes first. self assert: (node is: RODraggable). self deny: (node is: ROMenuActivable). self assert: (node is: ROPopupView) ! ! !ROPopupMondrianTest methodsFor: 'popupText per default' stamp: 'AlexandreBergel 7/14/2012 09:38'! testInteractionAndPopup3 | nodes node | view interaction action: #browse; noPopup. view shape rectangle size: 15. nodes := view nodes: (Array with: 10). node := nodes first. self assert: (node is: RODraggable). self assert: (node is: ROMenuActivable). self deny: (node is: ROPopupView) ! ! !ROPopupMondrianTest methodsFor: 'popupText per default' stamp: 'AlexandreBergel 7/14/2012 09:46'! testInteractionAndPopup4 | nodes node node1 node2 | view interaction action: #browse; noPopup. view shape rectangle size: 15. node1 := view node: 10. node2 := view node: 20. self assert: (node1 is: RODraggable). self assert: (node1 is: ROMenuActivable). self deny: (node1 is: ROPopupView). self assert: (node2 is: RODraggable). self deny: (node2 is: ROMenuActivable). self assert: (node2 is: ROPopupView) ! ! !ROPopupMondrianTest methodsFor: 'popupText per default' stamp: 'AlexandreBergel 7/16/2012 20:03'! testInteractionAndPopup5 | node1 node2 | view interaction action: #browse; noPopup. view shape rectangle size: 15. node1 := view node: 10 forIt: [ node2 := view node: 20 ]. self assert: (node1 is: RODraggable). self assert: (node1 is: ROMenuActivable). self deny: (node1 is: ROPopupView). self assert: (node2 is: RODraggable). self deny: (node2 is: ROMenuActivable). self assert: (node2 is: ROPopupView) ! ! !ROPopupMondrianTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/3/2012 13:28'! testNoTwoPopupAtTheSameTime | nodes | nodes := view nodes: #(1 2). "We have done nothing so far, so there is only two nodes" self assert: view raw numberOfElements = 2. self assert: view stack numberOfElements = 0. "We enter one node, a popup appears in the stack" nodes first announce: ROMouseEnter. self assert: view raw numberOfElements = 2. self assert: view stack numberOfElements = 1. "We enter the second node, a popup appears, but the first popup should diseapear" nodes second announce: ROMouseEnter. self assert: view raw numberOfElements = 2. self assert: view stack numberOfElements = 1. ! ! !RORemoveNodeTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/18/2012 15:55'! testBasic | view el1 el2 el3 el4 el | view := ROView new. view add: (el1 := ROElement on: 1). view add: (el2 := ROElement on: 2). view add: (el3 := ROElement on: 3). view add: (el4 := ROElement on: 4). view addAll: (ROEdge linesFor: (Array with: el1 -> el2 with: el1 -> el1 with: el3 -> el1)). self assert: view numberOfElements = 7. RORemoveNode suchThat: [ :e | e == el1 ] in: view. self assert: view numberOfElements = 3.! ! !ROScrollbableTest methodsFor: 'running' stamp: 'AlexandreBergel 6/9/2012 18:42'! setUp view := ROView new. view add: ROElement sprite. view addAll: (ROHorizontalLineLayout on: (ROElement spritesOn: (1 to: 50))). "view @ RODraggable ." stack := ROViewStack new. stack addView: view. stack @ ROScrollbable. "stack open." "Get the scrollbars" horizontalScrollbar := stack elements first. verticalScrollbar := stack elements second. ! ! !ROScrollbableTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/5/2012 23:22'! testMovingScrollbar ROGridLayout on: view elements . verticalScrollbar announce: (ROMouseDragging step: 0 @ 250). self assert: verticalScrollbar position = (0 @ 250). self assert: view encompassingRectangle height = 350. self assert: view camera position = (0 @ 175) " ((2995- view camera width) @0).". horizontalScrollbar announce: (ROMouseDragging step: 250 @ 0). self assert: horizontalScrollbar position = (250 @ 0). self assert: view encompassingRectangle width = 530. self assert: view camera position = (265 @ 175) " ((2995- view camera width) @0)."! ! !ROScrollbableTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/5/2012 18:02'! testScrollbar self assert: horizontalScrollbar position = (0 @ 0). self assert: view camera position = (0 @ 0)! ! !ROScrollbableTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/5/2012 23:22'! testScrollbarBottomMost verticalScrollbar announce: (ROMouseDragging step: 0 @ 10000). self assert: verticalScrollbar position = (0 @ 420). self assert: view encompassingRectangle height = 55. self assert: view camera position = (0@46) " ((2995- view camera width) @0)."! ! !ROScrollbableTest methodsFor: 'tests' stamp: 'DR 3/25/2013 21:53'! testScrollbarRightMost | points | horizontalScrollbar announce: (ROMouseDragging step: 10000 @ 0). self assert: horizontalScrollbar position = (420 @ 0). points := Array with: 2515@0 with: 2516@0. self assert: (points includes: view camera position). ! ! !ROScrollbableTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/5/2012 17:59'! testStack "Only one element in the stack so far. Soon we will have two!!" self assert: stack numberOfElements = 2. ! ! !ROShapeTest methodsFor: 'extent on chain' stamp: 'AlexandreBergel 10/17/2012 09:42'! testAddingShape | el shape b | el := ROElement on: 30. shape := ROBox new. shape height: (b := [ :e | e model + 1 ]). self assert: (shape extentFor: el) = (5 @ 31). el + shape. self assert: (shape extentFor: el) = (5 @ 31). self assert: shape height == b! ! !ROShapeTest methodsFor: 'extent on chain' stamp: 'AlexandreBergel 9/14/2013 12:49'! testAdjustingShapeChain | shape1 shape2 el | shape1 := ROBox blue. shape2 := ROBox green. el := ROElement new. el + shape1 + shape2. el extent: 50 @ 50. self assert: el extent = (50 @ 50). self assert: shape1 extent = (5 @ 5). self assert: shape2 extent = (5 @ 5).! ! !ROShapeTest methodsFor: 'extent on chain' stamp: 'AlexandreBergel 9/14/2013 12:49'! testAdjustingShapeChain4 | shape1 shape2 el | shape1 := ROBox blue. shape2 := ROBox green. el := ROElement new. el + shape1 + shape2. el extent: 50 @ 50. shape1 extent: 70 @ 70. self assert: el extent = (50 @ 50). self assert: shape1 extent = (70 @ 70). self assert: shape2 extent = (5 @ 5).! ! !ROShapeTest methodsFor: 'extent on chain' stamp: 'AlexandreBergel 9/14/2013 12:50'! testAdjustingShapeChain5 | shape1 shape2 el | shape1 := ROBox blue. shape2 := ROBox green. shape1 extent: 70 @ 70. el := ROElement new. el + shape1 + shape2. el extent: 50 @ 50. self assert: el extent = (50 @ 50). self assert: shape1 extent = (70 @ 70). self assert: shape2 extent = (5 @ 5).! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:42'! testCompose | shape1 shape2 shape3 | shape1 := ROBox new. shape2 := ROLabel. shape3 := shape1 compose: shape2. self assert: shape3 == shape1. self deny: shape3 next == shape2. self assert: (shape1 next isKindOf: shape2). ! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:42'! testCompose2 | shape1 shape2 shape3 | shape1 := ROBox. shape2 := ROLabel new. shape3 := shape1 compose: shape2. self deny: shape3 == shape1. self assert: (shape3 isKindOf: shape1). self assert: shape3 next == shape2.! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:42'! testCompose3 | shape1 shape2 shape3 | shape1 := ROBox. shape2 := ROLabel. shape3 := shape1 compose: shape2. self deny: shape3 == shape1. self assert: (shape3 isKindOf: shape1). self deny: shape3 next == shape2. self assert: (shape3 next isKindOf: shape2). ! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:43'! testCompose4 | shape1 shape2 shape3 | shape1 := ROBox new. shape2 := ROLabel new. shape3 := shape1 compose: shape2. self assert: shape3 == shape1. self assert: shape3 next == shape2.! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'AlexandreBergel 5/6/2013 18:08'! testComposeAllElementShapes | elementShapes composition element view excludedShapes | view := ROView new. excludedShapes := Array with: ROMiniMapDisplayer with: ROImage with: ROViewDisplayer. elementShapes := ROShape withAllSubclasses reject: [: e | (e isAbstract or: [ e isEdgeShape ]) or: [ excludedShapes anySatisfy: [ :ee | ee == e ] ] ]. composition := elementShapes first. composition := elementShapes inject: composition into: [ :subComposition :shape | subComposition + shape + shape new ]. composition := composition. element := ROElement new. element + composition. view add: element. view drawOn: ROTracingCanvas new. self assert: ((element shapes collect: #class) includesAll: elementShapes).! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:45'! testPlus | shape1 shape2 shape3 | shape1 := ROBox new. shape2 := ROLabel. shape3 := shape1 + shape2. self assert: shape3 == shape1. self deny: shape3 next == shape2. self assert: (shape1 next isKindOf: shape2). ! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:45'! testPlus2 | shape1 shape2 shape3 | shape1 := ROBox. shape2 := ROLabel new. shape3 := shape1 + shape2. self deny: shape3 == shape1. self assert: (shape3 isKindOf: shape1). self assert: shape3 next == shape2.! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:45'! testPlus3 | shape1 shape2 shape3 | shape1 := ROBox. shape2 := ROLabel. shape3 := shape1 + shape2. self deny: shape3 == shape1. self assert: (shape3 isKindOf: shape1). self deny: shape3 next == shape2. self assert: (shape3 next isKindOf: shape2). ! ! !ROShapeTest methodsFor: 'compose shapes' stamp: 'JurajKubelka 4/19/2013 12:45'! testPlus4 | shape1 shape2 shape3 | shape1 := ROBox new. shape2 := ROLabel new. shape3 := shape1 + shape2. self assert: shape3 == shape1. self assert: shape3 next == shape2.! ! !ROShapeTest methodsFor: 'remove shape' stamp: 'VanessaPena 3/12/2013 15:30'! testRemoveShape | b c removedElement | b := ROBox new. c := ROEllipse new. b addLast: c. self assert: b next == c. removedElement := b removeShape: ROEllipse. self assert: removedElement == c. self assert: (b next isKindOf: RONullShape) ! ! !ROShapeTest methodsFor: 'remove shape' stamp: 'VanessaPena 3/12/2013 15:30'! testRemoveShape2 | b c b2 | b := ROBox new. c := ROEllipse new. b addLast: c. b2 := b removeShape: ROBox. self assert: b2 == c. self assert: (b2 next isKindOf: RONullShape)! ! !ROSpecificAbstractLabelTest class methodsFor: 'testing' stamp: 'miltonmamani 4/17/2013 15:17'! isAbstract ^ self name == #ROSpecificAbstractLabelTest! ! !ROSpecificAbstractLabelTest methodsFor: 'hooks' stamp: 'miltonmamani 4/17/2013 15:09'! classToTest self subclassResponsibility ! ! !ROSpecificAbstractLabelTest methodsFor: 'font size' stamp: 'AlexandreBergel 6/12/2013 17:19'! testFontScale | el shape view heightBeforeZoomingIn | view := ROView new. el := ROElement on: 'Hola, mundo'. el + (shape := self classToTest new) . view add: el. heightBeforeZoomingIn := (shape fontFor: el with: view camera) height. ROZoomInMove new on: view. view doAllAnimationCycles. ROZoomInMove new on: view. view doAllAnimationCycles. self assert: (shape fontFor: el with: view camera) height > heightBeforeZoomingIn! ! !ROSpecificAbstractLabelTest methodsFor: 'font size' stamp: 'AlexandreBergel 6/21/2013 09:13'! testFontSize | el shape font | el := ROElement on: 'Hola, mundo'. el + (shape := self classToTest new) . shape fontSize: 19. font := shape fontFor: el with: el view camera. font class == LogicalFont ifTrue: [ self assert: font pointSize = 19 ] ifFalse: [ self assert: font height = 19 ]! ! !ROSpecificAbstractLabelTest methodsFor: 'font size' stamp: 'AlexandreBergel 6/21/2013 09:19'! testFontSizeBlock |el shape font | el := ROElement on: 28. el + (shape := self classToTest new) . shape fontSize: [ :element | element model ]. font := shape fontFor: el with: el view camera. font class == LogicalFont ifTrue: [ self assert: font pointSize = 28 ] ifFalse: [ self assert: font height = 28 ]! ! !ROSpecificCenteredLabelTest methodsFor: 'hooks' stamp: 'miltonmamani 4/17/2013 15:08'! classToTest ^ ROCenteredLabel! ! !ROSpecificCenteredLabelTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/29/2013 10:04'! testRendering | canvas view el el2 | canvas := ROTracingCanvas new. view := ROView new. el := ROElement sprite. el2 := ROElement new + (ROCenteredLabel new text: 'hel'; textPadding: 0). view add: el. el add: el2. el translateBy: 50 @ 50. view drawOn: canvas. self assert: canvas trace asArray = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(50@50)' '(100@50)' 1 'Color red') #(#line '(100@50)' '(100@100)' 1 'Color red') #(#line '(100@100)' '(50@100)' 1 'Color red') #(#line '(50@100)' '(50@50)' 1 'Color red') #(#drawStringColor 'hel' '(55@55)' 'Color black'))! ! !ROSpecificCenteredLabelTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/12/2013 17:32'! testRendering2 | canvas view el t | canvas := ROTracingCanvas new. view := ROView new. el := ROElement sprite + (ROCenteredLabel new text: 'hello'; textPadding: 0). view add: el. el translateBy: 50 @ 50. view drawOn: canvas. t := canvas trace asArray. (t at: 2) at: 3 put: nil. self assert: t = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#drawStringColor 'hello' nil 'Color black') #(#line '(50@50)' '(100@50)' 1 'Color red') #(#line '(100@50)' '(100@100)' 1 'Color red') #(#line '(100@100)' '(50@100)' 1 'Color red') #(#line '(50@100)' '(50@50)' 1 'Color red'))! ! !ROSpecificLabelTest methodsFor: 'hooks' stamp: 'miltonmamani 4/17/2013 15:08'! classToTest ^ ROLabel! ! !ROSpecificLabelTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/29/2013 10:04'! testRendering | canvas view el el2 | canvas := ROTracingCanvas new. view := ROView new. el := ROElement sprite. el2 := ROElement new + (ROLabel new text: 'hel'; textPadding: 0). view add: el. el add: el2. el translateBy: 50 @ 50. view drawOn: canvas. self assert: canvas trace asArray = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(50@50)' '(100@50)' 1 'Color red') #(#line '(100@50)' '(100@100)' 1 'Color red') #(#line '(100@100)' '(50@100)' 1 'Color red') #(#line '(50@100)' '(50@50)' 1 'Color red') #(#drawStringColor 'hel' '(55@55)' 'Color black')) ! ! !ROTest methodsFor: 'asserting' stamp: 'AlexandreBergel 10/21/2013 23:50'! validateShouldntException: exception "Override strange method from TestCase"! ! !ROTracingCanvasTest methodsFor: 'running' stamp: 'AlexandreBergel 12/14/2012 13:31'! setUp canvas := ROTracingCanvas new.! ! !ROTracingCanvasTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/14/2012 16:24'! testColToString self assert: (canvas colToStr: Color white) = 'Color white'. self assert: (canvas colToStr: Color red) = 'Color red'! ! !ROTracingCanvasTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/14/2012 13:32'! testRecToString self assert: (canvas recToStr: ((3 @ 6) corner: (10 @ 30))) = '(3@6) corner: (10@30)'! ! !ROTranslationTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/24/2013 08:54'! testDraggingOnTheTopLeftCorner | view outterNode innerNode1 innerNode2 | view := ROView new. view @ RODraggable. outterNode := ROElement new. outterNode + (ROBox new extent: 50 @ 50). innerNode1 := ROElement new. innerNode1 + (ROBox blue extent: 10 @ 10). innerNode2 := ROElement new. innerNode2 + (ROBox green extent: 10 @ 10). outterNode add: innerNode1. outterNode add: innerNode2. view add: outterNode. " view open " "Witout dragging" self assert: innerNode1 position = (5 @ 5). self assert: innerNode2 position = (5 @ 5). "Dragging innerNode" innerNode1 translateBy: -10 @ -10. self assert: innerNode1 position = (0 @ 0). self assert: innerNode2 position = (10 @ 10).! ! !ROTriangleTest commentStamp: '' prior: 34279352! A ROTriangleTest is a test class for testing the behavior of ROTriangle! !ROTriangleTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/25/2013 11:50'! testBasic | el view tracingCanvas | el := ROElement new. el + (ROTriangle new extent: 20 @ 30). view := ROView new. view add: el. tracingCanvas := ROTracingCanvas new. view drawOn: tracingCanvas. self assert: tracingCanvas trace = {#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white'). {#drawPolygon. '{(10@0). (20@30). (0@30)}'. 0. Color black}}! ! !ROViewStructureTest methodsFor: 'running' stamp: 'AlexandreBergel 7/24/2012 17:35'! setUp view := ROMondrianViewBuilder new.! ! !ROViewStructureTest methodsFor: 'frame' stamp: 'VanessaPena 4/12/2013 11:48'! testAddFrame |parent child| parent := ROMondrianFrame new. child := ROMondrianFrame new. self assert: parent children size = 0. parent addChild: child. child parent: parent. self assert: parent children size = 1. self assert: parent children first = child.! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'AlexandreBergel 7/25/2012 09:37'! testBasic view nodes: (1 to: 4). self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 4. view nodes: (5 to: 10). self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 10.! ! !ROViewStructureTest methodsFor: 'looking up' stamp: 'AlexandreBergel 7/25/2012 10:29'! testFrameOfElement | outterNodes outterFrame firstInnerFrame secondInnerFrame | outterNodes := view nodes: #(10 11) forEach: [ :e | view nodes: (1 to: 5) ]. outterFrame := view structureTree. outterNodes do: [ :n | self assert: (outterFrame frameOfElement: n) == outterFrame ]. firstInnerFrame := outterFrame children first. firstInnerFrame nodes do: [ :n | self assert: (outterFrame frameOfElement: n) == firstInnerFrame ]. secondInnerFrame := outterFrame children second. secondInnerFrame nodes do: [ :n | self assert: (outterFrame frameOfElement: n) == secondInnerFrame ]. ! ! !ROViewStructureTest methodsFor: 'looking up' stamp: 'AlexandreBergel 7/25/2012 16:44'! testFrameOfElementNotFound self assert: (view structureTree frameOfElement: ROElement new) == view structureTree ! ! !ROViewStructureTest methodsFor: 'initialization' stamp: 'AlexandreBergel 7/24/2012 17:54'! testInitialization self assert: view numberOfFrames = 1. ! ! !ROViewStructureTest methodsFor: 'initialization' stamp: 'AlexandreBergel 7/24/2012 17:44'! testInitializationFrame self assert: ROMondrianFrame new parent isNil! ! !ROViewStructureTest methodsFor: 'layout' stamp: 'AlexandreBergel 7/25/2012 10:06'! testLayout | node innerNodes outerFrame innerFrame | view nodes: #(10 11) forEach: [ :each | view nodes: (1 to: 5) ]. view treeLayout. outerFrame := view structureTree. self assert: outerFrame layout class == ROTreeLayout. innerFrame := outerFrame children anyOne. self assert: innerFrame layout class == ROHorizontalLineLayout ! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'AlexandreBergel 7/25/2012 09:46'! testNesting view node: 10 forIt: [ view nodes: (1 to: 5) ]. self assert: view numberOfFrames = 2. self assert: view structureTree numberOfElements = 1. self assert: (view structureTree numberOfChildren = 1). self assert: (view structureTree children first numberOfElements = 5). ! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'AlexandreBergel 7/25/2012 09:48'! testNesting2 | node innerNodes | node := view node: 10 forIt: [ innerNodes := view nodes: (1 to: 5) ]. self assert: view structureTree elements first == node. self assert: (view structureTree children first elements = innerNodes). ! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'AlexandreBergel 7/25/2012 10:07'! testNesting3 view nodes: #(1 2) forEach: [ :e | view nodes: (1to: 3)]. self assert: view structureTree numberOfElements = 2. self assert: view structureTree numberOfFrames = 3.! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'AlexandreBergel 7/25/2012 10:45'! testNestingWithEdges | innerNodes edge innerFrame | view node: 10 forIt: [ innerNodes := view nodes: (1 to: 5). edge := view edgeFromAssociation: 1->3 ]. innerFrame := view structureTree children first. self assert: (innerFrame numberOfElements = 6). self assert: (innerFrame edges size = 1). self assert: (innerFrame edges anyOne == edge). self assert: (innerFrame nodes = innerNodes). self assert: (innerFrame edges first == edge).! ! !ROViewStructureTest methodsFor: 'layout' stamp: 'AlexandreBergel 4/24/2013 08:33'! testNoLayout | innerNodes | view node: 10 forIt: [ innerNodes := view nodes: (1 to: 5). view horizontalLineLayout ]. "We haven't done a layout still" self assert: (view structureTree children first layout class == ROHorizontalLineLayout). self assert: (innerNodes allSatisfy: [ :n | n position = (5 @ 5)]) ! ! !ROViewStructureTest methodsFor: 'stack' stamp: 'AlexandreBergel 7/25/2012 09:36'! testPoping view push. view pop. self assert: view currentFrame == view structureTree. ! ! !ROViewStructureTest methodsFor: 'stack' stamp: 'AlexandreBergel 7/25/2012 09:36'! testPushing self assert: view currentFrame == view structureTree. view push. self assert: view currentFrame ~~ view structureTree. self assert: view currentFrame parent == view structureTree.! ! !ROViewStructureTest methodsFor: 'layout' stamp: 'AlexandreBergel 7/25/2012 09:53'! testRecursiveLayout | innerNodes positions | view node: 10 forIt: [ innerNodes := view nodes: (1 to: 5). view horizontalLineLayout ]. view applyLayout. positions := OrderedCollection new. positions add: (5@5); add: (20@5); add: (35@5); add: (50@5); add: (65@5). self assert: (innerNodes collect: #position) = positions asArray.! ! !ROViewStructureTest methodsFor: 'frame' stamp: 'VanessaPena 4/12/2013 11:48'! testRemoveFrame |parent child| parent := ROMondrianFrame new. child := ROMondrianFrame new. parent addChild: child. child parent: parent. self assert: parent children size = 1. self assert: parent children first = child. parent removeChild: child. self assert: parent children size = 0. ! ! !ROViewStructureTest methodsFor: 'frame' stamp: 'AlexandreBergel 5/25/2013 18:40'! testRemoveFrameFromParent | parent child | parent := ROMondrianFrame new. child := ROMondrianFrame new. parent addChild: child. child parent: parent. self assert: parent children size = 1. self assert: parent children first = child. child removeFromParent. self assert: parent children size = 0. ! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'VanessaPena 4/12/2013 11:18'! testRemoveNestedNode view node: 1forIt: [ view nodes: (1 to: 4)]. self assert: view numberOfFrames = 2. self assert: view currentFrame numberOfElements = 1. self assert: view currentFrame children first numberOfElements = 4. view removeNode: 1. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 0.! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'VanessaPena 4/12/2013 12:00'! testRemoveNestedNodes view nodes: (1 to: 3)forEach: [ view nodes: (1 to: 4)]. self assert: view numberOfFrames = 4. self assert: view currentFrame numberOfElements = 3. self assert: view currentFrame children first numberOfElements = 4. view removeNodes: (2 to: 3). self assert: view numberOfFrames = 2. self assert: view currentFrame numberOfElements = 1. self assert: view currentFrame children first numberOfElements = 4.! ! !ROViewStructureTest methodsFor: 'nesting' stamp: 'VanessaPena 4/12/2013 11:11'! testRemoveNode view node: 1. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 1. view removeNode: 1. self assert: view numberOfFrames = 1. self assert: view currentFrame numberOfElements = 0.! ! !ROViewStackTest methodsFor: 'animation' stamp: 'AlexandreBergel 5/18/2013 07:54'! testDoAnimationCycle | stack animation | stack := ROViewStack new. animation := ROLinearMove for: stack by: 50 @ 50. self assert: stack numberOfAnimations = 1. animation nbCycles timesRepeat: [ stack doAnimationCycle ]. self assert: stack numberOfAnimations = 0.! ! !ROViewStackTest methodsFor: 'animation' stamp: 'AlexandreBergel 5/18/2013 07:56'! testDrawOn | stack animation nullCanvas | stack := ROViewStack new. animation := ROLinearMove for: stack by: 50 @ 50. self assert: stack numberOfAnimations = 1. nullCanvas := RONullCanvas new. animation nbCycles timesRepeat: [ stack drawOn: nullCanvas ]. self assert: stack numberOfAnimations = 0.! ! !ROViewStackTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/1/2012 11:33'! testNestingView | newView el mouseClickPosition | newView := ROView new. newView add: (el := ROElement sprite translateTo: 0@60). view := ROViewStack new. view addFirst: newView. self assert: (view elementAtRealPosition: 23@85) == el. self assert: (newView elementAtRealPosition: 23@85) == el. (ROZoomOutMove new on: newView). self assert: newView hasAnimation. newView doAllAnimationCycles. self assert: (view elementAtRealPosition: (53@103)) == el. self assert: (newView elementAtRealPosition: (53@103)) == el. ROZoomOutMove new on: newView. newView doAllAnimationCycles. ROZoomOutMove new on: newView. newView doAllAnimationCycles. self assert: (view elementAtRealPosition: (109@131)) == el. " view openInWindow"! ! !ROViewStackTest methodsFor: 'animation' stamp: 'AlexandreBergel 5/18/2013 07:52'! testNumberOfAnimations self assert: ROViewStack new numberOfAnimations = 0.! ! !ROViewStackTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/30/2012 23:18'! testOpening | window | view := ROViewStack new. view add: (ROElement on: 'hello'). window := view open. window delete! ! !ROViewStackTest methodsFor: 'tests' stamp: 'AlexandreBergel 7/25/2012 17:17'! testZoomInAndDragAndDrop | newView el originalCameraBounds step | newView := ROView new. el := ROElement new extent: (5 @ 5). el + (ROBox new color: Color red). el @ RODraggable. newView add: el. el translateTo: 150 @ 100. view := ROViewStack new. view addFirst: newView. self assert: (el bounds = ( (150@100) corner: (155@105))). self assert: newView camera bounds = ( (0@0) corner: (500@500)). self assert: (newView camera virtualToRealPointNoTrunc: el position ) = (150 @ 100). "We simulate the zoom in" originalCameraBounds := newView camera bounds. step := 100 @ 100. newView camera bounds: ((originalCameraBounds topLeft + step) corner: (originalCameraBounds bottomRight - step)). newView signalUpdate. self assert: (el bounds = ( (150@100) corner: (155@105))). self assert: (((newView camera virtualToRealPointNoTrunc: el position ) - (83.33333333333333@0.0)) < (0.1 @ 0.1)). self assert: newView camera bounds = ( (100@100) corner: (400@400)). el announce: (ROMouseDragging step: 20 @ 20 ). self assert: (el bounds = ( (162.0@112.0) corner: (167.0@117.0))). self assert: ((newView camera virtualToRealPointNoTrunc: el position ) - (103.33333333333333@20.0)) < (0.1 @ 0.1)! ! !ROViewTest methodsFor: 'running' stamp: 'AlexandreBergel 9/25/2012 15:01'! setUp node1 := ROElement on: 'hello'. node1 extent: 40 @ 30. node1 addShape: (ROBox new color: Color yellow); addShape: ROBorder new. node1 addInteraction: RODraggable. node2 := ROElement on: 'world'. node2 extent: 40 @ 30. node2 addShape: (ROBox new color: Color green). node2 translateBy: 100@30. view := self viewClass new. view add: node1. view add: node2. emptyView := ROView new.! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/3/2012 22:34'! testAddingNode self assert: emptyView numberOfElements isZero. emptyView add: ROElement new. self assert: emptyView numberOfElements = 1. emptyView add: ROElement new. self assert: emptyView numberOfElements = 2! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 9/4/2012 15:21'! testAddingNodes | element | element := ROElement new. self assert: emptyView elements isEmpty. 3 timesRepeat: [ emptyView add: element ]. self assert: emptyView elements size = 1. ! ! !ROViewTest methodsFor: 'animations' stamp: 'AlexandreBergel 5/2/2013 19:06'! testAnimationWithDefaultStrategy | animation1 animation2 | animation1 := ROMotionMove new. animation2 := ROMotionMove new. view := ROView new. view addAnimation: animation1. view addAnimation: animation2. self assert: view numberOfAnimations = 2! ! !ROViewTest methodsFor: 'animations' stamp: 'AlexandreBergel 5/3/2013 08:37'! testAnimationWithExclusiveStrategy | animation | view := ROView new. ROMotionMove new for: view initialSpeed: 5 @ 5. animation := ROMotionMove new. animation strategy: (ROAnimationExclusive instance). animation for: view initialSpeed: 15 @ 15. self assert: view numberOfAnimations = 1. self assert: view animations asArray = (Array with: animation)! ! !ROViewTest methodsFor: 'events' stamp: 'AlexandreBergel 6/9/2012 15:15'! testAnnouncerInView self assert: (view instVarNamed: 'eventHandler') class == ROAnnouncer! ! !ROViewTest methodsFor: 'tests'! testCamera self assert: (view camera class == ROCamera)! ! !ROViewTest methodsFor: 'camera' stamp: 'DR 3/25/2013 21:58'! testCameraHeight | camera alts | camera := view camera. self assert: camera position = (0@0). self assert: camera altitude asInteger = 229. "Due to the rounding" camera altitude: 230. alts := Array with: 229 with: 230. self assert: (alts includes: camera altitude asInteger). ! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 3/20/2013 10:28'! testChangingToBasicOrdering view zOrdering: (ROBasicZOrdering new). self assert: node1 zIndex = 0. self assert: node2 zIndex = 0. view zOrdering: (ROZOrdering new setZIndex: 1 if: [ :el | el == node1 ]; setZIndex: 2 if: [ :el | el == node2 ]; yourself). self assert: node1 zIndex = 1. self assert: node2 zIndex = 2.! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 18:12'! testChangingZOrdering view zOrdering: (ROZOrdering new setZIndex: 1 if: [ :el | el == node1 ]; setZIndex: 2 if: [ :el | el == node2 ]; yourself). self assert: node1 zIndex = 1. self assert: node2 zIndex = 2. view zOrdering: (ROZOrdering new setZIndex: 1 if: [ :el | el == node2 ]; setZIndex: 2 if: [ :el | el == node1 ]; yourself). self assert: node1 zIndex = 2. self assert: node2 zIndex = 1.! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/30/2012 15:25'! testDefaultWindowSize self assert: (self viewClass new defaultWindowSize class == Point)! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/11/2012 21:08'! testDefaultZOrdering self assert: node1 zIndex = 0. self assert: node2 zIndex = 0.! ! !ROViewTest methodsFor: 'dragging'! testDraggingElement | el t | el := ROElement sprite. node1 add: el. t := false. view on: RORefreshNeeded do: [ :event | t := true. ]. self deny: t. el announce: (ROMouseDragging step: 5 @ 3). self assert: t! ! !ROViewTest methodsFor: 'dragging' stamp: 'AlexandreBergel 9/4/2012 15:30'! testDraggingElement2 | el t | el := ROElement sprite. node1 add: el. t := false. "view := self viewClass new. view add: node1; add: node2." view on: RORefreshNeeded do: [ :event | t := true ]. self deny: t. "Check signalUpdate, since this is what is used to update the view" self assert: el view == node1 view. el signalUpdate. self assert: t. t := false. el announce: (ROMouseDragging step: 5 @ 3). self assert: t! ! !ROViewTest methodsFor: 'camera'! testDraggingView | camera | camera := view camera. self assert: camera bounds = ( 0@0 corner: 500@500). camera translateByRealStep: 15 @ 10. self assert: camera bounds = ( 15@10 corner: 515@510). "camera translateByRealStep: -15 @ -10. self assert: camera bounds = ( 0@0 corner: 500@500)."! ! !ROViewTest methodsFor: 'dragging' stamp: 'AlexandreBergel 1/2/2013 09:19'! testDraggingViewAndPopupOnElement " self debug: #testDraggingViewAndPopupOnElement " | el popup | view := ROView new. el := ROElement spriteOn: 12. el @ ROPopup. view add: el. view @ RODraggable; @ RODraggableWithVelocity. view camera windowSize: 500 @ 500. el announce: (ROMouseEnter new position: 0@0). self assert: view elements size = 2. popup := view elements second. self assert: popup position = (10@10). el announce: ROMouseLeave. "We do a drag and drop of the view, and we mouse enter again" view translateBy: 50@60. el announce: (ROMouseEnter new realPosition: 50@60). popup := view elements second. self assert: popup position = (10@10). el announce: ROMouseLeave. " view open "! ! !ROViewTest methodsFor: 'tests'! testElementAt self assert: (view elementAt: node1 bounds center) == node1. self assert: (view elementAt: node2 bounds center) == node2. self assert: (view elementAt: node2 bounds bottomRight + (1 @ 1)) == view ! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 21:07'! testElementAt2 node1 translateBy: (-20 @ -20). self assert: (view elementAt: (node1 bottomRight - (5@5))) == node1. ! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 21:07'! testElementAt3 | node aPoint | node := ROElement sprite extent: (100@100); add: (ROElement sprite). view add: node. self assert: (view elementAt: (node bottomRight - (5@5))) == node. node translateBy: -20 @ -20. aPoint := node bottomRight - (5@5). self assert: (node contains: aPoint). self assert: (view elementAt: aPoint) == node. ! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 14:28'! testElementsToRenderDo | t | t := OrderedCollection new. view elementsToRenderDo: [ :el | t add: el ]. self assert: t asArray = view elements.! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 14:28'! testElementsToRenderReverseDo | t | t := OrderedCollection new. view elementsToRenderReverseDo: [ :el | t add: el ]. self assert: t asArray = view elements reverse! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 6/3/2012 15:13'! testEncompassingRectangle self assert: view encompassingRectangle = ((0@0) corner: (140@60)). node1 translateBy: 6@9. self assert: view encompassingRectangle = ((6@9) corner: (140@60)).! ! !ROViewTest methodsFor: 'events'! testEvents | t | t := 0. view announce: RORefreshNeeded. self assert: t isZero. view on: RORefreshNeeded do: [ :event | t := t + 1 ]. view announce: RORefreshNeeded. self assert: t = 1. ! ! !ROViewTest methodsFor: 'mondrian' stamp: 'AlexandreBergel 12/10/2012 20:00'! testMondrian | rawView | view := ROMondrianViewBuilder new. view node: 'foo' forIt: [ view nodes: (1 to: 2). view edgeFromAssociation: 1 -> 2. ]. view applyLayout. rawView := view raw. self assert: rawView numberOfElementsToRender = 4.! ! !ROViewTest methodsFor: 'animations' stamp: 'AlexandreBergel 5/2/2013 19:05'! testNumberOfAnimation self assert: ROView new numberOfAnimations = 0. self assert: (ROView new addAnimation: ROMotionMove new; numberOfAnimations) = 1. ! ! !ROViewTest methodsFor: 'opening' stamp: 'AlexandreBergel 11/23/2012 08:35'! testOpenInWindow | window | window := view open. window delete! ! !ROViewTest methodsFor: 'opening' stamp: 'AlexandreBergel 5/10/2012 16:41'! testOpenInWindowSized | window | [ window := view openInWindowSized: 400@30. self assert: window extent >= (400@30).] ensure: [ window delete ]! ! !ROViewTest methodsFor: 'overlapping' stamp: 'AlexandreBergel 9/28/2012 08:30'! testOverlapping | greenNode | "greenNode is overlapping node1" greenNode := ROElement spriteOn: 'green node'. greenNode setBounds: (node1 bounds translateBy: 5@6 ). view add: greenNode. "-----" self assert: (view elementAt: node1 bounds topLeft) == node1. self assert: (view elementAt: greenNode bounds topLeft) == greenNode ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 2/23/2013 20:09'! testRemovingAllElementToRender emptyView add: ROElement sprite. emptyView add: ROElement sprite. self assert: emptyView numberOfElementsToRender = 2. self assert: emptyView numberOfElements = 2. emptyView removeAllElementsToRender. self assert: emptyView numberOfElementsToRender = 0. self assert: emptyView numberOfElements = 2! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 06:40'! testRemovingNestedRenderingElements | spr spr2 | spr := ROElement sprite. spr2 := ROElement sprite. spr add: spr2. emptyView add: spr. self assert: emptyView numberOfElementsToRender = 2. self assert: emptyView numberOfElements = 1. spr remove. self assert: emptyView numberOfElementsToRender = 0. self assert: emptyView numberOfElements = 0. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 06:27'! testRemovingRenderingElements | spr | spr := ROElement sprite. emptyView add: spr. self assert: emptyView numberOfElementsToRender = 1. self assert: emptyView numberOfElements = 1. spr remove. self assert: emptyView numberOfElementsToRender = 0. self assert: emptyView numberOfElements = 0. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 11:49'! testRemovingRenderingElementsAndPopup | spr | spr := ROElement sprite. spr @ ROPopup. self assert: emptyView numberOfElements = 0. emptyView add: spr. spr announce: ROMouseEnter. "Because the popup has two elements" self assert: emptyView numberOfElementsToRender = 3. self assert: emptyView numberOfElements = 2. spr announce: ROMouseLeave. self assert: emptyView numberOfElementsToRender = 1. self assert: emptyView numberOfElements = 1. ! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'VanessaPena 3/12/2013 15:30'! testRendering | el1 el2 canvas | view := ROView new. el1 := ROElement new + ROBox. el1 extent: 30 @ 30. el2 := ROElement new + ROEllipse blue. el2 extent: 30 @ 30. view add: el1; add: el2. canvas := ROTracingCanvas new. view drawOn: canvas. self assert: canvas trace = #( #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(0@0) corner: (30@30)' 'Color veryLightGray' 0 'Color black') #(#fillOval: '(0@0) corner: (30@30)' 0 'Color blue'))! ! !ROViewTest methodsFor: 'running' stamp: 'AlexandreBergel 7/19/2013 19:37'! testRenderingElementAndDraggingView | el | view := ROView new. view add: (el := ROElement sprite). view windowSize: 500 @ 500. view @ RODraggable. view drawOn: RONullCanvas new. self assert: el isRendered. view announce: (ROMouseDragging step: -100 @ -100). view drawOn: RONullCanvas new. self assert: el isRendered not. view announce: (ROMouseDragging step: 100 @ 100). view drawOn: RONullCanvas new. self assert: el isRendered.! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/10/2012 19:31'! testRenderingElements emptyView add: ROElement sprite. self assert: emptyView numberOfElementsToRender = 1! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/10/2012 19:31'! testRenderingElements2 emptyView add: (ROElement sprite add: ROElement sprite). self assert: emptyView numberOfElementsToRender = 2! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 15:17'! testRenderingElements3 | spr | spr := ROElement sprite. emptyView add: spr. spr add: ROElement sprite. self assert: emptyView numberOfElementsToRender = 2. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 15:17'! testRenderingElements4 self deny: (ROElement sprite isRendered)! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 5/7/2013 19:46'! testRenderingElements5 | spr | spr := ROElement sprite. emptyView add: spr. self assert: emptyView numberOfElementsToRender = 1. spr setAsNotRendered. self assert: emptyView numberOfElementsToRender = 1. self assert: spr isRendered. spr view cleanRenderingElement. self assert: emptyView numberOfElementsToRender = 0. self deny: spr isRendered. spr setAsRendered. self assert: emptyView numberOfElementsToRender = 0. self deny: spr isRendered. spr view cleanRenderingElement. self assert: emptyView numberOfElementsToRender = 1. self assert: spr isRendered. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 5/7/2013 19:47'! testRenderingElements6 | spr1 spr2 edge | spr1 := ROElement sprite. spr2 := ROElement sprite. edge := ROEdge lineFrom: spr1 to: spr2. emptyView add: spr1; add: spr2; add: edge. self assert: emptyView numberOfElementsToRender = 3. edge setAsNotRendered. self assert: emptyView numberOfElementsToRender = 3. self assert: edge isRendered. edge view cleanRenderingElement. self assert: emptyView numberOfElementsToRender = 2. self deny: edge isRendered. edge setAsRendered. self assert: emptyView numberOfElementsToRender = 2. self deny: edge isRendered. edge view cleanRenderingElement. self assert: emptyView numberOfElementsToRender = 3. self assert: edge isRendered. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 6/10/2013 09:47'! testRenderingElements7 | spr1 spr2 canvas | canvas := ROTracingCanvas new. emptyView add: (spr1 := ROElement sprite). emptyView add: (spr2 := ROElement sprite). self assert: emptyView numberOfElementsToRender = 2. spr1 setAsNotRendered. spr2 setAsNotRendered. emptyView drawOn: canvas. self assert: emptyView numberOfElementsToRender = 0 ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 6/10/2013 09:55'! testRenderingElements8 | spr1 spr2 | emptyView add: (spr1 := ROElement sprite). emptyView add: (spr2 := ROElement sprite). emptyView drawOn: ROTracingCanvas new. spr1 setAsNotRendered. spr2 setAsNotRendered. emptyView drawOn: ROTracingCanvas new. self assert: emptyView numberOfElementsToRender = 0. emptyView makeAllElementAsRendered. self assert: emptyView numberOfElementsToRender = 2. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 6/10/2013 10:14'! testRenderingElements9 | spr1 spr2 | emptyView add: (spr1 := ROElement sprite). emptyView add: (spr2 := ROElement sprite). emptyView drawOn: ROTracingCanvas new. spr1 setAsNotRendered. emptyView drawOn: ROTracingCanvas new. self assert: emptyView numberOfElementsToRender = 1. emptyView makeAllElementAsRendered. self assert: emptyView numberOfElementsToRender = 2. ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 15:17'! testRenderingElementsTesting | el | emptyView add: (el := ROElement sprite). self assert: (emptyView numberOfElementsToRender = 1). self assert: (emptyView isRendered: el). self assert: (el isRendered)! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/10/2012 19:43'! testRenderingEmptyViewOnCanvas | canvas | canvas := ROTracingCanvas new. ROView new drawOn: canvas. self assert: canvas trace size = 1. self assert: canvas trace first = #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white')! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 4/24/2013 08:29'! testRenderingNestedElementOnCanvas | canvas | canvas := ROTracingCanvas new. view := ROView new. view add: (ROElement sprite add: ROElement sprite). view drawOn: canvas. self assert: canvas trace size = 9. self assert: canvas trace asArray = #( #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#line '(0@0)' '(60@0)' 1 'Color red') #(#line '(60@0)' '(60@60)' 1 'Color red') #(#line '(60@60)' '(0@60)' 1 'Color red') #(#line '(0@60)' '(0@0)' 1 'Color red') #(#line '(5@5)' '(55@5)' 1 'Color red') #(#line '(55@5)' '(55@55)' 1 'Color red') #(#line '(55@55)' '(5@55)' 1 'Color red') #(#line '(5@55)' '(5@5)' 1 'Color red') ) ! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/11/2012 06:23'! testRenderingOnCanvas | canvas | canvas := ROTracingCanvas new. view := ROView new. view add: ROElement sprite. view drawOn: canvas. self assert: canvas trace size = 5. self assert: canvas trace first = #(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white'). self assert: canvas trace second = #(#line '(0@0)' '(50@0)' 1 'Color red'). self assert: canvas trace third = #(#line '(50@0)' '(50@50)' 1 'Color red'). self assert: canvas trace fourth = #(#line '(50@50)' '(0@50)' 1 'Color red'). self assert: canvas trace fifth = #(#line '(0@50)' '(0@0)' 1 'Color red').! ! !ROViewTest methodsFor: 'rendering' stamp: 'AlexandreBergel 12/10/2012 19:15'! testRenderingWithoutElement self assert: emptyView numberOfElementsToRender = 0. self assert: emptyView elementsToRender = #()! ! !ROViewTest methodsFor: 'events' stamp: 'AlexandreBergel 11/15/2012 16:25'! testResizingViewAndEvent | e oldExtent | view := ROView new. view on: ROWindowResized do: [ :event | e := event ]. self assert: e isNil. oldExtent := view camera windowSize. view windowSize: 40 @ 60. self assert: e notNil. self assert: e class == ROWindowResized. self assert: e oldExtent = oldExtent. self assert: e extent = (40 @ 60)! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 13:26'! testSortedCollection "We are just testing a property of the sorted collection. This is useful when migrating to other platform to see whether this important invariant is preserved or not" | col el1 el2 el3 | col := SortedCollection sortBlock: [ :a :b | a model < b model ]. col add: (el1 := ROElement on: 1). col add: (el2 := ROElement on: 2). self assert: (col indexOf: el1) = 1. self assert: (col indexOf: el2) = 2. col add: (el3 := ROElement on: 2). self assert: (col indexOf: el1) = 1. self assert: (col indexOf: el3) = 2. self assert: (col indexOf: el2) = 3. ! ! !ROViewTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2012 13:55'! testSortingElements | nodes nodes2 | nodes := ROElement forCollection: #(1 2 3). emptyView addAll: nodes. nodes2 := emptyView elementsSuchThat: [ :v | true ]. self assert: (nodes2 collect: #model) asArray = #(1 2 3). emptyView sortElementsWith: [ :a :b | a model > b model ]. nodes2 := emptyView elementsSuchThat: [ :v | true ]. self assert: (nodes2 collect: #model) asArray = #(3 2 1). ! ! !ROViewTest methodsFor: 'camera'! testTranslatingCamera | camera | camera := view camera. self assert: camera bounds = ( 0@0 corner: 500@500). camera translateBy: 15 @ 10. self assert: camera bounds = ( 15@10 corner: 515@510). camera translateBy: -15 @ -10. self assert: camera bounds = ( 0@0 corner: 500@500).! ! !ROViewTest methodsFor: 'dragging' stamp: 'AlexandreBergel 6/12/2013 19:26'! testTranslatingView | camera e | view := ROView new. camera := view camera. view @ RODraggable. view add: (e := ROBox element extent: 20 @ 20). self assert: camera position = (0 @ 0). self assert: ((camera virtualToRealPoint: e position) = (0 @ 0)). view translateByRealPoint: 20 @ 30. self assert: ((camera virtualToRealPoint: e position) = (20 @ 30)). ! ! !ROViewTest methodsFor: 'camera'! testVisibleBounds | window | self assert: view camera bounds = ( 0@0 corner: 500@500). window := view open. window delete. self assert: view camera bounds = ( 0@0 corner: 500@500). ! ! !ROViewTest methodsFor: 'opening' stamp: 'AlexandreBergel 4/30/2012 15:26'! testWindowTitle | window | window := (view := self viewClass titled: 'Hello World') open. [ self assert: window labelString = 'Hello World'. self assert: view title = 'Hello World' ] ensure: [ window delete ]! ! !ROViewTest methodsFor: 'opening' stamp: 'AlexandreBergel 5/22/2012 21:01'! testWindowTitleDefault | window | window := self viewClass new open. [ self assert: window labelString = ROView defaultWindowTitle ] ensure: [ window delete ]! ! !ROViewTest methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/11/2012 21:07'! testzOrderingError self assert: (view numberOfElements > 0). self shouldnt: [ view zOrdering: ROZOrdering new ] raise: Error! ! !ROViewTest methodsFor: 'running' stamp: 'AlexandreBergel 4/30/2012 15:25'! viewClass ^ ROView! ! !ROCountingVisitorTest methodsFor: 'tests'! test | visitor | visitor := ROCountingVisitor new. self assert: visitor nbOfEdges isZero. self assert: visitor nbOfNodes isZero. visitor runOn: view. self assert: visitor nbOfEdges = 3. self assert: visitor nbOfNodes = 5. ! ! !ROVisitorTest class methodsFor: 'as yet unclassified'! isAbstract ^ self name == #ROVisitorTest! ! !ROVisitorTest methodsFor: 'running' stamp: 'AlexandreBergel 4/17/2012 17:02'! setUp | elements | view := ROView new. elements := ROElement forCollection: (1 to: 5). elements do: [ :el | el + ROBox ]. view addAll: elements. view addAll: (ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third ))! ! !ROVisitorTest methodsFor: 'tests' stamp: 'AlexandreBergel 11/21/2012 08:52'! test | visitor | visitor := ROVisitor new. visitor runOn: view.! ! !ROWiggleTest commentStamp: '' prior: 34279478! A ROWiggleTest is a test class for testing the behavior of ROWiggle! !ROWiggleTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 10:01'! testBasic | view el wiggle | view := ROView new. el := ROBox element. view add: el. self assert: el position = (0 @ 0). wiggle := ROWiggle on: el. self assert: el position = (0 @ 0). self assert: wiggle elapsedCycles = 0. view doAnimationCycle. self assert: el position = (3 @ 0). self assert: wiggle elapsedCycles = 1. view doAnimationCycle. self assert: el position = (0 @ 0). self assert: wiggle elapsedCycles = 2. ! ! !ROWiggleTest methodsFor: 'tests' stamp: 'AlexandreBergel 5/22/2013 10:14'! testToAll | view el1 el2 | view := ROView new. el1 := ROBox element. el2 := ROBox element. view add: el1; add: el2. ROWiggle onAll: (Array with: el1 with: el2). view doAnimationCycle. self assert: el1 position = (3 @ 0). self assert: el2 position = (3 @ 0).! ! !ROZOrderingTest methodsFor: 'running' stamp: 'AlexandreBergel 12/3/2012 21:05'! setUp super setUp. zordering := ROZOrdering new! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/13/2012 18:14'! test | view c1 c2 c3 c4 | zordering setZIndex: 10 if: #isEdge. zordering setZIndex: 20 if: #isNotEdge. view := ROView new. view zOrdering: zordering. view add: (c1 := ROEdge new). view add: (c2 := ROElement new). view add: (c3 := ROEdge new). view add: (c4 := ROElement new). self assert: c1 zIndex = 10. self assert: c2 zIndex = 20. self assert: c3 zIndex = 10. self assert: c4 zIndex = 20. self assert: view zOrdering == zordering. self assert: view numberOfElementsToRender = 4. self assert: view elementsToRender = (Array with: c1 with: c3 with: c2 with: c4)! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/3/2012 21:06'! testDefault self assert: (zordering zIndexOf: ROElement new) = 0! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/13/2012 18:14'! testDefaultValue zordering setZIndex: 10 if: true. self assert: zordering numberOfEntries = 1. self assert: (zordering zIndexOf: ROElement new) = 10! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 1/25/2013 08:31'! testDefaultValueWithoutIf zordering setZIndex: 10. self assert: zordering numberOfEntries = 1. self assert: (zordering zIndexOf: ROElement new) = 10! ! !ROZOrderingTest methodsFor: 'dynamic' stamp: 'AlexandreBergel 12/13/2012 18:14'! testDynamic | el1 el2 | zordering setZIndex: [ :element | element depth + 1 ] if: true. el1 := ROElement new. el2 := ROElement new. el1 add: el2. self assert: (zordering zIndexOf: el1) = 2. self assert: (zordering zIndexOf: el2) = 3.! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/3/2012 21:05'! testInitialization self assert: zordering numberOfEntries = 0! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/10/2012 20:09'! testView self assert: ROView new zOrdering notNil! ! !ROZOrderingTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/12/2013 14:15'! testWithEdgesAndNestingWithMondrian | view edge canvas | view := ROMondrianViewBuilder new. view node: 1 forIt: [ view shape rectangle fillColor: Color red. view node: 11]. view node: 2 forIt: [ view shape rectangle fillColor: Color green. view node: 22]. view node: 3 forIt: [ view shape rectangle fillColor: Color blue. view node: 33]. view shape line width: 3. view edgeFromAssociation: 11->33. view applyLayout. "Check the zIndex" "- nodes 1,2,3: zIndex 2 - nodes 11,22,33: zIndex 4 - edge: zIndex 3" self assert: (view elementFromModel: 1) zIndex = 2. self assert: (view elementFromModel: 3) zIndex = 2. self assert: (view elementFromModel: 11) zIndex = 4. self assert: (view elementFromModel: 33) zIndex = 4. edge := view raw elementsAsEdge anyOne. self assert: edge zIndex = 3. "Check the list of elements to render" self assert: ((view raw elementsToRender collect: #model) = ((Array new: 7) at: 1 put: 1; at: 2 put: 2; at: 3 put: 3; at: 4 put: (11->33); at: 5 put: 11; at: 6 put: 22; at: 7 put: 33; yourself)). "Check the trace for the first render" canvas := ROTracingCanvas new. view raw drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(5@5) corner: (20@20)' 'Color white' 1 'Color black') #(#frameAndFillRectangle: '(30@5) corner: (45@20)' 'Color white' 1 'Color black') #(#frameAndFillRectangle: '(55@5) corner: (70@20)' 'Color white' 1 'Color black') #(#line '(60@12)' '(15@12)' 3 'Color veryLightGray') #(#frameAndFillRectangle: '(10@10) corner: (15@15)' 'Color red' 1 'Color black') #(#frameAndFillRectangle: '(35@10) corner: (40@15)' 'Color green' 1 'Color black') #(#frameAndFillRectangle: '(60@10) corner: (65@15)' 'Color blue' 1 'Color black')). "Check the trace for the second render" view open delete. self assert: ((view raw elementsToRender collect: #model) = ((Array new: 7) at: 1 put: 1; at: 2 put: 2; at: 3 put: 3; at: 4 put: (11->33); at: 5 put: 11; at: 6 put: 22; at: 7 put: 33; yourself)). canvas := ROTracingCanvas new. view raw drawOn: canvas. self assert: canvas trace = #(#(#frameAndFillRectangle: '(0@0) corner: (40@30)' 'Color white' 0 'Color white') #(#frameAndFillRectangle: '(5@5) corner: (20@20)' 'Color white' 1 'Color black') #(#frameAndFillRectangle: '(30@5) corner: (45@20)' 'Color white' 1 'Color black') #(#frameAndFillRectangle: '(55@5) corner: (70@20)' 'Color white' 1 'Color black') #(#line '(60@12)' '(15@12)' 3 'Color veryLightGray') #(#frameAndFillRectangle: '(10@10) corner: (15@15)' 'Color red' 1 'Color black') #(#frameAndFillRectangle: '(35@10) corner: (40@15)' 'Color green' 1 'Color black') #(#frameAndFillRectangle: '(60@10) corner: (65@15)' 'Color blue' 1 'Color black')). ! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 10:32'! setUp stack := ROViewStack new.! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 11:13'! testAddView |view viewToAdd zoom| view := ROView new. viewToAdd := ROView new. zoom := ROZoomIntoElementOnClick new stack: stack; view: viewToAdd. view add: (ROElement sprite @zoom). stack addView: view. view elements first announce: ROMouseLeftClick. view doAllAnimationCycles. self assert: (stack viewsSize = 2). self assert: (stack firstView = viewToAdd ) ! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 11:13'! testAddViewAsBlock |view zoom| view := ROView new. zoom := ROZoomIntoElementOnClick new. zoom stack: stack; view: [:el | |v| v := ROView new. v ]. view add: (ROElement sprite @zoom). stack addView: view. view elements first announce: ROMouseLeftClick. view doAllAnimationCycles. self assert: (stack viewsSize = 2). self assert: (stack firstView elements size = 0) ! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 12:39'! testRecursive |view zoom| view := ROView new. zoom := ROZoomIntoElementOnClick new. zoom stack: stack; view: [:el | |v| v := ROView new. v add: ROElement sprite. v]; recursive: true. view add: (ROElement sprite @zoom). stack addView: view. (1 to: 2) do: [:n | stack firstView elements first announce: ROMouseLeftClick. stack firstView doAllAnimationCycles. self assert: (stack viewsSize = (n +1)). ]. (1 to: 2) do: [:n | stack firstView announce: ROMouseRightClick. stack firstView doAllAnimationCycles. self assert: (stack viewsSize = (3 - n)). ].! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 11:28'! testRemoveView |view zoom viewToAdd| view := ROView new. zoom := ROZoomIntoElementOnClick new. zoom stack: stack; view: (viewToAdd := ROView new). viewToAdd add: ROElement sprite. view add: (ROElement sprite @zoom). stack addView: view. view elements first announce: ROMouseLeftClick. view doAllAnimationCycles. self assert: (stack viewsSize = 2). self assert: (stack firstView = viewToAdd). viewToAdd announce: ROMouseRightClick. viewToAdd doAllAnimationCycles. self assert: (stack viewsSize = 1). self assert: (stack firstView = view). ! ! !ROZoomIntoElementOnClickTest methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/8/2013 13:07'! testZoomMove |view move| view := ROView new. view camera bounds: (0@0 corner: 200@200). move := ROZoomMove new. move nbCycles: 10. move on: view to: (0@0 corner: 50@50). (1 to: 10) do: [:n | move doStep]. self assert: (view camera bounds = (0@0 corner: 50@50)). ! ! !ROZoomOnClickTest methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 7/16/2012 08:11'! testZoomOnClick | view | view := ROView new. view add: (ROElement sprite @ ROZoomOnClick ). view elements first announce: ROMouseClick! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'VanessaPena 3/12/2013 16:13'! testCircle |view element visitor| view := ROView new. element := (ROElement new on: 'My Model') + (ROEllipse new color: Color green). view add: element. visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents = ' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "My Model", nodeWidth: 5, nodeHeight: 5, x: 0, y: 0, nodeParentID: 0, draggable: "false"}, { nodeID: 2, nodeParentID: 1, nodeShape: "ROEllipse", nodeWidth: 5, nodeHeight: 5, x: 0, y: 0, nodeFillColor: "#00FF00", nodeBorderColor: "#000000", nodeBorderWidth: "0", draggable: "false"}, ], '). self assert: (visitor linksStream contents = ' links:[ ] ') ! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'VanessaPena 1/31/2013 18:22'! testLabel |view element visitor w| view := ROView new. element := (ROElement spriteOn: 'My Model') + ROLabel. view add: element. w := element width. visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents = (' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "My Model", nodeWidth: ', w printString ,', nodeHeight: 50, x: 0, y: 0, nodeParentID: 0, draggable: "true"}, { nodeID: 2, nodeParentID: 1, nodeModel: "My Model", nodeShape: "ROLabel", nodeWidth: ', w printString ,', nodeHeight: 50, x: 0, y: 10, nodeFillColor: "none", nodeBorderColor: "#000000", draggable: "true"},{ nodeID: 3, nodeParentID: 1, nodeShape: "ROBorder", nodeWidth: ', w printString ,', nodeHeight: 50, x: 0, y: 0, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"}, ], ')). self assert: (visitor linksStream contents = ' links:[ ] ') ! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'miltonmamani 4/17/2013 14:56'! testLinks |view node1 node2 visitor edge| view := ROView new. node1 := (ROElement spriteOn: 'node1') + (ROBox new color: (Color r: 0 g: 0 b: 1)). node2 := (ROElement spriteOn: 'node2') + (ROBox new color: (Color r: 0 g: 0 b: 1)). node2 translateBy: 200@200. edge := ROEdge from: node1 to: node2. edge + (ROLine new color: Color black). view add: node1; add: node2; add: edge. visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents = ' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "node1", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeParentID: 0, draggable: "true"}, { nodeID: 2, nodeParentID: 1, nodeShape: "ROBox", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeFillColor: "#0000FF", nodeBorderColor: "#000000", nodeBorderWidth: "0", draggable: "true"},{ nodeID: 3, nodeParentID: 1, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 5, nodeShape: "ROElement", nodeModel: "node2", nodeWidth: 50, nodeHeight: 50, x: 200, y: 200, nodeParentID: 0, draggable: "true"}, { nodeID: 6, nodeParentID: 5, nodeShape: "ROBox", nodeWidth: 50, nodeHeight: 50, x: 200, y: 200, nodeFillColor: "#0000FF", nodeBorderColor: "#000000", nodeBorderWidth: "0", draggable: "true"},{ nodeID: 7, nodeParentID: 5, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 200, y: 200, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"}, ], '). self assert: (visitor linksStream contents = ' links:[ { sourceID: "1", targetID: "5", edgeColor: "#000000", edgeWidth: "1"}, ] ')! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'VanessaPena 1/31/2013 18:16'! testNestedNodes |view element visitor children| view := ROView new. element := (ROElement on: 'parent') + ROBorder new. children := ROElement spritesOn: (1 to: 6). element addAll: children. ROGridLayout new on: element elements . view add: element . visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents = ' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "parent", nodeWidth: 180, nodeHeight: 120, x: 0, y: 0, nodeParentID: 0, draggable: "false"}, { nodeID: 2, nodeParentID: 1, nodeShape: "ROBorder", nodeWidth: 180, nodeHeight: 120, x: 0, y: 0, nodeFillColor: "none", nodeBorderColor: "#000000", draggable: "false"},{ nodeID: 4, nodeShape: "ROElement", nodeModel: "1", nodeWidth: 50, nodeHeight: 50, x: 5, y: 5, nodeParentID: 1, draggable: "true"}, { nodeID: 5, nodeParentID: 4, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 5, y: 5, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 7, nodeShape: "ROElement", nodeModel: "2", nodeWidth: 50, nodeHeight: 50, x: 65, y: 5, nodeParentID: 1, draggable: "true"}, { nodeID: 8, nodeParentID: 7, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 65, y: 5, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 10, nodeShape: "ROElement", nodeModel: "3", nodeWidth: 50, nodeHeight: 50, x: 125, y: 5, nodeParentID: 1, draggable: "true"}, { nodeID: 11, nodeParentID: 10, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 125, y: 5, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 13, nodeShape: "ROElement", nodeModel: "4", nodeWidth: 50, nodeHeight: 50, x: 5, y: 65, nodeParentID: 1, draggable: "true"}, { nodeID: 14, nodeParentID: 13, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 5, y: 65, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 16, nodeShape: "ROElement", nodeModel: "5", nodeWidth: 50, nodeHeight: 50, x: 65, y: 65, nodeParentID: 1, draggable: "true"}, { nodeID: 17, nodeParentID: 16, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 65, y: 65, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 19, nodeShape: "ROElement", nodeModel: "6", nodeWidth: 50, nodeHeight: 50, x: 125, y: 65, nodeParentID: 1, draggable: "true"}, { nodeID: 20, nodeParentID: 19, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 125, y: 65, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"}, ], '). self assert: (visitor linksStream contents = ' links:[ ] ')! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'VanessaPena 1/31/2013 18:18'! testNestedNodes2 |view element visitor children| view := ROView new. element := (ROElement on: 'parent') + ROBorder new. children := ROElement spritesOn: (1 to: 2). element addAll: children. children do: [:node | node addAll: (ROElement spritesOn: (1 to: 3)). ROGridLayout new on: node elements. ]. ROGridLayout new on: element elements. view add: element . visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents = ' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "parent", nodeWidth: 260, nodeHeight: 130, x: 0, y: 0, nodeParentID: 0, draggable: "false"}, { nodeID: 2, nodeParentID: 1, nodeShape: "ROBorder", nodeWidth: 260, nodeHeight: 130, x: 0, y: 0, nodeFillColor: "none", nodeBorderColor: "#000000", draggable: "false"},{ nodeID: 4, nodeShape: "ROElement", nodeModel: "1", nodeWidth: 120, nodeHeight: 120, x: 5, y: 5, nodeParentID: 1, draggable: "true"}, { nodeID: 5, nodeParentID: 4, nodeShape: "ROBorder", nodeWidth: 120, nodeHeight: 120, x: 5, y: 5, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 7, nodeShape: "ROElement", nodeModel: "1", nodeWidth: 50, nodeHeight: 50, x: 10, y: 10, nodeParentID: 4, draggable: "true"}, { nodeID: 8, nodeParentID: 7, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 10, y: 10, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 10, nodeShape: "ROElement", nodeModel: "2", nodeWidth: 50, nodeHeight: 50, x: 70, y: 10, nodeParentID: 4, draggable: "true"}, { nodeID: 11, nodeParentID: 10, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 70, y: 10, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 13, nodeShape: "ROElement", nodeModel: "3", nodeWidth: 50, nodeHeight: 50, x: 10, y: 70, nodeParentID: 4, draggable: "true"}, { nodeID: 14, nodeParentID: 13, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 10, y: 70, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 16, nodeShape: "ROElement", nodeModel: "2", nodeWidth: 120, nodeHeight: 120, x: 135, y: 5, nodeParentID: 1, draggable: "true"}, { nodeID: 17, nodeParentID: 16, nodeShape: "ROBorder", nodeWidth: 120, nodeHeight: 120, x: 135, y: 5, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 19, nodeShape: "ROElement", nodeModel: "1", nodeWidth: 50, nodeHeight: 50, x: 140, y: 10, nodeParentID: 16, draggable: "true"}, { nodeID: 20, nodeParentID: 19, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 140, y: 10, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 22, nodeShape: "ROElement", nodeModel: "2", nodeWidth: 50, nodeHeight: 50, x: 200, y: 10, nodeParentID: 16, draggable: "true"}, { nodeID: 23, nodeParentID: 22, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 200, y: 10, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"},{ nodeID: 25, nodeShape: "ROElement", nodeModel: "3", nodeWidth: 50, nodeHeight: 50, x: 140, y: 70, nodeParentID: 16, draggable: "true"}, { nodeID: 26, nodeParentID: 25, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 140, y: 70, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"}, ], '). self assert: (visitor linksStream contents = ' links:[ ] ')! ! !RoassalExporterHTMLTest methodsFor: 'tests' stamp: 'VanessaPena 3/12/2013 16:13'! testShapeComposition |view element visitor| view := ROView new. element := (ROElement spriteOn: 'My Model') + (ROEllipse new color: Color green). view add: element. visitor := ROHTMLVisitor new runOn: view. self assert: (visitor nodesStream contents =' nodes:[ { nodeID: 1, nodeShape: "ROElement", nodeModel: "My Model", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeParentID: 0, draggable: "true"}, { nodeID: 2, nodeParentID: 1, nodeShape: "ROEllipse", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeFillColor: "#00FF00", nodeBorderColor: "#000000", nodeBorderWidth: "0", draggable: "true"},{ nodeID: 3, nodeParentID: 1, nodeShape: "ROBorder", nodeWidth: 50, nodeHeight: 50, x: 0, y: 0, nodeFillColor: "none", nodeBorderColor: "#FF0000", draggable: "true"}, ], '). self assert: (visitor linksStream contents = ' links:[ ] ') ! ! !RoassalExporterSVGTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/9/2013 18:43'! testBasic |view edges n1 n2 n3 canvas| view := ROView new. n1 := ROElement spriteOn: 1. n2 := ROElement spriteOn: 2. n3 := ROElement spriteOn: 3. edges := ROEdge linesFor: (Array with: (n1 -> n2) with: (n1 -> n3)). edges do: [:e | (e getShape: ROLine) color: Color blue]. view add: n1; add: n2; add: n3; addAll: edges. ROTreeLayout on: view elements. canvas := ROSVGCanvas onCamera: view camera. canvas view: view. canvas addStart. view drawOn: canvas. canvas addEnd. self assert: canvas stream contents = ' '! ! !RoassalExporterSVGTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/4/2013 08:45'! testLine |view n1 n2 canvas edge| view := ROView new. n1 := (ROElement on: 'n1') + (ROBox new color: Color red). n2 := (ROElement on: 'n2') + (ROBox new color: Color red). n2 translateBy: 100@100. edge := ROEdge from: n1 to: n2. edge + (ROLine red). view add: n1; add: n2; add: edge. canvas := ROSVGCanvas onCamera: view camera. canvas view: view. canvas addStart. view drawOn: canvas. canvas addEnd. self assert: canvas stream contents = ' '! ! !RoassalExporterSVGTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/4/2013 08:45'! testNesting |view node ch1 ch2 ch3 canvas| view := ROView new. node := ROElement spriteOn: 'node'. ch1 := (ROElement on: 'ch1') + (ROBox new color: Color green). ch2 := (ROElement on: 'ch2') + (ROBox new color: Color green). ch3 := (ROElement on: 'ch3') + (ROBox new color: Color green). node add: ch1; add: ch2; add: ch3. ROGridLayout on: node elements. view add: node. canvas := ROSVGCanvas onCamera: view camera. canvas view: view. canvas addStart. view drawOn: canvas. canvas addEnd. self assert: canvas stream contents = ' '! ! !RoassalExporterSVGTest methodsFor: 'tests' stamp: 'miltonmamani 4/17/2013 14:57'! testOval |view n1 canvas | view := ROView new. n1 := (ROElement on: 1) + (ROEllipse new color: (Color r: 0 g: 0.5 b: 0.5)); yourself . n1 size: 200. view add: n1. canvas := ROSVGCanvas onCamera: view camera. canvas view: view. canvas addStart. view drawOn: canvas. canvas addEnd. self assert: canvas stream contents = ' '! ! !RoassalExporterSVGTest methodsFor: 'tests' stamp: 'AlexandreBergel 8/9/2013 18:41'! testView | view n1 canvas | view := ROView new. n1 := (ROElement on: 1) + (ROEllipse new color: (Color r: 0 g: 0.5 b: 0.5)); yourself . n1 size: 200. view add: n1. view translateBy: 100 @ 100. canvas := ROSVGCanvas onCamera: view camera. canvas view: view. canvas addStart. view drawOn: canvas. canvas addEnd. self assert: canvas stream contents = ' '! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 9/4/2012 15:23'! testBasicNodePositioning | layout view nodes edges root | "Setting up..." layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. view shape width: 400; height: 400. view nodes: (0 to: 76). edges := view edgesFrom: [ :each | each // 10 ]. view layout: layout. nodes := view nodes. root := nodes first. view applyLayout. nodes := layout recursiveChildrenSortedFor: root. "Check dimensions and position of root node." self assert: root extent = (400 @ 400). self assert: root bounds = ((5@5) corner: (405@405)). "These are relative bounds (to containment nodes bounds)." self assert: (nodes at: 1) bounds = ((5@5) corner: (44@91)). self assert: (nodes at: 2) bounds = ((43@5) corner: (122@91)). self assert: (nodes at: 3) bounds = ((121@5) corner: (238@91)). self assert: (nodes at: 8) bounds = ((126@177) corner: (252@395)). self assert: (nodes at: 33) bounds = ((5@46) corner: (29@81)). self assert: (nodes at: 49) bounds = ((102@53) corner: (153@81)). self assert: (nodes at: 67) bounds = ((47@79) corner: (117@106)). self assert: (nodes at: 76) bounds = ((223@5) corner: (264@83)).! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 12/11/2012 14:39'! testDeepNesting | layout view nodes interval o | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). layout inset: 5. layout minInset: 3. interval := 1 to: 30. view := ROMondrianViewBuilder new. view shape size: 240. view nodes: interval. o := OrderedCollection new. interval do: [ :each | o add: each -> (each+1)]. view edgesFromAssociations: o. view layout: layout. nodes := view nodes. view applyLayout. self assert: (nodes at: 1) extent = (240@240). self assert: (nodes at: 1) position = (5@5). self assert: (nodes at: 2) extent = (230@230). self assert: (nodes at: 2) position = (5@5). self assert: (nodes at: 4) extent = (210@210). self assert: (nodes at: 4) position = (5@5). self assert: (nodes at: 7) extent = (182@182). self assert: (nodes at: 7) position = (4@4). self assert: (nodes at: 11) extent = (150@150). self assert: (nodes at: 11) position = (4@4). self assert: (nodes at: 16) extent = (120@120). self assert: (nodes at: 16) position = (3@3). self assert: (nodes at: 22) extent = (84@84). self assert: (nodes at: 22) position = (3@3). self assert: (nodes at: 29) extent = (42@42). self assert: (nodes at: 29) position = (3@3). self assert: (nodes at: 30) extent = (36@36). self assert: (nodes at: 30) position = (3@3).! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/12/2013 15:46'! testDisplayOfManyChildren | layout view associations numberOfNodes | numberOfNodes := 800. layout := ROTreeMapLayout withWeightBlock: [ :e | e model ]. layout minAreaPerNode: 25. layout inset: 5. layout weightBlock: [ :e | e model squared ]. view := ROMondrianViewBuilder new. view shape rectangle size: 200. view nodes: (1 to: numberOfNodes). associations := Array new: numberOfNodes. (1 to: numberOfNodes) do: [ :i | associations at: i put: (1 -> i) ]. view edgesFromAssociations: associations. view layout: layout. "view open." view applyLayout. self assert: view nodes first elements size = 498 description: 'Not all 800 should be drawn, but only 498'. ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/12/2013 15:50'! testDisplayOfManyChildren2 | layout view associations numberOfNodes | numberOfNodes := 5000. layout := ROTreeMapLayout withWeightBlock: [ :e | e model ]. layout minAreaPerNode: 25. layout inset: 5. layout weightBlock: [ :e | e model squared ]. view := ROMondrianViewBuilder new. view shape rectangle size: 400. view nodes: (1 to: numberOfNodes). associations := Array new: numberOfNodes. (1 to: numberOfNodes) do: [ :i | associations at: i put: (1 -> i) ]. view edgesFromAssociations: associations. view layout: layout. "view open." view applyLayout. self assert: view nodes first elements size = 2773 description: 'Not all 5000 should be drawn, but only 2773'. ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'miltonmamani 4/17/2013 15:39'! testEdgeDrivenLayouting | view nodes rawEdges edges | view := ROMondrianViewBuilder new. view shape width: 200; height: 200. "view nodes: Collection withAllSubclasses. view edgesFrom: #superclass." nodes := view nodes: (1 to: 9). rawEdges := OrderedCollection new. rawEdges add: 1 -> 2; add: 1 -> 3; add: 2 -> 4; add: 3 -> 5; add: 5 -> 6; add: 6 -> 7; add: 7 -> 8; add: 8 -> 9. edges := view edgesFromAssociations: rawEdges. view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view applyLayout. "Testing right number of objects and ordering" self assert: nodes size = 9. self assert: edges size = 8. self assert: nodes first model = 1. "Testing bounds" self assert: (nodes first bounds = ((5@5) corner: (205@205))). self assert: (nodes second bounds = ((5@5) corner: (195@81))). self assert: (nodes third bounds = ((5@80) corner: (195@195))). self assert: ((nodes at: 8) bounds = ((5@5) corner: (155@80))). self assert: ((nodes at: 9) bounds = ((4@4) corner: (146@71))). "Testing z-index" self assert: nodes first zIndex = 1. self assert: nodes second zIndex = 2. self assert: nodes third zIndex = 2. self assert: nodes fourth zIndex = 3. self assert: nodes fifth zIndex = 3. self assert: (nodes at: 6) zIndex = 4. self assert: (nodes at: 7) zIndex = 5. self assert: (nodes at: 8) zIndex = 6. self assert: (nodes at: 9) zIndex = 7.! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'AlexandreBergel 4/24/2013 17:01'! testLayoutEmbedding | layout view outerModel outerNodes node1 node2 node3 | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. outerModel := (OrderedCollection with: 1). outerNodes := view nodes: outerModel forEach: [ :node | "Testing setting the size of the node that has the treemap layout." view shape rectangle size: 150. view nodes: (2 to: 3). view edgesFromAssociations: (Array with: 2 -> 3). view layout: layout. ]. view applyLayout. node1 := outerNodes at: 1. node2 := node1 elements at: 1. node3 := node2 elements at: 1. "Make sure outer node has grown corecctly." self assert: node1 extent = (165 @ 165). "Make sure the inner nodes have according sizes." self assert: node2 extent = (150@150). self assert: node3 extent = (140@140). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 9/19/2012 12:16'! testLayoutEmbedding2 | layout view outerModel outerNodes innerNodes node1 node2 node3 | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. outerModel := (OrderedCollection with: 1). "Testing setting the size of the node that is outside of the treemap layout." view shape rectangle size: 160. outerNodes := view nodes: outerModel forEach: [ :node | innerNodes := view nodes: (2 to: 3). view edgesFromAssociations: (Array with: 2 -> 3). view layout: layout. ]. view applyLayout. node1 := outerNodes at: 1. node2 := node1 elements at: 1. node3 := node2 elements at: 1. self assert: node1 extent = (160@160). self assert: node2 extent = (150@150). self assert: node3 extent = (140@140). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/12/2013 15:47'! testMinAreaOptimizations | layout view nodes | layout := ROTreeMapLayout withWeightBlock: [ :e | e model ]. layout minAreaPerNode: 25. view := ROMondrianViewBuilder new. view shape rectangle size: 15. view nodes: (1 to: 3). view edgesFromAssociations: (Array with: 1 -> 2 with: 1 -> 3). view layout: layout. view applyLayout. nodes := view nodes. "The node has lost its relation to its children... :(" self assert: nodes first elements isEmpty. "Make sure we only render the first node, and none of its children" self assert: view raw elementsToRender size = 1. "Also check for correct sizing" self assert: nodes first extent = (15@15). self assert: nodes first bounds = ((5@5) corner: (20@20)). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/12/2013 15:48'! testMinAreaOptimizations2 | layout view minAreaPerNode minAreaBreakPoint sizeBreakpoint inset numberOfNodes nodes o | minAreaPerNode := 25. inset := 3. numberOfNodes := 10. layout := ROTreeMapLayout withWeightBlock: [ :e | e model ]. layout inset: inset. layout minAreaPerNode: minAreaPerNode. minAreaBreakPoint := layout minAreaNeededFor: (2 to: (numberOfNodes - 1)). sizeBreakpoint := minAreaBreakPoint sqrt. view := ROMondrianViewBuilder new. view shape rectangle size: sizeBreakpoint + 40. view nodes: (1 to: numberOfNodes). o := OrderedCollection new. o add: 1->2; add: 1->3; add: 2->4; add: 1->5; add: 1->6; add: 4->7; add: 7->8; add: 7->9; add: 7->10. view edgesFromAssociations: o. view layout: layout. view applyLayout. nodes := view nodes. "In this confgration, exactly 7 nodes should be visible" self assert: view raw elementsToRender size = 7. ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 2/26/2013 16:24'! testMinAreaOptimizations3 | layout view minAreaPerNode minAreaBreakPoint sizeBreakpoint inset numberOfNodes nodes o | minAreaPerNode := 25. inset := 3. numberOfNodes := 10. layout := ROTreeMapLayout withWeightBlock: [ :e | e model ]. layout inset: inset. layout minAreaPerNode: minAreaPerNode. minAreaBreakPoint := layout minAreaNeededFor: (2 to: (numberOfNodes - 1)). sizeBreakpoint := minAreaBreakPoint sqrt. view := ROMondrianViewBuilder new. view shape rectangle size: sizeBreakpoint + 40. view nodes: (1 to: numberOfNodes). o := OrderedCollection new. o add: 1->2; add: 1->3; add: 2->4; add: 1->5; add: 1->6; add: 4->7; add: 7->8; add: 7->9; add: 7->10. view edgesFromAssociations: o. view layout: layout. view applyLayout. nodes := view nodes. "In this confgration, exactly 7 nodes should be visible" self assert: view raw elementsToRender size = 7. ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/13/2013 09:38'! testNestedNodePositioning | view nodes edges root | view := ROMondrianViewBuilder new. view shape rectangle size: 100. view nodes: (1 to: 4) forEach: [ :each | | innerNodes innerEdges | innerNodes := view nodes: (each*10 to: each*40 by: each*5) asOrderedCollection. innerEdges := view edgesFromAssociations: ((Array new: 6) at: 1 put: (each*10) -> (each*10+each*5*1); at: 2 put: (each*10) -> (each*10+each*5*2); at: 3 put: (each*10) -> (each*10+each*5*3); at: 4 put: (each*10) -> (each*10+each*5*4); at: 5 put: (each*10) -> (each*10+each*5*5); at: 6 put: (each*10) -> (each*10+each*5*6); yourself). view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ]. nodes := view nodes. view applyLayout. "view open." "Make sure outer nodes have the size we specified." self assert: (nodes at: 1) extent = (100 @ 100). self assert: (nodes at: 2) extent = (100 @ 100). self assert: (nodes at: 3) extent = (100 @ 100). self assert: (nodes at: 4) extent = (100 @ 100). "Make sure the standard layout - because we have none set for the outer nodes - positions them correctly." self assert: (nodes at: 1) bounds = ((5@5) corner: (105@105)). self assert: (nodes at: 2) bounds = ((115@5) corner: (215@105)). self assert: (nodes at: 3) bounds = ((225@5) corner: (325@105)). self assert: (nodes at: 4) bounds = ((335@5) corner: (435@105)). "Test first (inner) nodes..." self assert: ((nodes at: 1) elements at: 2) bounds = ((24@5) corner: (54@28)). self assert: ((nodes at: 1) elements at: 3) bounds = ((53@5) corner: (95@28)). self assert: ((nodes at: 1) elements at: 5) bounds = ((5@56) corner: (43@95)). self assert: ((nodes at: 1) elements at: 7) bounds = ((42@57) corner: (95@95)). "Test third (inner) nodes..." self assert: ((nodes at: 3) elements at: 1) bounds = ((5@5) corner: (25@28)). self assert: ((nodes at: 3) elements at: 3) bounds = ((53@5) corner: (95@28)). self assert: ((nodes at: 3) elements at: 4) bounds = ((5@27) corner: (43@57)). self assert: ((nodes at: 3) elements at: 6) bounds = ((42@27) corner: (95@58)).! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 1/8/2013 09:59'! testSimpleEdgeDrivenLayouting | layout view nodes edges node1 node2 node3 mergedBounds | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. view shape width: 100; height: 100. view nodes: (1 to: 3). view edgesFromAssociations: (Array with: 1 -> 2 with: 1 -> 3). view layout: layout. nodes := view nodes. view applyLayout. node1 := (nodes at: 1). node2 := (nodes at: 2). node3 := (nodes at: 3). mergedBounds := node1 bounds merge: (node2 bounds merge: node3 bounds). "Make sure the whole 'canvas' is as specified" self assert: mergedBounds extent = (100@100). self assert: mergedBounds = ((5@5) corner: (105@105)). "Lets also make sure the nodes are correctly positioned" self assert: (node1 bounds = ((5@5) corner: (105@105))). self assert: (node2 bounds = ((5@5) corner: (95@41))). self assert: (node3 bounds = ((5@40) corner: (95@95))). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 8/13/2013 09:37'! testSimpleNestedDrivenLayouting | layout view nodes root mergedBounds node1 node2 node3 | view := ROMondrianViewBuilder new. view shape rectangle size: 100. view nodes: (OrderedCollection with: 1) forEach: [ :each | | innerNodes innerEdges | innerNodes := (view nodes: (2 to: 3)) reverse. view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ]. nodes := view nodes. view applyLayout. nodes := nodes reverse. node1 := (nodes at: 1). node2 := ((nodes at: 1) elements at: 1). node3 := ((nodes at: 1) elements at: 2). mergedBounds := node1 bounds merge: (node2 bounds merge: node3 bounds). "Make sure the whole 'canvas' is as specified" self assert: mergedBounds extent = (100@100). self assert: mergedBounds = ((5@5) corner: (105@105)). "Lets also make sure the nodes are correctly positioned" self assert: (node1 bounds = ((5@5) corner: (105@105))). self assert: (node2 bounds = ((5@5) corner: (95@41))). self assert: (node3 bounds = ((5@40) corner: (95@95))). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 9/4/2012 16:47'! testSingleNodeLayouting | layout view nodes edges root | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. view shape width: 100; height: 100. view nodes: (OrderedCollection with: 1). view layout: layout. nodes := view nodes. root := nodes first. "view open." view applyLayout. "Make sure the node has the dimension we specified." self assert: (nodes at: 1) extent = (100 @ 100). ! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 12/18/2012 15:51'! testThreeNodesLayouting | layout view nodes node1 node2 node3 mergedBounds | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. view shape width: 100; height: 100. view nodes: (1 to: 3). view layout: layout. nodes := view nodes. view applyLayout. node1 := (nodes at: 1). node2 := (nodes at: 2). node3 := (nodes at: 3). mergedBounds := node1 bounds merge: (node2 bounds merge: node3 bounds). "Make sure the whole 'canvas' is as specified" self assert: mergedBounds extent = (100@100). self assert: mergedBounds = ((5@5) corner: (105@105)). "Lets also make sure the nodes are correctly positioned" self assert: (node1 bounds = ((5@5) corner: (105@21))). self assert: (node2 bounds = ((5@20) corner: (45@105))). self assert: (node3 bounds = ((44@20) corner: (105@105))).! ! !ROTreeMapLayoutTest methodsFor: 'tests' stamp: 'DennisSchenk 12/18/2012 15:51'! testTwoNodeslayouting | layout view nodes node1 node2 mergedBounds | layout := (ROTreeMapLayout withWeightBlock: [ :e | e model ]). view := ROMondrianViewBuilder new. view shape width: 100; height: 100. view nodes: (1 to: 2). view layout: layout. nodes := view nodes. view applyLayout. node1 := (nodes at: 1). node2 := (nodes at: 2). mergedBounds := node1 bounds merge: node2 bounds. "Make sure the whole 'canvas' is as specified" self assert: mergedBounds extent = (100@100). self assert: mergedBounds = ((5@5) corner: (105@105)). "Make sure the nodes have the right dimensions based on their weight: node2 should be double the size as node1." "We have to substract the area that node2 has additionally because of the border overlapping. See the splitRectangle methods in ROTreeMapLayout" self assert: (node1 bounds area) * 2 = (node2 bounds area - (2 * node2 bounds width)). "Lets also make sure the nodes are correctly positioned" self assert: (node1 bounds = ((5@5) corner: (105@38))). self assert: (node2 bounds = ((5@37) corner: (105@105))). ! ! !Boolean methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! glamourValueWithArgs: anArray ^self! ! !Class methodsFor: '*roassal-core'! numberOfSubclasses ^ self allSubclasses size! ! !Class methodsFor: '*roassal-core'! numberOfVariables ^ self instVarNames size! ! !SequenceableCollection methodsFor: '*petitparser-core-converting' stamp: 'lr 2/7/2010 20:53'! asPetitStream ^ PPStream on: self! ! !SequenceableCollection methodsFor: '*roassalmorphic' stamp: 'AlexandreBergel 12/13/2012 12:18'! maxValue: aBlock ^ self inject: (aBlock value: self anyOne) into: [ :max :each | max max: (aBlock value: each) ]! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 2/25/2012 18:18'! pairsDistanceFrom: aSequenceableCollection self deprecated: 'Please use pairsSimilarityWith:'. ^ self pairsSimilarityWith: aSequenceableCollection! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TudorGirba 2/25/2012 18:18'! pairsSimilarityWith: aSequenceableCollection " Examples: '1234' pairsSimilarityWith: '2234' ==> (2/3) '1234' pairsSimilarityWith: '123' ==> (4/5) '1234' pairsSimilarityWith: '5678' ==> 0 " | set1 set2 | set1 := Set new. set2 := Set new. self overlappingPairsDo: [:a :b | set1 add: a -> b]. aSequenceableCollection overlappingPairsDo: [:a :b | set2 add: a -> b]. ^ 2 * (set1 intersection: set2) size / (set1 size + set2 size)! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'tg 4/26/2010 21:54'! piecesCutWhere: testBlock do: enumerationBlock "Evaluate testBlock for successive pairs of the receiver elements, breaking the receiver into pieces between elements where the block evaluated to true, and evaluate enumerationBlock with each of those pieces." "'A sentence. Another sentence... Yet another sentence.' piecesCutWhere: [:each :next | each = $. and: [next = Character space]] do: [:each | Transcript show: each printString; cr]" | start prevElem nextElem size | self isEmpty ifTrue: [^self]. prevElem := self at: (start := 1). 2 to: (size := self size) do: [:index| nextElem := self at: index. (testBlock value: prevElem value: nextElem) ifTrue: [enumerationBlock value: (self copyFrom: start to: index - 1). start := index]. prevElem := nextElem]. enumerationBlock value: (self copyFrom: start to: size)! ! !SequenceableCollection methodsFor: '*roassal-core' stamp: 'AlexandreBergel 8/6/2013 06:13'! reverseSortedAs: aSortBlockOrSymbol ^ (self sortedAs: aSortBlockOrSymbol) reverse! ! !SequenceableCollection methodsFor: '*roassal-core' stamp: 'AlexandreBergel 5/3/2012 19:16'! roSwapElement: u withElement: v | index1 index2 | index1 := self indexOf: u. index2 := self indexOf: v. self at: index2 put: u. self at: index1 put: v.! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:27'! runsFailing: aBlock "Evaluate testBlock with the receiver elements, selecting from the receiver runs, that is sequences of adjacent elements, for which the block returned false. Return an OrderedCollection of those runs." "'Hello to\all of the world,\isn''t Smalltalk cool?' runsFailing: [:each | each = $\] " ^self runsSatisfying: [:each | (aBlock value: each) not]! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:27'! runsSatisfying: testBlock "Evaluate testBlock with the receiver elements, selecting from the receiver runs, that is sequences of adjacent elements, for which the block returned true. Return an OrderedCollection of those subsequences." "'Hello to\all of the world,\isn''t Smalltalk cool?' runsSatisfying: [:each | each ~= $\] " | runs | runs := OrderedCollection new. self runsSatisfying: testBlock do: [:each | runs add: each]. ^runs! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:28'! runsSatisfying: testBlock do: enumerationBlock "Evaluate testBlock with the receiver elements, selecting from the receiver runs, that is sequences of adjacent elements, for which the block returned true, and evaluate enumerationBlock with each of those subsequences." "'Hello to\all of the world,\isn''t Smalltalk cool?' runsSatisfying: [:each | each ~= $\] do: [:each | Transcript show: each; cr]" | size start wasInside nowInside | start := 1. wasInside := false. 1 to: (size := self size) do: [:index| nowInside := testBlock value: (self at: index). nowInside ~~ wasInside ifTrue: [wasInside := nowInside. nowInside ifTrue: [start := index] ifFalse: [enumerationBlock value: (self copyFrom: start to: index - 1)]]]. wasInside ifTrue: [enumerationBlock value: (self copyFrom: start to: size)]! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:17'! sliceFrom: startIndex "Answers a copy of a subset of the receiver, starting from element at start index up to the end of the collection. Comfortable alternative to stupid copyFrom:to: method. See also comment on sliceFrom:to:" ^self sliceFrom: startIndex to: self size! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:16'! sliceFrom: startIndex to: endIndex "Answers a copy of a subset of the receiver, starting from element at start index until element at end index. Comfortable alternative to stupid copyFrom:to: method. If the start or end index is negative, the index will be counted from the end of the collection. Note: this method does NEVER throw a SubscriptOutOfBoundsError. If the indexes are too large or start is greater than end, then an empty collection will be returned." | start end | start := 1 max: (startIndex positive ifTrue: [startIndex] ifFalse: [self size + startIndex +1]). end := self size min: (endIndex positive ifTrue: [endIndex] ifFalse: [self size + endIndex]). ((start > end) or: [end <= 0]) ifTrue: [^self copyEmpty: 0]. ^self copyFrom: start to: end! ! !SequenceableCollection methodsFor: '*CollectionExtensions' stamp: 'TestRunner 10/25/2009 01:17'! sliceTo: endIndex "Answer a copy of a subset of the receiver, starting from first element up to element at endIndex." ^self sliceFrom: 1 to: endIndex! ! !SequenceableCollection methodsFor: '*roassal-core' stamp: 'AlexandreBergel 5/27/2013 14:36'! sortedAs: aSortBlockOrSymbol "Answer a SortedCollection whose elements are the elements of the receiver. The sort order is defined by the argument, aSortBlock." "Return a new collection. This method does not do a side effect" | aSortedCollection aSortBlock | aSortedCollection := SortedCollection new: self size. aSortBlock := aSortBlockOrSymbol isSymbol ifTrue: [ [:a :b | |t1 t2| t1 := (a perform: aSortBlockOrSymbol). t2 := (b perform: aSortBlockOrSymbol). ((t1 isKindOf: Boolean) and: [t2 isKindOf: Boolean]) ifTrue: [ t1 ] ifFalse: [ t1 < t2 ] ] ] ifFalse: [ (aSortBlockOrSymbol numArgs = 1) ifTrue: [ [ :v1 :v2 | (aSortBlockOrSymbol value: v1) < (aSortBlockOrSymbol value: v2) ] ] ifFalse: [ aSortBlockOrSymbol ] ]. aSortedCollection sortBlock: aSortBlock. aSortedCollection addAll: self. ^ aSortedCollection! ! !GLMWatcherWindow commentStamp: '' prior: 34279604! This morph is used as support for the watcher (quick preview) behavior. GLMWatcherWindow uniqueInstance openInWorld. GLMWatcherWindow reset.! !GLMWatcherWindow class methodsFor: 'instance creation' stamp: 'TudorGirba 5/25/2012 17:22'! buildKeymapsOn: aBuilder (aBuilder shortcut: #openGlamourWatcher) category: #Glamour default: Character space command shift do: [ :morph | self uniqueInstance toggleOpen ]. aBuilder attachShortcutCategory: #Glamour to: Morph.! ! !GLMWatcherWindow class methodsFor: 'instance creation' stamp: 'TudorGirba 5/12/2012 22:50'! reset "self reset" uniqueInstance := nil! ! !GLMWatcherWindow class methodsFor: 'instance creation' stamp: 'TudorGirba 5/12/2012 22:52'! uniqueInstance ^ uniqueInstance ifNil: [uniqueInstance := self new]! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/23/2012 13:28'! activeFillStyle "Return the active fillStyle for the receiver." ^self theme watcherWindowActiveFillStyleFor: self! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/20/2012 22:51'! activeTitleFillStyle "Return the active title fillStyle for the receiver." ^ SolidFillStyle color: Color transparent! ! !GLMWatcherWindow methodsFor: 'accessing' stamp: 'TudorGirba 5/27/2012 23:20'! addContent: aBlockWhoseValueReturnsAMorph | newMorph | "if we are still rendering some contents for another watcher, we stop and replace with the current request" process ifNotNil: [ process terminate ]. process := nil. process := [ newMorph := aBlockWhoseValueReturnsAMorph value. WorldState addDeferredUIMessage: [ self contentsMorph removeAllMorphs; addMorph: newMorph fullFrame: (LayoutFrame fractions: (0@0 corner: 1@1)) ] ] newProcess. process priority: Processor userBackgroundPriority. process resume! ! !GLMWatcherWindow methodsFor: 'initialize' stamp: 'TudorGirba 5/20/2012 16:40'! addContentsMorph self contentsMorph: GLMMorphic emptyMorph. self contentsMorph layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1) offsets: (10@10 corner: -10@(-10))); hResizing: #spaceFill; vResizing: #spaceFill. self addMorphBack: self contentsMorph! ! !GLMWatcherWindow methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2012 01:32'! contentsMorph ^ contentsMorph! ! !GLMWatcherWindow methodsFor: 'accessing' stamp: 'TudorGirba 5/20/2012 01:32'! contentsMorph: anObject contentsMorph := anObject! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/31/2012 23:24'! defaultBorderStyle ^ FillStyleBorder color: (Color white darker alpha: 0.5) width: 10! ! !GLMWatcherWindow methodsFor: 'initialize' stamp: 'TudorGirba 5/20/2012 10:48'! defaultFillStyle ^ SolidFillStyle color: Color transparent! ! !GLMWatcherWindow methodsFor: 'open/close' stamp: 'TudorGirba 5/12/2012 23:11'! delete super delete. isOpen := false! ! !GLMWatcherWindow methodsFor: 'initialize' stamp: 'TudorGirba 5/20/2012 11:00'! fastFramingOn ^self theme settings fastDragging and: [self isFlexed not]! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/23/2012 14:11'! inactiveFillStyle "Return the active title fillStyle for the receiver." ^ self theme watcherWindowInactiveFillStyleFor: self! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/20/2012 23:29'! inactiveTitleFillStyle "Return the active title fillStyle for the receiver." ^ SolidFillStyle color: Color transparent! ! !GLMWatcherWindow methodsFor: 'initialize' stamp: 'TudorGirba 5/27/2012 01:41'! initialize super initialize. self fillStyle: self defaultFillStyle. " self borderStyle: self defaultBorderStyle." isOpen := false. self setLabel: 'Glamorous Watcher'. self addCornerGrips. self addEdgeGrips. self addContentsMorph. process := nil. self on: Character escape do: [ self hide ]! ! !GLMWatcherWindow methodsFor: 'accessing' stamp: 'TudorGirba 5/19/2012 18:05'! morphicLayerNumber "We want this preview to be always on top" ^ 10! ! !GLMWatcherWindow methodsFor: 'open/close' stamp: 'TudorGirba 5/19/2012 18:01'! openInWorld super openInWorld. isOpen := true. ! ! !GLMWatcherWindow methodsFor: 'initialize' stamp: 'TudorGirba 5/23/2012 13:59'! replaceBoxes "Rebuild the various boxes." labelArea removeAllMorphs. self setLabelWidgetAllowance. self theme configureWatcherWindowLabelAreaFor: self. self setFramesForLabelArea. self isActive ifFalse: [labelArea passivate]! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/23/2012 13:48'! taskbarTask "Answer a new taskbar task for the receiver. Answer nil if not required." ^nil! ! !GLMWatcherWindow methodsFor: 'open/close' stamp: 'TudorGirba 5/14/2013 08:51'! toggleOpen isOpen ifFalse: [ ^ self openInWorld ]. self visible ifTrue: [self hide] ifFalse: [self show]! ! !GLMWatcherWindow methodsFor: 'settings' stamp: 'TudorGirba 5/23/2012 13:13'! wantsExpandBox "Answer whether I'd like an expand box" ^ false! ! !ConfigurationOfGlamour commentStamp: 'TudorGirba 1/3/2012 13:23' prior: 34279823! ConfigurationOfGlamour loadDevelopment! !ConfigurationOfGlamour class methodsFor: 'private' stamp: 'TudorGirba 4/27/2011 13:38'! ensureMetacello "Bootstrap Gofer (if necessary), load latest mcz file for ConfigurationOfMetacello (using old Gofer API), then load the latest version of Metacello itself." Smalltalk at: #MetacelloProject ifAbsent: [ | error | "list of repositories to try, in case primary repository is not accessible" (Array with: 'http://www.squeaksource.com/MetacelloRepository' with: 'http://seaside.gemstone.com/ss/metacello') do: [:repositoryUrl | ([ Smalltalk at: #Gofer ifAbsent: [ "Current version of Gofer from which to bootstrap - as of 1.0-beta.21" self bootstrapPackage: 'Gofer-Core-lr.115' from: repositoryUrl ]. Smalltalk at: #Gofer ifPresent: [:goferClass | | gofer | gofer := goferClass new url: repositoryUrl; yourself. [ gofer addPackage: 'ConfigurationOfMetacello' ] on: Warning do: [:ex | ex resume ]. gofer load ]] on: Error do: [ :ex | error := ex. Transcript cr; show: 'failed ensureMetacello: '; show: ex description printString; show: '...retrying'. "try again" ex return: nil ]) ~~ nil ifTrue: [ "load 'default' group of Metacello" (Smalltalk at: #ConfigurationOfMetacello) perform: #load. ^self ]]. "shouldn't get here unless the load failed ... throw an error" self error: 'retry with alternate repository failed: ', error description printString ]! ! !ConfigurationOfGlamour class methodsFor: 'metacello tool support' stamp: 'tg 10/18/2009 12:48'! isMetacelloConfig "Answer true and the Metacello tools will operate on you" ^true! ! !ConfigurationOfGlamour class methodsFor: 'loading' stamp: 'TudorGirba 1/3/2012 12:52'! loadDefault "this will be deprecated soon" self loadDevelopment! ! !ConfigurationOfGlamour class methodsFor: 'loading' stamp: 'TudorGirba 12/23/2011 08:58'! loadDevelopment (self project version: #development) load! ! !ConfigurationOfGlamour class methodsFor: 'accessing' stamp: 'tg 10/20/2009 23:22'! project ^self new project! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'tg 11/21/2009 23:05'! baseline20beta1: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Morphic-MorphTreeWidget' with: [ spec file: 'Morphic-MorphTreeWidget-AlainPlantec.17'. spec repository: 'http://www.squeaksource.com/Momo' ]; package: 'Glamour-Helpers' ; package: 'Glamour-Squeak' ; package: 'Glamour-Core' ; package: 'Glamour-Presentations' ; package: 'Glamour-Browsers' ; package: 'Glamour-Scripting' ; package: 'Glamour-Tests' ; package: 'Glamour-Morphic' with: [spec requires: #('Morphic-MorphTreeWidget')]; package: 'Glamour-Test-Morphic' ; package: 'Glamour-Examples'. spec group: 'Tests' with: #( 'Glamour-Tests' 'Glamour-Examples' 'Glamour-Test-Morphic'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'tg 12/18/2009 19:13'! baseline20beta2: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Morphic-MorphTreeWidget' with: [ spec repository: 'http://www.squeaksource.com/Momo' ]; package: 'Glamour-Helpers' ; package: 'Glamour-Squeak' ; package: 'Glamour-Core' ; package: 'Glamour-Presentations' ; package: 'Glamour-Browsers' ; package: 'Glamour-Scripting' ; package: 'Glamour-Tests' ; package: 'Glamour-Morphic' with: [spec requires: #('Morphic-MorphTreeWidget')]; package: 'Glamour-Test-Morphic' with: [spec requires: #('Glamour-Morphic')]; package: 'Glamour-Examples'. spec group: 'Tests' with: #( 'Glamour-Tests' 'Glamour-Examples' 'Glamour-Test-Morphic'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'tg 12/28/2009 21:28'! baseline20beta3: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Morphic-MorphTreeWidget' with: [ spec repository: 'http://www.squeaksource.com/Momo10' ]; package: 'Glamour-Helpers' ; package: 'Glamour-Squeak' ; package: 'Glamour-Core' ; package: 'Glamour-Presentations' ; package: 'Glamour-Browsers' ; package: 'Glamour-Scripting' ; package: 'Glamour-Tests' ; package: 'Glamour-Morphic' with: [spec requires: #('Morphic-MorphTreeWidget')]; package: 'Glamour-Test-Morphic' with: [spec requires: #('Glamour-Morphic')]; package: 'Glamour-Examples'. spec group: 'Tests' with: #( 'Glamour-Tests' 'Glamour-Examples' 'Glamour-Test-Morphic'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'tg 2/16/2010 13:17'! baseline20beta4: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Morphic-MorphTreeWidget' with: [ spec repository: 'http://www.squeaksource.com/Momo10' ]; package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' ; package: 'Glamour-Presentations' ; package: 'Glamour-Browsers' ; package: 'Glamour-Scripting' ; package: 'Glamour-Tests' ; package: 'Glamour-Morphic' with: [spec requires: #('Morphic-MorphTreeWidget')]; package: 'Glamour-Test-Morphic' with: [spec requires: #('Glamour-Morphic')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools' . spec group: 'Tests' with: #( 'Glamour-Tests' 'Glamour-Examples' 'Glamour-Test-Morphic'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'jannik.laval 9/13/2010 22:49'! baseline20beta5: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Scripting' with: [spec requires: #('Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Magritte-Morph' 'Mondrian for Glamour')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools'; package: 'Magritte-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Grease']; package: 'Magritte-Tests-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model']; package: 'Magritte-Morph' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: #('Magritte-Model')]; package: 'Magritte-Pharo-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model' ]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Scripting' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Extras' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme' 'Mondrian for Glamour'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. spec project: 'Grease' with: [ spec className: 'ConfigurationOfGrease'; file: 'ConfigurationOfGrease'; version: '1.0-alpha9.1'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'TudorGirba 12/4/2010 20:09'! baseline20beta6: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Work on Pharo 1.1.1'. spec author: 'Alexandre Bergel'. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Scripting' with: [spec requires: #('Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Core' 'Mondrian for Glamour')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Shout')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools'; package: 'Magritte-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Grease']; package: 'Magritte-Tests-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model']; package: 'Magritte-Morph' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: #('Magritte-Model')]; package: 'Magritte-Pharo-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model' ]; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte-Morph' 'Magritte-Pharo-Model')]; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Scripting' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian'). spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; file: 'ConfigurationOfShout'; version: '1.1'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: '2.1.2'; repository: 'http://www.squeaksource.com/Mondrian' ]. spec project: 'Grease' with: [ spec className: 'ConfigurationOfGrease'; file: 'ConfigurationOfGrease'; version: '1.0-alpha9.1'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'DamienCassou 7/9/2011 15:59'! baseline21: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Shout')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools'; package: 'Magritte-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Grease']; package: 'Magritte-Tests-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model']; package: 'Magritte-Morph' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: #('Magritte-Model')]; package: 'Magritte-Pharo-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model' ]; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte-Morph' 'Magritte-Pharo-Model')]; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic'). spec group: 'ExtrasTests' with: #( 'Glamour-Tests-Mondrian'). spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; file: 'ConfigurationOfShout'; version: '1.2.2'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. spec project: 'Grease' with: [ spec className: 'ConfigurationOfGrease'; file: 'ConfigurationOfGrease'; version: '1.0.3'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'GuillermoPolito 9/28/2011 17:30'! baseline22: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'CollectionExtensions' with: [spec repository: 'http://www.squeaksource.com/CollectionExtensions']; package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Widgets' with: [spec requires: #('Shout')]; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools' with: [spec requires: 'CollectionExtensions']; package: 'Magritte-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Grease']; package: 'Magritte-Tests-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model']; package: 'Magritte-Morph' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: #('Magritte-Model')]; package: 'Magritte-Pharo-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model' ]; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte-Morph' 'Magritte-Pharo-Model')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian' 'Glamour-Tests-EyeSee'). spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; file: 'ConfigurationOfShout'; version: '1.3'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. spec project: 'EyeSee for Glamour' with: [ spec className: 'ConfigurationOfEyeSee'; file: 'ConfigurationOfEyeSee'; version: 'default'; repository: 'http://www.squeaksource.com/EyeSee' ]. spec project: 'Grease' with: [ spec className: 'ConfigurationOfGrease'; file: 'ConfigurationOfGrease'; version: #stable; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'EstebanLorenzano 6/3/2012 13:40'! baseline23: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'CollectionExtensions' with: [spec repository: 'http://www.squeaksource.com/CollectionExtensions']; package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Widgets'; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools' with: [spec requires: 'CollectionExtensions']; package: 'Magritte-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Grease']; package: 'Magritte-Tests-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model']; package: 'Magritte-Morph' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: #('Magritte-Model')]; package: 'Magritte-Pharo-Model' with: [ spec repository: 'http://source.lukas-renggli.ch/magritte2'. spec requires: 'Magritte-Model' ]; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte-Morph' 'Magritte-Pharo-Model')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian' 'Glamour-Tests-EyeSee'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://www.squeaksource.com/Mondrian' ]. spec project: 'EyeSee for Glamour' with: [ spec className: 'ConfigurationOfEyeSee'; file: 'ConfigurationOfEyeSee'; version: 'default'; repository: 'http://www.squeaksource.com/EyeSee' ]. spec project: 'Grease' with: [ spec className: 'ConfigurationOfGrease'; file: 'ConfigurationOfGrease'; version: #stable; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'DiegoLont 9/20/2013 16:05'! baseline24: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Loading moose packages from SmalltalkHub for Pharo1.4'. spec repository: 'http://smalltalkhub.com/mc/Moose/Glamour/main'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Widgets' with: [spec requires: #('Shout' 'NEC')]; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer' 'BDDExtensions')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools'; package: 'Glamour-Roassal-Presentations' with: [spec requires: 'Roassal for Glamour']; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte3')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]; package: 'Glamour-Tests-Roassal' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Roassal-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]; package: 'Glamour-Tests-Resources'. spec for: #squeakCommon do: [ spec package: 'CollectionExtensions' with: [ spec repository: 'http://smalltalkhub.com/mc/Moose/CollectionExtensions/main']. spec package: 'Glamour-Tools' with: [spec requires: 'CollectionExtensions']. ]. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations' 'Glamour-Roassal-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Resources' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian' 'Glamour-Tests-EyeSee' 'Glamour-Tests-Roassal' 'Glamour-Tests-Resources'). spec project: 'Shout' with: [ spec className: 'ConfigurationOfShout'; file: 'ConfigurationOfShout'; version: '1.3'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. spec project: 'NEC' with: [ spec className: 'ConfigurationOfNewECompletion'; file: 'ConfigurationOfNewECompletion'; version: #stable; repository: 'http://ss3.gemstone.com/ss/NEC' ]. spec project: 'BDDExtensions' with: [ spec className: 'ConfigurationOfBDDExtensions'; file: 'ConfigurationOfBDDExtensions'; version: '1.0-baseline'; repository: 'http://www.squeaksource.com/BDDExtensions' ]. spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: 'default'; repository: 'http://smalltalkhub.com/mc/Moose/Mondrian/main' ]. spec project: 'Roassal for Glamour' with: [ spec className: 'ConfigurationOfRoassal'; file: 'ConfigurationOfRoassal'; version: #development; repository: 'http://www.squeaksource.com/Roassal' ]. spec project: 'EyeSee for Glamour' with: [ spec className: 'ConfigurationOfEyeSee'; file: 'ConfigurationOfEyeSee'; version: 'default'; repository: 'http://smalltalkhub.com/mc/Moose/EyeSee/main' ]. spec project: 'Magritte3' with: [ spec className: 'ConfigurationOfMagritte3'; file: 'ConfigurationOfMagritte3'; version: #stable; repository: 'http://source.lukas-renggli.ch/magritte3'; loads: #('Magritte-Model' 'Magritte-Tests-Model' 'Magritte-Morph' 'Magritte-Pharo-Model') ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'DiegoLont 9/20/2013 16:00'! baseline25: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Loading moose packages from SmalltalkHub for Pharo2.0'. spec repository: 'http://www.smalltalkhub.com/mc/Moose/Glamour/main'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Widgets'; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' with: [spec requires: #('Glamour-Tools')]; package: 'Glamour-Tools' with: [spec requires: #('Glamour-Core')]; package: 'Rubric' with: [spec repository: 'http://www.smalltalkhub.com/mc/AlainPlantec/Rubric/main']; package: 'Glamour-Rubric-Presentations' with: [spec requires: 'Rubric']; package: 'Glamour-Roassal-Presentations' with: [spec requires: 'Roassal for Glamour']; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte3')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-GraphET-Presentations' with: [spec requires: 'Graph-ET']; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]; package: 'Glamour-Tests-Rubric' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Rubric-Presentations')]; package: 'Glamour-Tests-Roassal' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Roassal-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]; package: 'Glamour-Tests-Resources']. spec for: #squeakCommon do: [ spec package: 'CollectionExtensions' with: [spec repository: 'http://www.smalltalkhub.com/mc/Moose/CollectionExtensions/main']. spec package: 'Glamour-Tools' with: [spec requires: #('Glamour-Core' 'CollectionExtensions')]. ]. spec for: #common do: [ spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Roassal' with: #( 'Glamour-Roassal-Presentations'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations' 'Glamour-Roassal-Presentations' 'Glamour-Rubric-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Resources' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian' 'Glamour-Tests-EyeSee' 'Glamour-Tests-Roassal' 'Glamour-Tests-Rubric' 'Glamour-Tests-Resources'). spec project: 'Mondrian for Glamour' with: [ spec className: 'ConfigurationOfMondrian'; file: 'ConfigurationOfMondrian'; version: #development; repository: 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main' ]. spec project: 'Roassal for Glamour' with: [ spec className: 'ConfigurationOfRoassal'; file: 'ConfigurationOfRoassal'; version: #development; repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main' ]. spec project: 'EyeSee for Glamour' with: [ spec className: 'ConfigurationOfEyeSee'; file: 'ConfigurationOfEyeSee'; version: #development; repository: 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main' ]. spec project: 'Graph-ET' with: [ spec className: 'ConfigurationOfGraphET'; file: 'ConfigurationOfGraphET'; version: #development; repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/GraphET/main' ]. spec project: 'Magritte3' with: [ spec className: 'ConfigurationOfMagritte3'; file: 'ConfigurationOfMagritte3'; version: #development; repository: 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main'; loads: #('Magritte-Model' 'Magritte-Tests-Model' 'Magritte-Morph' 'Magritte-Pharo-Model') ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'TudorGirba 10/4/2013 23:09'! baseline26: spec spec for: #common do: [ spec blessing: #baseline. spec description: 'Removed Mondrian'. spec repository: 'http://www.smalltalkhub.com/mc/Moose/Glamour/main'. spec package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' ; package: 'Glamour-Morphic-Widgets'; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer')]; package: 'Glamour-Examples' with: [spec requires: #('Glamour-Tools')]; package: 'Glamour-Tools' with: [spec requires: #('Glamour-Core')]; package: 'Rubric' with: [spec repository: 'http://www.smalltalkhub.com/mc/AlainPlantec/Rubric/main']; package: 'Glamour-Rubric-Presentations' with: [spec requires: 'Rubric']; package: 'Glamour-Roassal-Presentations' with: [spec requires: 'Roassal for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte3')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-GraphET-Presentations' with: [spec requires: 'Graph-ET']; package: 'Glamour-Tests-Rubric' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Rubric-Presentations')]; package: 'Glamour-Tests-Roassal' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Roassal-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]; package: 'Glamour-Tests-Resources']. spec for: #squeakCommon do: [ spec package: 'CollectionExtensions' with: [spec repository: 'http://www.smalltalkhub.com/mc/Moose/CollectionExtensions/main']. spec package: 'Glamour-Tools' with: [spec requires: #('Glamour-Core' 'CollectionExtensions')]. ]. spec for: #common do: [ spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Examples' 'Glamour-Tools'). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Roassal' with: #( 'Glamour-Roassal-Presentations'). spec group: 'Extras' with: #( 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations' 'Glamour-Roassal-Presentations' 'Glamour-Rubric-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Resources' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Core' 'Glamour-Examples' 'Glamour-Tests-Morphic' 'Glamour-Tests-EyeSee' 'Glamour-Tests-Roassal' 'Glamour-Tests-Rubric' 'Glamour-Tests-Resources'). spec project: 'Roassal for Glamour' with: [ spec className: 'ConfigurationOfRoassal'; file: 'ConfigurationOfRoassal'; version: #development; repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main' ]. spec project: 'EyeSee for Glamour' with: [ spec className: 'ConfigurationOfEyeSee'; file: 'ConfigurationOfEyeSee'; version: #development; repository: 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main' ]. spec project: 'Graph-ET' with: [ spec className: 'ConfigurationOfGraphET'; file: 'ConfigurationOfGraphET'; version: #development; repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/GraphET/main' ]. spec project: 'Magritte3' with: [ spec className: 'ConfigurationOfMagritte3'; file: 'ConfigurationOfMagritte3'; version: #development; repository: 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main'; loads: #('Magritte-Model' 'Magritte-Tests-Model' 'Magritte-Morph' 'Magritte-Pharo-Model') ]. ]! ! !ConfigurationOfGlamour methodsFor: 'baselines' stamp: 'usmanbhatti 2/22/2013 13:42'! default: spec self baseline25: spec.! ! !ConfigurationOfGlamour methodsFor: 'symbolic versions' stamp: 'TudorGirba 10/4/2013 22:44'! development: spec spec for: #'common' version: '2.6-baseline'. spec for: #'pharo2.x' version: '2.6-baseline'.! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'AndreiChis 12/4/2012 13:03'! minimum: spec spec for: #common do: [ spec blessing: #baseline. spec repository: 'http://www.squeaksource.com/Glamour'. spec package: 'CollectionExtensions' with: [spec repository: 'http://www.squeaksource.com/CollectionExtensions']; package: 'Glamour-Announcements' ; package: 'Glamour-Helpers' ; package: 'Glamour-Core' with: [spec requires: #('Glamour-Helpers' 'Glamour-Announcements')]; package: 'Glamour-Presentations' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Browsers' with: [spec requires: #('Glamour-Core')]; package: 'Glamour-Tests-Core' with: [spec requires: #('Glamour-Tests-Resources') ] ; package: 'Glamour-Morphic-Widgets'; package: 'Glamour-Morphic-Renderer' with: [spec requires: #('Glamour-Morphic-Widgets' 'Glamour-Core')]; package: 'Glamour-Morphic-Theme'; package: 'Glamour-Tests-Morphic' with: [spec requires: #('Glamour-Morphic-Renderer' 'Glamour-Tests-Resources')]; package: 'Glamour-Examples' ; package: 'Glamour-Tools' with: [spec requires: 'CollectionExtensions']; package: 'Glamour-Roassal-Presentations' with: [spec requires: 'Roassal for Glamour']; package: 'Glamour-Mondrian-Presentations' with: [spec requires: 'Mondrian for Glamour']; package: 'Glamour-Magritte-Presentations' with: [spec requires: #('Magritte3')]; package: 'Glamour-EyeSee-Presentations' with: [spec requires: 'EyeSee for Glamour']; package: 'Glamour-Tests-Mondrian' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Mondrian-Presentations')]; package: 'Glamour-Tests-Roassal' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-Roassal-Presentations')]; package: 'Glamour-Tests-EyeSee' with: [spec requires: #('Glamour-Tests-Morphic' 'Glamour-EyeSee-Presentations')]; package: 'Glamour-Tests-Resources'. spec group: 'Core' with: #( 'Glamour-Announcements' 'Glamour-Helpers' 'Glamour-Core' 'Glamour-Presentations' 'Glamour-Browsers' 'Glamour-Tools'). spec group: 'Examples' with: #( 'Glamour-Examples' ). spec group: 'Morphic' with: #( 'Glamour-Morphic-Renderer' 'Glamour-Morphic-Theme'). spec group: 'Extras' with: #( 'Glamour-Mondrian-Presentations' 'Glamour-Magritte-Presentations' 'Glamour-EyeSee-Presentations' 'Glamour-Roassal-Presentations'). spec group: 'Core Tests' with: #( 'Glamour-Tests-Resources' 'Glamour-Tests-Core' 'Glamour-Tests-Morphic'). spec group: 'Tests' with: #( 'Glamour-Tests-Resources' 'Glamour-Tests-Core' 'Glamour-Tests-Morphic' 'Glamour-Tests-Mondrian' 'Glamour-Tests-EyeSee' 'Glamour-Tests-Roassal'). ]! ! !ConfigurationOfGlamour methodsFor: 'snapshots' stamp: 'TudorGirba 9/10/2013 08:46'! populateSpec: aSpec with: list "generated by Snapshotcello creates a spec object for the package and the version stored in the list" list do: [:each | aSpec package: each third with: [ aSpec file: (each first copyUpToLast: $. ). aSpec repository: each second ] ]! ! !ConfigurationOfGlamour methodsFor: 'accessing' stamp: 'tg 10/18/2009 12:48'! project ^ project ifNil: [ | constructor | "Bootstrap Metacello if it is not already loaded" self class ensureMetacello. "Construct Metacello project" constructor := (Smalltalk at: #MetacelloVersionConstructor) on: self. project := constructor project. project]! ! !ConfigurationOfGlamour methodsFor: 'snapshots' stamp: 'DiegoLont 9/11/2013 13:58'! snapshot1 "generated by Snapshotcello" ^ #( #('ConfigurationOfGraphET-AlexandreBergel.6.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/GraphET/main/' 'ConfigurationOfGraphET' ) #('ConfigurationOfEyeSee-TudorGirba.29.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'ConfigurationOfEyeSee' ) #('ConfigurationOfMondrian-StephaneDucasse.375.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'ConfigurationOfMondrian' ) #('ConfigurationOfMagritte3-TudorGirba.47.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'ConfigurationOfMagritte3' ) #('ConfigurationOfRoassal-TudorGirba.1186.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'ConfigurationOfRoassal' ) #('Glamour-Announcements-TudorGirba.7.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Announcements' ) #('Glamour-Helpers-TudorGirba.32.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Helpers' ) #('Glamour-Core-AndreiChis.256.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Core' ) #('Glamour-Presentations-AndreiChis.121.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Presentations' ) #('Glamour-Browsers-AndreiChis.101.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Browsers' ) #('Glamour-Tests-Core-AndreiChis.90.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Core' ) #('Glamour-Morphic-Widgets-TudorGirba.68.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Widgets' ) #('Glamour-Morphic-Renderer-AndreiChis.208.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Renderer' ) #('Glamour-Morphic-Theme-TudorGirba.78.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Morphic-Theme' ) #('Glamour-Tests-Morphic-TudorGirba.108.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Morphic' ) #('Glamour-Tools-TudorGirba.66.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tools' ) #('Glamour-Examples-TudorGirba.262.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Examples' ) #('Rubric-AlainPlantec.82.mcz' 'http://www.smalltalkhub.com/mc/AlainPlantec/Rubric/main/' 'Rubric' ) #('Glamour-Rubric-Presentations-StephanEggermont.7.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Rubric-Presentations' ) #('Glamour-Tests-Rubric-TudorGirba.8.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Rubric' ) #('Glamour-Tests-Resources-AndreiChis.3.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Resources' ) #('ConfigurationOfProfStef-ChristopheDemarey.48.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/ProfStef/main/' 'ConfigurationOfProfStef' ) #('ConfigurationOfHealthReportProducer-TudorGirba.23.mcz' 'http://www.smalltalkhub.com/mc/Moose/HealthReportProducer/main/' 'ConfigurationOfHealthReportProducer' ) #('ConfigurationOfShapeST80-TudorGirba.8.mcz' 'http://www.smalltalkhub.com/mc/Moose/ShapeST80/main/' 'ConfigurationOfShapeST80' ) #('ShapeST80-TudorGirba.2.mcz' 'http://www.smalltalkhub.com/mc/Moose/ShapeST80/main/' 'ShapeST80' ) #('ProfStef-Core-EstebanLorenzano.30.mcz' 'http://smalltalkhub.com/mc/PharoExtras/ProfStef/main/' 'ProfStef-Core' ) #('ProfStef-Tests-LaurentLaffont.16.mcz' 'http://smalltalkhub.com/mc/PharoExtras/ProfStef/main/' 'ProfStef-Tests' ) #('ProfStef-Help-AlainPantec.7.mcz' 'http://smalltalkhub.com/mc/PharoExtras/ProfStef/main/' 'ProfStef-Help' ) #('ConfigurationOfXMLParser-DamienCassou.14.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/XMLParser/main/' 'ConfigurationOfXMLParser' ) #('ConfigurationOfOrderPreservingDictionary-StephaneDucasse.3.mcz' 'http://smalltalkhub.com/mc/PharoExtras/OrderPreservingDictionary/main/' 'ConfigurationOfOrderPreservingDictionary' ) #('ConfigurationOfBitmapCharacterSet-StephaneDucasse.2.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/BitmapCharacterSet/main/' 'ConfigurationOfBitmapCharacterSet' ) #('ConfigurationOfXMLWriter-StephaneDucasse.39.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/XMLWriter/main/' 'ConfigurationOfXMLWriter' ) #('Collections-OrderPreservingDictionary-JAA.7.mcz' 'http://smalltalkhub.com/mc/PharoExtras/OrderPreservingDictionary/main/' 'Collections-OrderPreservingDictionary' ) #('XML-Writer-Core-CamilloBruni.2.mcz' 'http://smalltalkhub.com/mc/Pharo/XMLWriter/main/' 'XML-Writer-Core' ) #('Collections-BitmapCharacterSet-JAA.5.mcz' 'http://smalltalkhub.com/mc/PharoExtras/BitmapCharacterSet/main/' 'Collections-BitmapCharacterSet' ) #('XML-Parser-DamienCassou.143.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/XMLParser/main/' 'XML-Parser' ) #('XML-Tests-Parser-StephaneDucasse.15.mcz' 'http://www.smalltalkhub.com/mc/PharoExtras/XMLParser/main/' 'XML-Tests-Parser' ) #('HealthReportProducer-Ivan_Rojas.16.mcz' 'http://www.squeaksource.com/HealthReportProducer/' 'HealthReportProducer' ) #('Nile-Base-DamienCassou.81.mcz' 'http://www.squeaksource.com/Nile/' 'Nile-Base' ) #('Mondrian-Core-TudorGirba.86.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Core' ) #('Mondrian-Layouts-AnneEtien.27.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Layouts' ) #('Mondrian-Help-TudorGirba.15.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Help' ) #('Mondrian-Tests-AndreHora.113.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Tests' ) #('Mondrian-Pharo-Tests-AndreHora.14.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Pharo-Tests' ) #('Mondrian-Shapes-AlexandreBergel.39.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Shapes' ) #('Mondrian-ComplexShape-AlexandreBergel.33.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-ComplexShape' ) #('Mondrian-Events-TudorGirba.25.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Events' ) #('Mondrian-Util-AndreHora.12.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Util' ) #('Mondrian-Normalizers-TudorGirba.5.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Normalizers' ) #('Mondrian-Example-JurajKubelka.48.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Example' ) #('Mondrian-ShapeVisitor-TudorGirba.6.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-ShapeVisitor' ) #('Mondrian-Pharo-Morphic-JurajKubelka.41.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Pharo-Morphic' ) #('Mondrian-Visitor-AndreHora.33.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-Visitor' ) #('Mondrian-FADELayout-AndreHora.5.mcz' 'http://www.smalltalkhub.com/mc/Moose/Mondrian/main/' 'Mondrian-FADELayout' ) #('Glamour-Mondrian-Presentations-TudorGirba.4.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Mondrian-Presentations' ) #('Glamour-Tests-Mondrian-AndreHora.7.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Mondrian' ) #('Roassal-AlexandreBergel.668.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'Roassal' ) #('RoassalMorphic-AlexandreBergel.146.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalMorphic' ) #('Glamour-Roassal-Presentations-TudorGirba.14.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Roassal-Presentations' ) #('Glamour-Tests-Roassal-AndreHora.5.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-Roassal' ) #('ConfigurationOfShapeST80-TudorGirba.8.mcz' 'http://www.smalltalkhub.com/mc/Moose/ShapeST80/main/' 'ConfigurationOfShapeST80' ) #('EyeSee-Events-TudorGirba.11.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'EyeSee-Events' ) #('EyeSee-Axis-AndreHora.16.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'EyeSee-Axis' ) #('EyeSee-Tests-Core-AndreHora.68.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'EyeSee-Tests-Core' ) #('EyeSee-Support-usmanbhatti.9.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'EyeSee-Support' ) #('ShapeST80-TudorGirba.2.mcz' 'http://www.smalltalkhub.com/mc/Moose/ShapeST80/main/' 'ShapeST80' ) #('EyeSee-Core-AnneEtien.106.mcz' 'http://www.smalltalkhub.com/mc/Moose/EyeSee/main/' 'EyeSee-Core' ) #('Glamour-EyeSee-Presentations-TudorGirba.4.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-EyeSee-Presentations' ) #('Glamour-Tests-EyeSee-TudorGirba.8.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Tests-EyeSee' ) #('ConfigurationOfRoassal-TudorGirba.1186.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'ConfigurationOfRoassal' ) #('Graph-ET-TudorGirba.76.mcz' 'http://smalltalkhub.com/mc/ObjectProfile/GraphET/main/' 'Graph-ET' ) #('Roassal-AlexandreBergel.668.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'Roassal' ) #('RoassalMorphic-AlexandreBergel.146.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalMorphic' ) #('Glamour-GraphET-Presentations-TudorGirba.3.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-GraphET-Presentations' ) #('ConfigurationOfGrease-MattSpr.207.mcz' 'http://smalltalkhub.com/mc/Seaside/MetacelloConfigurations/main/' 'ConfigurationOfGrease' ) #('Grease-Core-MattSpr.77.mcz' 'http://www.smalltalkhub.com/mc/Seaside/Seaside31/main/' 'Grease-Core' ) #('Grease-Pharo20-Core-pmm.10.mcz' 'http://www.smalltalkhub.com/mc/Seaside/Seaside31/main/' 'Grease-Pharo20-Core' ) #('Magritte-Model-SeanDeNigris.433.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'Magritte-Model' ) #('Magritte-Pharo-Model-DiegoLont.27.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'Magritte-Pharo-Model' ) #('Magritte-Tests-Model-DamienCassou.33.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'Magritte-Tests-Model' ) #('Magritte-Tests-Pharo-Model-lr.4.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'Magritte-Tests-Pharo-Model' ) #('Magritte-Morph-TudorGirba.70.mcz' 'http://www.smalltalkhub.com/mc/Magritte/Magritte3/main/' 'Magritte-Morph' ) #('Glamour-Magritte-Presentations-TudorGirba.4.mcz' 'http://www.smalltalkhub.com/mc/Moose/Glamour/main/' 'Glamour-Magritte-Presentations' ) )! ! !ConfigurationOfGlamour methodsFor: 'symbolic versions' stamp: 'TudorGirba 9/10/2013 08:46'! stable: spec spec for: #'common' version: '2.1'. spec for: #'pharo1.3.x' version: '2.2'. spec for: #'pharo1.4.x' version: '2.4'. spec for: #'pharo2.x' version: '2.5-snapshot'. ! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'simondenier 4/6/2010 20:16'! version206: spec spec for: #common do: [ spec author: 'simondenier'. spec timestamp: '4/6/2010 19:51'. spec blessing: #development. spec project: 'Mondrian for Glamour' with: '2.0.7'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.88'; package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.4'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.17'; package: 'Glamour-Core' with: 'Glamour-Core-tg.121'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.71'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.38'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.83'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.137'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-tg.271'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.65'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.137'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.22'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'tg 12/28/2009 21:28'! version20beta1: spec spec for: #common do: [ spec blessing: #stable. spec author: 'tg'. spec timestamp: '11/21/2009 23:06'. spec project: 'Mondrian for Glamour' with: '2.0-beta.1'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.17'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.11'; package: 'Glamour-Squeak' with: 'Glamour-Squeak-tg.7'; package: 'Glamour-Core' with: 'Glamour-Core-tg.51'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-VeronicaUquillas.51'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.14'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.44'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.53'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-VeronicaUquillas.194'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.11'; package: 'Glamour-Examples' with: 'Glamour-Examples-simondenier.89'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'tg 2/9/2010 18:11'! version20beta2: spec spec for: #common do: [ spec blessing: #stable. spec author: 'tg'. spec timestamp: '12/18/2009 19:13'. spec project: 'Mondrian for Glamour' with: '2.0-beta.1'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.39'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.11'; package: 'Glamour-Squeak' with: 'Glamour-Squeak-tg.7'; package: 'Glamour-Core' with: 'Glamour-Core-tg.55'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.52'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.15'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.46'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.59'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-tg.203'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.18'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.95'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'tg 12/28/2009 21:29'! version20beta3: spec spec for: #common do: [ spec blessing: #stable. spec author: 'tg'. spec timestamp: '12/28/2009 21:29'. spec project: 'Mondrian for Glamour' with: '2.0-beta.3'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.46'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.11'; package: 'Glamour-Squeak' with: 'Glamour-Squeak-tg.7'; package: 'Glamour-Core' with: 'Glamour-Core-tg.59'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.53'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.15'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.47'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.61'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-tg.204'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.18'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.97'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'tg 2/16/2010 13:54'! version20beta4: spec spec for: #common do: [ spec blessing: #beta. spec author: 'tg'. spec timestamp: '2/16/2010 12:58'. spec project: 'Mondrian for Glamour' with: '2.0-beta.5'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.88'; package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.3'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.15'; package: 'Glamour-Core' with: 'Glamour-Core-tg.113'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.63'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.37'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.74'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.124'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-tg.259'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.57'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.125'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.21'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'simon.denier 3/31/2010 16:13'! version20beta5: spec spec for: #common do: [ spec author: 'simon.denier'. spec timestamp: '3/31/2010 16:13'. spec blessing: #development. spec project: 'Mondrian for Glamour' with: '2.0-beta.6'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.88'; package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.3'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.15'; package: 'Glamour-Core' with: 'Glamour-Core-tg.113'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.63'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.37'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.74'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.124'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-tg.259'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.57'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.125'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.21'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'jannik.laval 6/1/2010 23:02'! version20beta6: spec spec for: #common do: [ spec author: 'jannik.laval'. spec timestamp: '6/1/2010 22:59'. spec blessing: #development. spec project: 'Mondrian for Glamour' with: '2.0-beta.7'. spec package: 'Morphic-MorphTreeWidget' with: 'Morphic-MorphTreeWidget-AlainPlantec.88'; package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.4'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-FabrizioPerin.19'; package: 'Glamour-Core' with: 'Glamour-Core-tg.131'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-VeronicaUquillas.79'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-Alexandre_Bergel.40'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-VeronicaUquillas.89'; package: 'Glamour-Tests' with: 'Glamour-Tests-tg.143'; package: 'Glamour-Morphic' with: 'Glamour-Morphic-VeronicaUquillas.282'; package: 'Glamour-Test-Morphic' with: 'Glamour-Test-Morphic-tg.72'; package: 'Glamour-Examples' with: 'Glamour-Examples-VeronicaUquillas.142'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.22'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'jannik.laval 9/14/2010 11:51'! version20beta7: spec spec for: #common do: [ spec author: 'jl'. spec timestamp: '09/13/2010 22:00'. spec blessing: #development. spec project: 'Mondrian for Glamour' with: '2.0-beta.8'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.5'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.20'; package: 'Glamour-Core' with: 'Glamour-Core-tg.142'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.83'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.45'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-tg.91'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-tg.1'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-tg.5'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-tg.21'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-tg.3'; package: 'Glamour-Examples' with: 'Glamour-Examples-tg.148'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.22'; package: 'Magritte-Model' with: 'Magritte-Model-lr.397'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-lr.13'; package: 'Magritte-Morph' with: 'Magritte-Morph-lr.52'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'TudorGirba 12/4/2010 20:08'! version20beta8: spec spec for: #common do: [ spec author: 'Alexandre Bergel'. spec timestamp: '12/2/2010 09:36'. spec description: 'Compatible with Pharo 1.1.1'. spec blessing: #development. spec project: 'Mondrian for Glamour' with: '2.1.2'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.5'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-tg.23'; package: 'Glamour-Core' with: 'Glamour-Core-tg.146'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-tg.88'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-tg.46'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-TudorGirba.100'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-TudorGirba.9'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-TudorGirba.21'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-tg.21'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-tg.4'; package: 'Glamour-Examples' with: 'Glamour-Examples-TudorGirba.156'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.23'; package: 'Magritte-Model' with: 'Magritte-Model-lr.397'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-lr.13'; package: 'Magritte-Morph' with: 'Magritte-Morph-lr.52'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'.].! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'GuillermoPolito 9/27/2011 02:11'! version21: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: 'New version'. spec author: 'AlexandreBergel'. spec timestamp: '2/17/2011 10:45'. spec project: 'Shout' with: '1.2.2'; project: 'Mondrian for Glamour' with: '2.49'; project: 'Grease' with: '1.0.3.1'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-tg.5'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-TudorGirba.25'; package: 'Glamour-Core' with: 'Glamour-Core-TudorGirba.159'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-TudorGirba.90'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-TudorGirba.55'; package: 'Glamour-Scripting' with: 'Glamour-Scripting-TudorGirba.112'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-TudorGirba.23'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-TudorGirba.70'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-TudorGirba.38'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-TudorGirba.27'; package: 'Glamour-Examples' with: 'Glamour-Examples-TudorGirba.162'; package: 'Glamour-Tools' with: 'Glamour-Tools-tg.23'; package: 'Magritte-Model' with: 'Magritte-Model-lr.404'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-lr.16'; package: 'Magritte-Morph' with: 'Magritte-Morph-lr.53'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'; package: 'Glamour-Mondrian-Presentations' with: 'Glamour-Mondrian-Presentations-TudorGirba.2'; package: 'Glamour-Magritte-Presentations' with: 'Glamour-Magritte-Presentations-tg.1'; package: 'Glamour-Tests-Mondrian' with: 'Glamour-Tests-Mondrian-TudorGirba.4'. ]. ! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'TudorGirba 3/4/2012 20:49'! version22: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: 'release for pharo 1.3'. spec author: 'GuillermoPolito'. spec timestamp: '9/26/2011 21:07'. spec package: 'CollectionExtensions' with: 'CollectionExtensions-TudorGirba.29'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-TudorGirba.6'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-TudorGirba.32'; package: 'Glamour-Core' with: 'Glamour-Core-TudorGirba.221'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-TudorGirba.109'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-TudorGirba.90'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-TudorGirba.66'; package: 'Glamour-Morphic-Widgets' with: 'Glamour-Morphic-Widgets-TudorGirba.31'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-TudorGirba.139'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-TudorGirba.55'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-TudorGirba.83'; package: 'Glamour-Examples' with: 'Glamour-Examples-TudorGirba.219'; package: 'Glamour-Tools' with: 'Glamour-Tools-TudorGirba.50'; package: 'Magritte-Model' with: 'Magritte-Model-NickAger.407'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-lr.16'; package: 'Magritte-Morph' with: 'Magritte-Morph-EstebanLorenzano.57'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'; package: 'Glamour-Mondrian-Presentations' with: 'Glamour-Mondrian-Presentations-TudorGirba.4'; package: 'Glamour-Magritte-Presentations' with: 'Glamour-Magritte-Presentations-TudorGirba.2'; package: 'Glamour-EyeSee-Presentations' with: 'Glamour-EyeSee-Presentations-AndreHora.2'; package: 'Glamour-Tests-Mondrian' with: 'Glamour-Tests-Mondrian-TudorGirba.5'; package: 'Glamour-Tests-EyeSee' with: 'Glamour-Tests-EyeSee-AndreHora.6'. ]! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'GuillermoPolito 4/26/2012 19:42'! version23: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: 'release for pharo 1.4'. spec author: 'GuillermoPolito'. spec timestamp: '2012-04-26T19:38:58.264+02:00'. spec package: 'CollectionExtensions' with: 'CollectionExtensions-TudorGirba.29'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-TudorGirba.7'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-TudorGirba.32'; package: 'Glamour-Core' with: 'Glamour-Core-TudorGirba.225'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-EstebanLorenzano.111'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-TudorGirba.90'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-TudorGirba.69'; package: 'Glamour-Morphic-Widgets' with: 'Glamour-Morphic-Widgets-EstebanLorenzano.38'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-EstebanLorenzano.145'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-TudorGirba.56'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-TudorGirba.87'; package: 'Glamour-Examples' with: 'Glamour-Examples-TudorGirba.235'; package: 'Glamour-Tools' with: 'Glamour-Tools-TudorGirba.51'; package: 'Magritte-Model' with: 'Magritte-Model-NickAger.407'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-lr.16'; package: 'Magritte-Morph' with: 'Magritte-Morph-EstebanLorenzano.57'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'; package: 'Glamour-Mondrian-Presentations' with: 'Glamour-Mondrian-Presentations-TudorGirba.4'; package: 'Glamour-Magritte-Presentations' with: 'Glamour-Magritte-Presentations-BenComan.3'; package: 'Glamour-EyeSee-Presentations' with: 'Glamour-EyeSee-Presentations-AndreHora.2'; package: 'Glamour-Tests-Mondrian' with: 'Glamour-Tests-Mondrian-TudorGirba.5'; package: 'Glamour-Tests-EyeSee' with: 'Glamour-Tests-EyeSee-AndreHora.6'. ]! ! !ConfigurationOfGlamour methodsFor: 'versions' stamp: 'DiegoLont 9/20/2013 16:05'! version24: spec spec for: #'common' do: [ spec blessing: #'release'. spec description: '-updated to Pharo 1.4 -using latest versions'. spec author: 'EstebanLorenzano'. spec timestamp: '6/3/2012 13:40'. spec project: 'Mondrian for Glamour' with: '2.157'; project: 'EyeSee for Glamour' with: '0.9.8'; project: 'Grease' with: #'stable'. spec package: 'Glamour-Announcements' with: 'Glamour-Announcements-TudorGirba.7'; package: 'Glamour-Helpers' with: 'Glamour-Helpers-TudorGirba.32'; package: 'Glamour-Core' with: 'Glamour-Core-TudorGirba.230'; package: 'Glamour-Presentations' with: 'Glamour-Presentations-EstebanLorenzano.111'; package: 'Glamour-Browsers' with: 'Glamour-Browsers-TudorGirba.93'; package: 'Glamour-Tests-Core' with: 'Glamour-Tests-Core-TudorGirba.73'; package: 'Glamour-Morphic-Widgets' with: 'Glamour-Morphic-Widgets-TudorGirba.52'; package: 'Glamour-Morphic-Renderer' with: 'Glamour-Morphic-Renderer-TudorGirba.159'; package: 'Glamour-Morphic-Theme' with: 'Glamour-Morphic-Theme-TudorGirba.60'; package: 'Glamour-Tests-Morphic' with: 'Glamour-Tests-Morphic-TudorGirba.92'; package: 'Glamour-Examples' with: 'Glamour-Examples-TudorGirba.239'; package: 'Glamour-Tools' with: 'Glamour-Tools-TudorGirba.55'; package: 'Magritte-Model' with: 'Magritte-Model-AvO.408'; package: 'Magritte-Tests-Model' with: 'Magritte-Tests-Model-AvO.17'; package: 'Magritte-Morph' with: 'Magritte-Morph-EstebanLorenzano.57'; package: 'Magritte-Pharo-Model' with: 'Magritte-Pharo-Model-lr.22'; package: 'Glamour-Mondrian-Presentations' with: 'Glamour-Mondrian-Presentations-TudorGirba.4'; package: 'Glamour-Magritte-Presentations' with: 'Glamour-Magritte-Presentations-BenComan.3'; package: 'Glamour-EyeSee-Presentations' with: 'Glamour-EyeSee-Presentations-AndreHora.2'; package: 'Glamour-Tests-Mondrian' with: 'Glamour-Tests-Mondrian-TudorGirba.5'; package: 'Glamour-Tests-EyeSee' with: 'Glamour-Tests-EyeSee-AndreHora.6' ]. spec for: #squeakCommon do: [ spec package: 'CollectionExtensions' with: 'CollectionExtensions-TudorGirba.32' ]. ! ! !ConfigurationOfGlamour methodsFor: 'snapshot versions' stamp: 'DiegoLont 9/20/2013 16:07'! version25snapshot: spec "generated by Snapshotcello" spec for: #common do: [ self populateSpec: spec with: self snapshot1 ]. spec for: #squeakCommon do: [ spec package: 'CollectionExtensions' with: 'CollectionExtensions-TudorGirba.34.mcz' ]! ! !ConfigurationOfRoassal class methodsFor: 'development support'! DevelopmentSupport "See the methods in the 'development support' category on the class-side of MetacelloBaseConfiguration. Decide what development support methods you would like to use and copy them the the class-side of your configuration." ! ! !ConfigurationOfRoassal class methodsFor: 'private'! baseConfigurationClassIfAbsent: aBlock ^Smalltalk at: #MetacelloBaseConfiguration ifAbsent: [ self ensureMetacelloBaseConfiguration. Smalltalk at: #MetacelloBaseConfiguration ifAbsent: aBlock ]. ! ! !ConfigurationOfRoassal class methodsFor: 'private'! ensureMetacello (self baseConfigurationClassIfAbsent: []) ensureMetacello! ! !ConfigurationOfRoassal class methodsFor: 'private'! ensureMetacelloBaseConfiguration Smalltalk at: #MetacelloBaseConfiguration ifAbsent: [ | repository version | repository := MCHttpRepository location: 'http://seaside.gemstone.com/ss/metacello' user: '' password: ''. repository versionReaderForFileNamed: 'Metacello-Base-DaleHenrichs.2.mcz' do: [ :reader | version := reader version. version load. version workingCopy repositoryGroup addRepository: repository ] ]! ! !ConfigurationOfRoassal class methodsFor: 'metacello tool support'! isMetacelloConfig "Answer true and the Metacello tools will operate on you" ^true! ! !ConfigurationOfRoassal class methodsFor: 'loading'! load "Load the #stable version defined for this platform. The #stable version is the version that is recommended to be used on this platform." "self load" ^(self project version: #stable) load! ! !ConfigurationOfRoassal class methodsFor: 'loading'! loadBleedingEdge "Load the latest versions of the mcz files defined for this project. It is not likely that the #bleedingEdge has been tested." "self loadBleedingEdge" ^(self project version: #bleedingEdge) load! ! !ConfigurationOfRoassal class methodsFor: 'loading'! loadDevelopment "Load the #development version defined for this platform. The #development version will change over time and is not expected to be stable." "self loadDevelopment" ^(self project version: #development) load! ! !ConfigurationOfRoassal class methodsFor: 'accessing'! project ^self new project! ! !ConfigurationOfRoassal class methodsFor: 'development support'! validate "Check the configuration for Errors, Critical Warnings, and Warnings (see class comment for MetacelloMCVersionValidator for more information). Errors identify specification issues that will result in unexpected behaviour when you load the configuration. Critical Warnings identify specification issues that may result in unexpected behavior when you load the configuration. Warnings identify specification issues that are technically correct, but are worth take a look at." "self validate" self ensureMetacello. ^ ((Smalltalk at: #MetacelloToolBox) validateConfiguration: self debug: #() recurse: false) explore! ! !ConfigurationOfRoassal methodsFor: 'baselines' stamp: 'AlexandreBergel 9/11/2013 23:34'! baseline15: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: '1.289 : cleaning and refactoring 1.290 : - Correctly implemented layout start, step and end announcement support. - Fixed a bug related to layout creation. Thanks Dennis Schenk!! 1.292 : removed unused method and added a comment 1.293 : added a small comment 1.294 : Fix by Juraj. 1.295 : fixing undeterministic tests with force layout 1.296 : Integrated many fixes 1.297 : Fixed Issue 307: Bug when exporting SVG 1.298 : Added a superclass ROAbstractPopupTest. A bit of cleaning 1.299 : Fixed Issue 308: Large popup in the wrong place 1.300 : Fixed Issue 309: empty categories are listed in the examples 1.301 : Roassal example about drawing 1.302 : Fixed Issue 310: Slow with inner nodes 1.303 : Having edges that show up when you enter a node is a recurrent need. I have worked on some easy way to make this possible. Using the Roassal low level api: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | view rawView el1 el2 el3 | rawView := ROView new. rawView add: (el1 := ROBox element size: 20). rawView add: (el2 := ROBox element size: 20). rawView add: (el3 := ROBox element size: 20). ROCircleLayout on: (Array with: el1 with: el2 with: el3). el1 @ RODraggable. el2 @ RODraggable. el3 @ RODraggable. el1 @ (RODynamicEdge toAll: (Array with: el2 with: el3) using: (ROLine arrowed color: Color red)). rawView open -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Using the Mondrian builder: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= view interaction dynamicEdge: [ :model | (Array with: 10 with: 20 with: 30) copyWithout: model ] using: (ROLine arrowed color: Color red). view shape rectangle size: 20. view nodes: (Array with: 10 with: 20 with: 30). view circleLayout. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1.304 : - Fixed Issue 311: ROHorizontalLineLayout>>positionOriginalPointer: buggy - cleaned a bit - testing ROPharoHTMLExporterTest 1.305 : Fixed Issue 311: ROHorizontalLineLayout>>positionOriginalPointer: buggy 1.306 : merged 1.307 : Merged 1.308 : Fixing Roassal.Core.Tests.ROEventTest.testProperlyInitialized 1.309 : Fixed Issue 312: Bugfix for ROTreeMapLayout 1.310 : Fixed Issue 313: RODynamicEdge cannot be combined 1.311 : Big big speed improvement 1.312 : Fixed Issue 314: Freezing the image with Otho lines Apparently lineSegmentsFor: returns an empty collection for Ortho lines. Which is obviously wrong. 1.312 : Fixed Issue 317: expectedFailures in Roassal is not properly defined - merged with Vanessa code Added ROMondrianViewBuilder >> removeNodesAndEdgesOf: so Juampi can remove nodes and edges easily :D - fixed issue: 315 with applying layout after removing and adding nodes - fixed RoassalSerializerExporterTest expected failures - tests added 1.314 : - Included Mathieu works on the radial tree layout - Added Bezier Curve - Fix by Milton on making Roassal importable in VisualWorks 1.315 : Added a test for the radial tree layout 1.409 : Included fix from Dennis for the two failing tests of the treemap 1.409 : Included fix for the two failing tests of Dennis 1.410 : simplified ROAttachPointTest>>setUp Run code critics on Roassal 1.429 : Fixed bug with the MouseClick'. spec author: 'AlexandreBergel'. spec timestamp: '9/11/2013 23:34'. spec repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main'. spec package: #Roassal; package: #RoassalMorphic. spec group: 'default' with: #(#Roassal #RoassalMorphic ); group: 'Tests' with: #(#Roassal #RoassalMorphic ). ]. ! ! !ConfigurationOfRoassal methodsFor: 'baselines' stamp: 'AlexandreBergel 9/14/2013 00:51'! baseline16: spec spec for: #'common' do: [ spec blessing: #'baseline'. spec description: ''. spec author: 'AlexandreBergel'. spec timestamp: '9/11/2013 23:34'. spec repository: 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main'. spec package: #Roassal; package: #RoassalMorphic; package: #RoassalExtras. spec group: 'default' with: #(#Roassal #RoassalMorphic #RoassalExtras); group: 'Tests' with: #(#Roassal #RoassalMorphic #RoassalExtras). ]. ! ! !ConfigurationOfRoassal methodsFor: 'symbolic versions' stamp: 'AlexandreBergel 9/14/2013 00:51'! development: spec spec for: #'common' version: '0.6-baseline'. ! ! !ConfigurationOfRoassal methodsFor: 'snapshots' stamp: 'TudorGirba 9/10/2013 08:46'! populateSpec: aSpec with: list "generated by Snapshotcello creates a spec object for the package and the version stored in the list" list do: [:each | aSpec package: each third with: [ aSpec file: (each first copyUpToLast: $. ). aSpec repository: each second ] ]! ! !ConfigurationOfRoassal methodsFor: 'accessing'! project ^ project ifNil: [ | constructor | "Bootstrap Metacello if it is not already loaded" (self class baseConfigurationClassIfAbsent: []) ensureMetacello. "Construct Metacello project" constructor := (Smalltalk at: #MetacelloVersionConstructor) on: self. project := constructor project. project loadType: #linear. "change to #atomic if desired" project ]! ! !ConfigurationOfRoassal methodsFor: 'snapshots' stamp: 'TudorGirba 9/10/2013 08:46'! snapshot1 "generated by Snapshotcello" ^ #( #('Roassal-AlexandreBergel.668.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'Roassal' ) #('RoassalMorphic-AlexandreBergel.146.mcz' 'http://www.smalltalkhub.com/mc/ObjectProfile/Roassal/main/' 'RoassalMorphic' ) )! ! !ConfigurationOfRoassal methodsFor: 'symbolic versions' stamp: 'TudorGirba 9/10/2013 08:46'! stable: spec spec for: #'common' version: '1.408'. spec for: #'pharo2.x' version: '1.428-snapshot'. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1400: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.400 : Fixed Issue 348: horizontalOutGap: and verticalOutGap: are not necessary'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/11/2013 17:28'. spec package: #Roassal with: 'Roassal-AlexandreBergel.637'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.142'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1401: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.401 : fix with the Diamond test'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/11/2013 17:30'. spec package: #Roassal with: 'Roassal-AlexandreBergel.637'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1402: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.402 : Removed testNoPadding6, which was not portable (fail on Jenkins)'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/11/2013 17:42'. spec package: #Roassal with: 'Roassal-AlexandreBergel.638'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1403: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.403: - Issue 349: Need a better way to define edges - Issue 350: Need to define better way for callbacks when modifying an element'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/11/2013 22:18'. spec package: #Roassal with: 'Roassal-AlexandreBergel.639'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1404: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.404 : - Test for Issue 350: Need to define better way for callbacks when modifying an element'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/11/2013 22:29'. spec package: #Roassal with: 'Roassal-AlexandreBergel.640'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1405: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.405: Fixed Issue 351: MondrianViewBuilder should support a better zOrder'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/12/2013 14:19'. spec package: #Roassal with: 'Roassal-AlexandreBergel.641'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1406: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.406 : Fixed Issue 352: Replacing elements in a container'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/12/2013 18:49'. spec package: #Roassal with: 'Roassal-AlexandreBergel.641'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1407: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.407 : Fixed Issue 353: (ROLine buildEdgesFromElements: #() from: nil to: nil) raise en error, it should not'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/12/2013 19:11'. spec package: #Roassal with: 'Roassal-AlexandreBergel.643'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:30'! version1408: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.408 : Failing test as expectedFailure. Waiting for Dennis to do something'. spec author: 'AlexandreBergel'. spec timestamp: 'AlexandreBergel 8/12/2013 19:15'. spec package: #Roassal with: 'Roassal-AlexandreBergel.643'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/15/2013 18:32'! version1409: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.409 : Included fix for the two failing tests of Dennis'. spec author: 'AlexandreBergel'. spec timestamp: '8/15/2013 18:32'. spec package: #Roassal with: 'Roassal-AlexandreBergel.645'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/20/2013 21:33'! version1410: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.410 : simplified ROAttachPointTest>>setUp'. spec author: 'AlexandreBergel'. spec timestamp: '8/20/2013 21:33'. spec package: #Roassal with: 'Roassal-AlexandreBergel.646'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'TudorGirba 8/27/2013 11:55'! version1411: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.411 : Border width fix'. spec author: 'TudorGirba'. spec timestamp: '8/27/2013 11:21'. spec package: #Roassal with: 'Roassal-TudorGirba.651'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143' ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/27/2013 21:55'! version1412: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: 'Run code critics on Roassal 1.412 : added ROTriangle'. spec author: 'AlexandreBergel'. spec timestamp: '8/27/2013 21:55'. spec package: #Roassal with: 'Roassal-AlexandreBergel.653'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.143'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/28/2013 14:02'! version1413: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.412 : added ROTriangle 1.413 : Triangles are now supported. Not for Athens however'. spec author: 'AlexandreBergel'. spec timestamp: '8/28/2013 14:02'. spec package: #Roassal with: 'Roassal-AlexandreBergel.654'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.144'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/28/2013 16:12'! version1414: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.413 : Triangles are now supported. Not for Athens however 1.414 : Fixed Issue 357: stretch Horizontally'. spec author: 'AlexandreBergel'. spec timestamp: '8/28/2013 16:12'. spec package: #Roassal with: 'Roassal-AlexandreBergel.655'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.144'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/28/2013 18:22'! version1415: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.414 : Fixed Issue 357: stretch Horizontally 1.415 : Worked on animated resizing. Consider the following examples: view := ROView new. el := (ROBox new extent: 50 @ 50) element. view add: el . el @ RODraggable. view open. ROAnimatedResizing for: el resizeAndFixBottomLeft: 400 @ 100. ROAnimatedResizing for: el resizeAndFixBottomLeft: 40 @ 10. ROBlink on: el'. spec author: 'AlexandreBergel'. spec timestamp: '8/28/2013 18:22'. spec package: #Roassal with: 'Roassal-AlexandreBergel.656'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.144'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/29/2013 08:15'! version1416: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.415 : Worked on animated resizing. Consider the following examples: view := ROView new. el := (ROBox new extent: 50 @ 50) element. view add: el . el @ RODraggable. view open. ROAnimatedResizing for: el resizeAndFixBottomLeft: 400 @ 100. ROAnimatedResizing for: el resizeAndFixBottomLeft: 40 @ 10. ROBlink on: el 1.416 : fixed a broken test 1.416 : Fixed Issue 359: the triangle should not have a black border'. spec author: 'AlexandreBergel'. spec timestamp: '8/29/2013 08:15'. spec package: #Roassal with: 'Roassal-AlexandreBergel.658'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.145'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/29/2013 08:37'! version1417: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.416 : Fixed Issue 359: the triangle should not have a black border 1.417 : Fixed Issue 360: Treemaplayout, minimum size'. spec author: 'AlexandreBergel'. spec timestamp: '8/29/2013 08:37'. spec package: #Roassal with: 'Roassal-AlexandreBergel.659'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.145'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 8/29/2013 09:28'! version1418: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.417 : Fixed Issue 360: Treemaplayout, minimum size 1.418 : Fixed Issue 361: Roassal crops the exported PNG Fixed http://code.google.com/p/moose-technology/issues/detail?id=969'. spec author: 'AlexandreBergel'. spec timestamp: '8/29/2013 09:28'. spec package: #Roassal with: 'Roassal-AlexandreBergel.660'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.145'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 09:03'! version1419: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.418 : Fixed Issue 361: Roassal crops the exported PNG Fixed http://code.google.com/p/moose-technology/issues/detail?id=969 1.419 : Fix in the #animation example'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 09:03'. spec package: #Roassal with: 'Roassal-AlexandreBergel.661'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 09:32'! version1420: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.419 : Fix in the #animation example 1.420 : Added utility methods to write: | view | view := ROView new. view addAll: (ROBox elementsOn: (1 to: 5) ). view addAll: (ROLine buildEdgesFromAssociations: {1 -> 3 . 3 -> 5. 1 -> 4 . 4 -> 5} inView: view). ROHorizontalTreeLayout on: view elements. view open'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 09:32'. spec package: #Roassal with: 'Roassal-AlexandreBergel.662'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 09:36'! version1421: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.420 : Added utility methods to write: | view | view := ROView new. view addAll: (ROBox elementsOn: (1 to: 5) ). view addAll: (ROLine buildEdgesFromAssociations: {1 -> 3 . 3 -> 5. 1 -> 4 . 4 -> 5} inView: view). ROHorizontalTreeLayout on: view elements. view open 1.421 : Added example for the buildingEdge in Roassal'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 09:36'. spec package: #Roassal with: 'Roassal-AlexandreBergel.663'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 11:47'! version1422: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.421 : Added example for the buildingEdge in Roassal 1.422 : Fixed Issue 363: How to get vertical labels with Roassal?'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 11:47'. spec package: #Roassal with: 'Roassal-AlexandreBergel.664'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 11:54'! version1423: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.422 : Fixed Issue 363: How to get vertical labels with Roassal? 1.423 : Fixed Issue 364: Vertical labels shows quotes'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 11:54'. spec package: #Roassal with: 'Roassal-AlexandreBergel.665'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 12:02'! version1424: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.423 : Fixed Issue 364: Vertical labels shows quotes 1.424 : have a -4 interlineSpace for vertical labels'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 12:02'. spec package: #Roassal with: 'Roassal-AlexandreBergel.666'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/1/2013 20:47'! version1425: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.424 : have a -4 interlineSpace for vertical labels 1.425 : added pluggable callback. Worked on the build edges utility methods. Fixed a number of issues'. spec author: 'AlexandreBergel'. spec timestamp: '9/1/2013 20:47'. spec package: #Roassal with: 'Roassal-AlexandreBergel.667'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/2/2013 19:24'! version1426: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.425 : added pluggable callback. Worked on the build edges utility methods. Fixed a number of issues 1.426 : Worked on the callback. Need some more work however...'. spec author: 'AlexandreBergel'. spec timestamp: '9/2/2013 19:24'. spec package: #Roassal with: 'Roassal-AlexandreBergel.668'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/2/2013 19:25'! version1427: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.426 : Worked on the callback. Need some more work however...'. spec author: 'AlexandreBergel'. spec timestamp: '9/2/2013 19:25'. spec package: #Roassal with: 'Roassal-AlexandreBergel.668'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.146'. ]. ! ! !ConfigurationOfRoassal methodsFor: 'snapshot versions' stamp: 'TudorGirba 9/10/2013 08:46'! version1428snapshot: spec "generated by Snapshotcello" spec for: #common do: [ self populateSpec: spec with: self snapshot1 ]! ! !ConfigurationOfRoassal methodsFor: 'versions' stamp: 'AlexandreBergel 9/11/2013 23:34'! version1429: spec spec for: #'common' do: [ spec blessing: #'development'. spec description: '1.429 : Fixed bug with the MouseClick'. spec author: 'AlexandreBergel'. spec timestamp: '9/11/2013 23:34'. spec package: #Roassal with: 'Roassal-AlexandreBergel.669'; package: #RoassalMorphic with: 'RoassalMorphic-AlexandreBergel.147'. ]. ! ! !GLMAbstractWizardStep methodsFor: 'testing' stamp: 'cyrilledelaunay 4/4/2011 13:57'! atBeginning ^ self numberOfDisplay = 1! ! !GLMAbstractWizardStep methodsFor: 'testing' stamp: 'cyrilledelaunay 4/4/2011 17:10'! atEnd ^ self size = self numberOfDisplay ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:43'! decrementNumberOfDisplay self numberOfDisplay: self numberOfDisplay - 1! ! !GLMAbstractWizardStep methodsFor: 'scripting' stamp: 'cyrilledelaunay 4/4/2011 13:17'! from: aSymbol self previousStep: aSymbol ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:43'! incrementNumberOfDisplay self numberOfDisplay: self numberOfDisplay + 1! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 14:00'! input ^ input ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 14:01'! input: anObject input := anObject! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:07'! name ^ name ifNil: [name := '']! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:02'! name: aSymbolOrABlock name := aSymbolOrABlock! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:07'! numberOfDisplay ^ numberOfDisplay ifNil: [numberOfDisplay := 0]! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 13:06'! numberOfDisplay: aNumber numberOfDisplay := aNumber! ! !GLMAbstractWizardStep methodsFor: 'testing' stamp: 'cyrilledelaunay 5/25/2011 10:29'! overBeginning ^ self numberOfDisplay < 1! ! !GLMAbstractWizardStep methodsFor: 'testing' stamp: 'cyrilledelaunay 5/24/2011 17:12'! overEnd ^ self size < self numberOfDisplay ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:02'! presentationBlock ^ presentationBlock ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:02'! presentationBlock: aBlock presentationBlock := aBlock! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/12/2011 12:02'! previousStep ^ previousStep ifNil: [previousStep := OrderedCollection new]! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/12/2011 12:03'! previousStep: aSymbol self previousStep add: aSymbol! ! !GLMAbstractWizardStep methodsFor: 'scripting' stamp: 'cyrilledelaunay 4/4/2011 13:16'! show: aBlock self presentationBlock: aBlock ! ! !GLMAbstractWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:03'! size ^ self subclassResponsibility ! ! !GLMWizardGenericStep methodsFor: 'initialize-release' stamp: 'cyrilledelaunay 4/4/2011 13:51'! initialize super initialize. size := 1! ! !GLMWizardGenericStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/24/2011 16:42'! numberOfDisplay self numberOfDisplayBlock isNil ifFalse: [ ^ self numberOfDisplayBlock moValue: self input ] ifTrue: [ ^ super numberOfDisplay ]. ! ! !GLMWizardGenericStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/24/2011 16:38'! numberOfDisplayBlock ^ numberOfDisplayBlock! ! !GLMWizardGenericStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 5/24/2011 16:38'! numberOfDisplayBlock: aBlock "this method allow the user to externally control the progression of this step. In merlin for exemple, it can be usefull to have some 'conditions' to validate before going on. If those conditions are not validated, we do not progress" numberOfDisplayBlock := aBlock! ! !GLMWizardGenericStep methodsFor: 'accessing' stamp: 'AndreiChis 12/4/2012 11:08'! size ^ size glamourValue: self input! ! !GLMWizardGenericStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:06'! size: aNumberOrAblock size := aNumberOrAblock ! ! !GLMWizardStep methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/4/2011 12:04'! size ^ 1! ! !GLMBrowserTemplate class methodsFor: 'opening' stamp: 'tg 12/29/2009 03:33'! openOn: anEntity ^ self new openOn: anEntity! ! !GLMBrowserTemplate class methodsFor: 'opening' stamp: 'tg 1/15/2010 23:46'! startOn: anEntity ^ self new startOn: anEntity! ! !GLMBrowserTemplate methodsFor: 'accessing' stamp: 'tg 12/29/2009 03:41'! browser ^ browser ifNil: [self buildBrowser. browser]! ! !GLMBrowserTemplate methodsFor: 'building' stamp: 'tg 12/15/2009 13:54'! buildBrowser ^ self subclassResponsibility! ! !GLMBrowserTemplate methodsFor: 'opening' stamp: 'tg 12/29/2009 03:30'! openOn: anEntity ^ self browser openOn: anEntity! ! !GLMBrowserTemplate methodsFor: 'opening' stamp: 'tg 1/15/2010 23:31'! startOn: anEntity ^ self browser startOn: anEntity! ! !GLMGlobalBrowserTemplate class methodsFor: 'opening' stamp: 'tg 12/29/2009 03:31'! open ^ self new open! ! !GLMGlobalBrowserTemplate methodsFor: 'opening' stamp: 'tg 12/29/2009 03:31'! entity ^ self subclassResponsibility! ! !GLMGlobalBrowserTemplate methodsFor: 'opening' stamp: 'tg 12/29/2009 03:31'! open ^ self openOn: self entity! ! !GLMParameterizableExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:50' prior: 34279950! This is an abstract class that provides the infrastructure for an example browser. It is meant to work with classes that hold examples in methods.! !GLMEyeSeeExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:44' prior: 34280176! self new openOn: ESExamples! !GLMEyeSeeExamplesBrowser class methodsFor: 'instance creation' stamp: 'TudorGirba 9/9/2012 02:55'! open ^ self new openOn: ESExamples! ! !GLMEyeSeeExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:43'! exampleSelectorsFromClass: exampleClass ^ exampleClass selectors select: [ :each | each endsWith: 'With:' ]! ! !GLMEyeSeeExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 5/21/2013 21:54'! installTitle browser title: 'EyeSee Examples'! ! !GLMEyeSeeExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:45'! renderedExampleIn: composer composer eyesee title: 'Example'; diagram: [ :renderer :exampleClass :exampleSelector | exampleClass new perform: exampleSelector with: renderer ]! ! !GLMParameterizableExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 5/21/2013 21:53'! buildBrowser browser := GLMTabulator new. self installTitle. browser column: #titles; column: #example span: 4. browser transmit to: #titles; andShow: [ :a | self exampleListIn: a ]. browser transmit to: #example; fromOutsidePort: #entity; from: #titles; andShow: [ :a | self exampleIn: a ]. ^ browser! ! !GLMParameterizableExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 02:49'! compose self tabulator with: [ :browser | browser column: #titles; column: #example span: 4. browser transmit to: #titles; andShow: [ :a | self exampleListIn: a ]. browser transmit to: #example; fromOutsidePort: #entity; from: #titles; andShow: [ :a | self exampleIn: a ] ]! ! !GLMParameterizableExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 02:50'! exampleIn: composer self renderedExampleIn: composer. composer smalltalkCode title: 'Source code'; act: [ :text :exampleClass :exampleSelector | Smalltalk tools browser fullOnClass: exampleClass selector: exampleSelector ] icon: GLMUIThemeExtraIcons glamorousBrowse entitled: 'Browse'; smalltalkClass: [ :exampleClass | exampleClass ]; doItReceiver: [ :exampleClass | exampleClass ]; display: [ :exampleClass :exampleSelector | exampleClass sourceCodeAt: exampleSelector ]! ! !GLMParameterizableExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 02:42'! exampleListIn: a ^ a list title: 'Examples'; display: [ :exampleClass | self exampleSelectorsFromClass: exampleClass ]; sorted: [ :x :y | x < y ]; format: [ :selector | ' ' join: ((selector piecesCutWhereCamelCase reject: [:each | each endsWith: ':']) collect: #capitalized) ]! ! !GLMParameterizableExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:43'! exampleSelectorsFromClass: exampleClass self subclassResponsibility! ! !GLMParameterizableExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 5/21/2013 21:53'! installTitle "Override this method for specific title"! ! !GLMParameterizableExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:43'! renderedExampleIn: composer self subclassResponsibility! ! !GLMRoassalExamplesBrowser commentStamp: 'TudorGirba 9/9/2012 02:47' prior: 34280284! self new openOn: ROMondrianExample! !GLMRoassalExamplesBrowser class methodsFor: 'instance creation' stamp: 'TudorGirba 9/9/2012 02:56'! open ^ self new openOn: ROMondrianExample! ! !GLMRoassalExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:46'! exampleSelectorsFromClass: exampleClass ^ exampleClass selectors select: [ :each | each endsWith: 'On:' ]! ! !GLMRoassalExamplesBrowser methodsFor: 'building' stamp: 'TudorGirba 5/21/2013 21:54'! installTitle browser title: 'Roassal Examples'! ! !GLMRoassalExamplesBrowser methodsFor: 'hooks' stamp: 'TudorGirba 9/9/2012 02:47'! renderedExampleIn: composer composer roassal title: 'Example'; painting: [ :view :exampleClass :exampleSelector | exampleClass new perform: exampleSelector with: view ]! ! !GLMScriptingEditorTemplate commentStamp: 'TudorGirba 12/28/2011 23:33' prior: 34280402! GLMScriptingEditorTemplate offers a simple template for building scripting editors. It offers basically three panes: - one for the script - one for the set of input variables - one for the preview once you accept the script A typical case is provided by the GLMMondrianEasel. To open any of the subclasses, you need to provide an array of associations whose values represent the names of a variables and the values are the objects referred by these variables. These variables can then be used in the code of the script.! !GLMEditor commentStamp: 'TudorGirba 12/28/2011 23:33' prior: 34280991! This is an Glamour-based editor for Glamour browsers. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMEditor methodsFor: 'private' stamp: 'TudorGirba 4/26/2013 07:07'! createResultBrowserWithBindings: bindings andScript: script | context resultBrowser scriptedBrowser composer | composer := GLMCompositePresentation new. context := GLMDoItContext with: #composer -> composer withAll: bindings. [ Compiler new evaluate: script in: context to: context ] on: Error do: [ :e | self inform: e class name , ': ' , e errorMessage. ^ GLMWrapper new show: #text; startOn: e class name , ': ' , e errorMessage ]. scriptedBrowser := composer first. resultBrowser := GLMTabulator new. resultBrowser column: #theOuterPane. resultBrowser transmit fromOutsideEntityPort; to: #theOuterPane; andShow: [ :a | a custom: scriptedBrowser ]. "this is a bit of a hack. we take the entity as specified in the script by taking it directly from the evaluated script browser. this is needed because right now the input entity is specified in the same script with the browser" ^ resultBrowser startOn: composer entity! ! !GLMEditor methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:51'! defaultScriptBindings ^ {#composer -> GLMCompositePresentation new}! ! !GLMEditor methodsFor: 'building' stamp: 'TudorGirba 6/1/2012 20:13'! defaultScriptDisplayIn: aTextPresentation ^ aTextPresentation display: 'composer'; morphicAct: [:text | GLMBasicExamples open ] icon: GLMUIThemeExtraIcons glamorousExample entitled: 'Browse basic examples'! ! !GLMEditor methodsFor: 'building' stamp: 'TudorGirba 12/8/2012 14:30'! defaultTitle ^ 'Glamour Editor'! ! !GLMEditor methodsFor: 'building' stamp: 'TudorGirba 5/24/2012 17:20'! resultIn: composite composite dynamic title: 'Preview'; display: [ :bindings :script | self createResultBrowserWithBindings: bindings andScript: script ]; act: [ :dynamic | dynamic cachedPresentation presentations first panes first presentations first openTree ] entitled: 'View browser tree'; act: [:dynamic | dynamic cachedPresentation presentations first panes first presentations first explore ] icon: GLMUIThemeExtraIcons glamorousInspect entitled: 'Explore'; act: [ :dynamic | dynamic cachedPresentation presentations first panes first presentations first open ] icon: GLMUIThemeExtraIcons glamorousSpawn entitled: 'Spawn browser'! ! !GLMEyeSeeEditor commentStamp: 'TudorGirba 12/28/2011 23:34' prior: 34281249! This browser offers a Glamour-based editor for EyeSee charts. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMEyeSeeEditor methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:57'! defaultScriptBindings ^ {#chart -> ESDiagramRenderer new}! ! !GLMEyeSeeEditor methodsFor: 'building' stamp: 'TudorGirba 6/5/2013 22:19'! defaultScriptDisplayIn: aPresentation ^ aPresentation display: 'chart'; morphicAct: [:text | GLMEyeSeeExamplesBrowser open ] icon: GLMUIThemeExtraIcons glamorousExample entitled: 'Browse basic examples'! ! !GLMEyeSeeEditor methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:57'! defaultTitle ^ 'EyeSee Editor'! ! !GLMEyeSeeEditor methodsFor: 'building' stamp: 'TudorGirba 6/5/2013 22:20'! resultIn: a ^ a eyesee title: 'Chart'; diagram: [ :renderer :bindings :script | | context | context := GLMDoItContext with: #chart -> renderer withAll: bindings. [ Compiler new evaluate: script in: context to: context ] on: Error do: [ :e | self inform: e class name , ': ' , e errorMessage. (renderer pieDiagram) radius: 100; models: #('Error'); pieValue: [:x | 100]; displayLegend: true; defaultColor: Color red ] ]; defaultActions! ! !GLMMondrianEasel commentStamp: 'TudorGirba 12/28/2011 23:34' prior: 34281516! This browser offers a Glamour-based MondrianEasel. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMMondrianEasel methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:51'! defaultScriptBindings ^ {#view -> MOViewRenderer new}! ! !GLMMondrianEasel methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:51'! defaultScriptDisplayIn: aPresentation ^ aPresentation display: 'view'! ! !GLMMondrianEasel methodsFor: 'building' stamp: 'TudorGirba 9/5/2011 19:04'! defaultTitle ^ 'Mondrian Easel'! ! !GLMMondrianEasel methodsFor: 'private' stamp: 'TudorGirba 4/26/2013 07:38'! evaluate: script in: context for: view | message | ^ [ Compiler new evaluate: script in: context to: context ] on: Error do: [ :e | message := e class name , ': ' , e errorMessage. self inform: message. view shape label fontColor: Color red; withText . view node: message ]! ! !GLMMondrianEasel methodsFor: 'building' stamp: 'TudorGirba 4/26/2013 07:30'! resultIn: a ^ a mondrian title: 'Painting'; painting: [ :view :bindings :script | | context | context := GLMDoItContext with: #view -> view withAll: bindings. self evaluate: script in: context for: view ]; act: [ :m | m canvas exportAsPNG ] entitled: 'Export as PNG'; act: [ :m | m canvas exportAsJPEG ] entitled: 'Export as JPEG'; act: [ :m | m canvas exportAsSVG ] entitled: 'Export as SVG'; act: [ :m | m canvas exportAsTikz ] entitled: 'Export as Tikz'; act: [ :m | m canvas exportAsXML ] entitled: 'Export as XML'; act: [ :m | m canvas root decreaseZoom. m canvas changed ] icon: MondrianIcons mondrianZoomOut on: $- entitled: 'Zoom out'; act: [ :m | m canvas root increaseZoom. m canvas changed ] icon: MondrianIcons mondrianZoomIn on: $+ entitled: 'Zoom in'! ! !GLMRoassalEasel commentStamp: '' prior: 34281756! This browser offers a Glamour-based Roassal Easel. Example: self openOn: {#variable->'value'} This will open the editor with a variable named #variable whose value will be 'value'.! !GLMRoassalEasel methodsFor: 'building' stamp: 'TudorGirba 6/5/2012 17:10'! defaultScriptBindings ^ {#view -> ROMondrianViewBuilder new}! ! !GLMRoassalEasel methodsFor: 'building' stamp: 'TudorGirba 9/9/2012 02:56'! defaultScriptDisplayIn: aPresentation ^ aPresentation display: 'view'; morphicAct: [:text | GLMRoassalExamplesBrowser open ] icon: GLMUIThemeExtraIcons glamorousExample entitled: 'Browse basic examples'! ! !GLMRoassalEasel methodsFor: 'building' stamp: 'TudorGirba 5/7/2012 10:18'! defaultTitle ^ 'Roassal Easel'! ! !GLMRoassalEasel methodsFor: 'private' stamp: 'TudorGirba 8/10/2013 23:25'! evaluate: script in: context for: view | message | ^ [ Compiler new evaluate: script in: context to: context ] on: Error do: [ :e | message := e class name , ': ' , e messageText. self inform: message. view shape label color: Color red lighter; withText . view node: message ]! ! !GLMRoassalEasel methodsFor: 'building' stamp: 'TudorGirba 6/5/2013 23:11'! resultIn: a ^ a roassal title: 'View'; painting: [ :view :bindings :script | | context | context := GLMDoItContext with: #view -> view withAll: bindings. self evaluate: script in: context for: view ]! ! !GLMScriptingEditorTemplate class methodsFor: 'instance creation' stamp: 'TudorGirba 6/1/2012 20:09'! open ^ self openOn: {}! ! !GLMScriptingEditorTemplate class methodsFor: 'instance creation' stamp: 'TudorGirba 1/4/2012 08:08'! openOn: anArrayOfAssociations "To spawn an editor, provide an array of associations whose values represent the names of a variables and the values are the objects referred by these variables. These variables can then be used in the code of the script. For example: GLMEditor openOn: {#variable1->'value1' . #variable2->'value2'}" ^ super openOn: anArrayOfAssociations! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 9/5/2011 19:05'! buildBrowser browser := GLMTabulator new. self setTitleOf: browser. browser row: #result span: 2; row: [ :r | r column: #script span: 3; column: #variables span: 2 ]. browser transmit to: #script; andShow: [ :a | self scriptIn: a ]. browser transmit to: #variables; andShow: [ :a | self variablesIn: a ]. browser transmit to: #result; fromOutsidePort: #entity; from: #script; andShow: [ :a | self resultIn: a ]. ^ browser! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:51'! defaultScriptBindings "Override this method if you want to provide more bindings for your editor. Typically these bindings are related to the Facade that offers the entry point to the scripting API" ^ {}! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 10/8/2011 19:51'! defaultScriptDisplayIn: aPresentation ^ ''! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 9/5/2011 19:06'! defaultTitle ^ 'Editor'! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 9/5/2011 18:55'! resultIn: a "Override this method to describe the presentation that should show the result of evaluating the script" self subclassResponsibility ! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 5/24/2012 18:16'! scriptIn: a ^ a smalltalkCode title: 'Script'; variableBindings: [ :bindings | | col | col := OrderedCollection withAll: bindings. col addAll: self defaultScriptBindings. col ]; with: [:p | self defaultScriptDisplayIn: p ]; populate: #selection icon: GLMUIThemeExtraIcons glamorousPlay on: $s entitled: 'Generate' with: [ :text | text text ] "; act: [:text | text text ] icon: GLMUIThemeExtraIcons glamorousAccept entitled: 'Install'"! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 9/5/2011 19:05'! setTitleOf: b b title: self defaultTitle! ! !GLMScriptingEditorTemplate methodsFor: 'building' stamp: 'TudorGirba 11/15/2011 21:44'! variablesIn: a ^ a table selectionAct: [:t | t selection value inspect ] on: $i entitled: 'Inspect'; selectionAct: [:t | t selection value explore ] on: $I entitled: 'Explore'; column: 'Variable' evaluated: [ :each | each key asString ]; column: 'Value' evaluated: [ :each | each value asString contractTo: 20 ]! ! !GLMColor methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/13/2011 16:51'! cssColor "should return a css color code" ^ self subclassResponsibility ! ! !GLMColor methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/13/2011 16:52'! morphicColor "should return an object kind of Color" ^ self subclassResponsibility ! ! !GLMTransparentColor methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/13/2011 16:52'! cssColor ^ 'transparent'! ! !GLMTransparentColor methodsFor: 'accessing' stamp: 'cyrilledelaunay 7/13/2011 16:52'! morphicColor ^ Color transparent! ! !GLMCompositeArrangement commentStamp: 'tg 1/6/2010 23:12' prior: 34282009! This is a strategy to capture the intended arrangement of multiple presentations of a composite presentation. The subclasses define the actual arrangement.! !GLMAccordionArrangement methodsFor: 'rendering' stamp: 'tg 1/6/2010 23:23'! renderGlamorouslyOn: aRenderer ^ aRenderer renderAccordionCompositePresentation: self composite! ! !GLMCompositeArrangement class methodsFor: 'as yet unclassified' stamp: 'tg 1/6/2010 23:14'! of: aCompositePresentation ^ self new composite: aCompositePresentation; yourself! ! !GLMCompositeArrangement methodsFor: 'accessing' stamp: 'tg 1/6/2010 23:13'! composite ^ composite! ! !GLMCompositeArrangement methodsFor: 'accessing' stamp: 'tg 1/6/2010 23:13'! composite: anObject composite := anObject! ! !GLMCompositeArrangement methodsFor: 'rendering' stamp: 'tg 1/6/2010 23:16'! renderGlamorouslyOn: aRenderer self subclassResponsibility! ! !GLMStackedVerticallyArrangement methodsFor: 'rendering' stamp: 'tg 1/7/2010 09:38'! renderGlamorouslyOn: aRenderer ^ aRenderer renderStackedVerticallyCompositePresentation: self composite! ! !GLMTabbedArrangement methodsFor: 'rendering' stamp: 'tg 1/6/2010 23:23'! renderGlamorouslyOn: aRenderer ^ aRenderer renderTabbedCompositePresentation: self composite! ! !GLMCondition commentStamp: 'TudorGirba 7/14/2011 10:53' prior: 34282233! GLMCondition is the abstract class for defininf a boolean condition applied on some input arguments. It is meant to be subclassed.! !GLMAllNilCondition methodsFor: 'glamour' stamp: 'VeronicaUquillas 2/18/2011 15:11'! glamourValueWithArgs: anArray ^anArray allSatisfy: [:each | each isNil]! ! !GLMAllNotNilCondition commentStamp: '' prior: 34282427! Used to test if all defined arguments of a condition or not nil. We use this as a default condition for presentations. Usually, you will want to define a condition as a block such as '[ :class :category | (class isKindOf: Class) and: [ category isKindOf: Symbol ] ]' (or something like that) but sometimes you just want to make sure that all arguments are defined. Since we do not know the number of arguments in advance, we use this class to interpret #glamourValueWithArgs: and return true if all arguments are not nil.! !GLMAllNotNilCondition methodsFor: 'glamour' stamp: 'DamienCassou 9/10/2009 19:54'! glamourValueWithArgs: anArray ^anArray allSatisfy: [:each | each notNil]! ! !GLMSomeNotNilCondition methodsFor: 'glamour' stamp: 'tg 12/31/2009 00:22'! glamourValueWithArgs: anArray ^anArray anySatisfy: [:each | each notNil]! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! browser ^browser! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! browser: anObject browser := anObject! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! children ^children ifNil: [children := OrderedCollection new]! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! children: anObject children := anObject! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! childrenCount ^self children inject: 0 into: [:sum :each | sum + each span]! ! !GLMCustomCell methodsFor: 'testing' stamp: ' 4/5/09 22:18'! hasId ^id notNil! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! id ^id ifNil: [#anonymous]! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! id: anObject id := anObject! ! !GLMCustomCell methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isColumn ^false! ! !GLMCustomCell methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isRow ^false! ! !GLMCustomCell methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isSplitIntoColumns ^self children allSatisfy: [:each | each isColumn]! ! !GLMCustomCell methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isSplitIntoRows ^self children allSatisfy: [:each | each isRow]! ! !GLMCustomCell methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:17'! size ^ size ifNil: [0]! ! !GLMCustomCell methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:20'! size: anObject size := anObject.! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! span ^span ifNil: [span := 1]! ! !GLMCustomCell methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! span: anObject span := anObject! ! !GLMCustomColumn methodsFor: 'accessing' stamp: 'jorge.ressia 6/2/2009 21:53'! addRow: aBlockOrSymbol | newRow cell | cell := aBlockOrSymbol isSymbol ifTrue: [self browser addNewPaneNamed: aBlockOrSymbol. (GLMCustomRow new) id: aBlockOrSymbol; browser: self browser] ifFalse: [newRow := GLMCustomRow new browser: self browser. aBlockOrSymbol value: newRow. newRow]. self children addLast: cell. ^cell! ! !GLMCustomColumn methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:20'! addRow: aBlockOrSymbol size: anInteger ^(self addRow: aBlockOrSymbol) size: anInteger; span: 0! ! !GLMCustomColumn methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:20'! addRow: aBlockOrSymbol span: anInteger ^(self addRow: aBlockOrSymbol) span: anInteger; size: 0! ! !GLMCustomColumn methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isColumn ^true! ! !GLMCustomColumn methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! row: aBlockOrSymbol ^self addRow: aBlockOrSymbol! ! !GLMCustomColumn methodsFor: 'scripting' stamp: 'tg 10/21/2009 22:08'! row: aBlockOrSymbol size: anInteger ^self addRow: aBlockOrSymbol size: anInteger! ! !GLMCustomColumn methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! row: aBlockOrSymbol span: anInteger ^self addRow: aBlockOrSymbol span: anInteger! ! !GLMCustomRow methodsFor: 'accessing' stamp: 'jorge.ressia 6/2/2009 21:49'! addColumn: aBlockOrSymbol | newColumn cell | cell := aBlockOrSymbol isSymbol ifTrue: [self browser addNewPaneNamed: aBlockOrSymbol. (GLMCustomColumn new) id: aBlockOrSymbol; browser: self browser] ifFalse: [newColumn := GLMCustomColumn new browser: self browser. aBlockOrSymbol value: newColumn. newColumn]. self children addLast: cell. ^cell! ! !GLMCustomRow methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:21'! addColumn: aBlockOrSymbol size: anInteger ^(self addColumn: aBlockOrSymbol) size: anInteger; span: 0! ! !GLMCustomRow methodsFor: 'accessing' stamp: 'tg 10/22/2009 10:21'! addColumn: aBlockOrSymbol span: anInteger ^(self addColumn: aBlockOrSymbol) span: anInteger; size: 0! ! !GLMCustomRow methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! column: aBlockOrSymbol ^self addColumn: aBlockOrSymbol! ! !GLMCustomRow methodsFor: 'scripting' stamp: 'tg 10/21/2009 22:08'! column: aBlockOrSymbol size: anInteger ^self addColumn: aBlockOrSymbol size: anInteger! ! !GLMCustomRow methodsFor: 'scripting' stamp: ' 4/5/09 22:18'! column: aBlockOrSymbol span: anInteger ^self addColumn: aBlockOrSymbol span: anInteger! ! !GLMCustomRow methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isRow ^true! ! !GLMDashboardExtentStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:27'! initializeContainer: aPanelMorph ^ self subclassResponsibility ! ! !GLMDashboardExtentStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:27'! initializeFirstColumn: aPanelMorph ^ self subclassResponsibility ! ! !GLMDashboardExtentStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:10'! initializePane: aMorphPane ^ self subclassResponsibility ! ! !GLMDashboardExtentStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:27'! initializeSecondColumn: aPanelMorph ^ self subclassResponsibility ! ! !GLMFillWidthAndHeightStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:31'! initializeContainer: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #shrinkWrap.! ! !GLMFillWidthAndHeightStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:31'! initializeFirstColumn: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #spaceFill.! ! !GLMFillWidthAndHeightStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:14'! initializePane: aMorphPane aMorphPane hResizing: #spaceFill; vResizing: #spaceFill.! ! !GLMFillWidthAndHeightStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:30'! initializeSecondColumn: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #spaceFill.! ! !GLMFillWidthStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 15:21'! initializeContainer: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #shrinkWrap.! ! !GLMFillWidthStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:29'! initializeFirstColumn: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #shrinkWrap.! ! !GLMFillWidthStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:12'! initializePane: aMorphPane aMorphPane hResizing: #spaceFill; vResizing: #rigid.! ! !GLMFillWidthStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:29'! initializeSecondColumn: aPanelMorph aPanelMorph hResizing: #spaceFill; vResizing: #shrinkWrap.! ! !GLMRigidStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:28'! initializeContainer: aPanelMorph aPanelMorph hResizing: #shrinkWrap; vResizing: #shrinkWrap.! ! !GLMRigidStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:28'! initializeFirstColumn: aPanelMorph aPanelMorph hResizing: #shrinkWrap; vResizing: #shrinkWrap.! ! !GLMRigidStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:13'! initializePane: aMorphPane aMorphPane hResizing: #rigid; vResizing: #rigid.! ! !GLMRigidStrategy methodsFor: '*glamour-morphic-renderer' stamp: 'cyrilledelaunay 5/20/2011 11:28'! initializeSecondColumn: aPanelMorph aPanelMorph hResizing: #shrinkWrap; vResizing: #shrinkWrap.! ! !GLMDoItContext commentStamp: 'TudorGirba 8/24/2011 23:50' prior: 34283020! This offers support for a do it context. Example: context := GLMContext withAll: {#a -> 1 . #b -> 2}. Compiler new evaluate: 'a + b' in: context to: context! !GLMDoItContext class methodsFor: 'instance creation' stamp: 'TudorGirba 8/25/2011 00:03'! with: aBinding withAll: aCollectionOfBindings | col | col := OrderedCollection with: aBinding. col addAll: aCollectionOfBindings. ^ self withAll: col! ! !GLMDoItContext class methodsFor: 'instance creation' stamp: 'TudorGirba 8/24/2011 23:48'! withAll: aCollectionOfBindings ^ self new variableBindings: (aCollectionOfBindings inject: Dictionary new into: [:dict :each | dict at: each key put: each value. dict])! ! !GLMDoItContext methodsFor: 'bindings' stamp: 'TudorGirba 8/24/2011 23:36'! bindingOf: aKey ^ self variableBindings at: #aKey ifAbsent: [nil]! ! !GLMDoItContext methodsFor: 'bindings' stamp: 'TudorGirba 3/15/2013 21:27'! method ^ GLMDoItContext >> #method! ! !GLMDoItContext methodsFor: 'bindings' stamp: 'TudorGirba 8/24/2011 23:44'! namedTempAt: index ^ self variableBindings at: (self tempNames at: index)! ! !GLMDoItContext methodsFor: 'bindings' stamp: 'TudorGirba 8/24/2011 23:43'! tempNames ^ self variableBindings keys asSortedCollection! ! !GLMDoItContext methodsFor: 'accessing' stamp: 'TudorGirba 8/24/2011 23:36'! variableBindings ^ variableBindings! ! !GLMDoItContext methodsFor: 'accessing' stamp: 'TudorGirba 8/24/2011 23:36'! variableBindings: anObject variableBindings := anObject! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 15:55'! announcer ^ announcer ifNil: [announcer := GLMAnnouncer new]! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 16:33'! glamourPresentation ^glamourPresentation! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 16:33'! glamourPresentation: anObject glamourPresentation := anObject! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'AndreiChis 8/21/2013 16:10'! list ^list ifNil: [ list:= (self glamourPresentation displayValue collect:[ :each| (self glamourPresentation formatedDisplayValueOf: each) asMorph ])]! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/18/2010 15:53'! list: anObject list := anObject! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'AndreiChis 8/21/2013 15:42'! resetData list := nil. selectionIndex := nil! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/27/2010 17:48'! selectedItem "Answer the currently selected item or nil if none." ^self selectionIndex = 0 ifTrue: [nil] ifFalse: [self glamourPresentation displayValue at: self selectionIndex]! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'VeronicaUquillas 5/26/2010 14:45'! selectionIndex ^ selectionIndex ifNil:[ selectionIndex:= self glamourPresentation selectedIndex ]! ! !GLMDropListModel methodsFor: 'accessing' stamp: 'AndreiChis 8/20/2013 22:43'! selectionIndex: anObject selectionIndex := anObject. self announcer announce: ( GLMDropDownListMorphSelectionChanged new selectionValue: self selectedItem; selectionIndex: selectionIndex; yourself)! ! !GLMBasicExamples commentStamp: '' prior: 34283236! self open! !GLMBasicExamples class methodsFor: 'accessing'! title ^ 'Basic Examples'! ! !GLMBasicExamples methodsFor: 'browsers'! accumulator "self new accumulator openOn: 42" | browser acc | browser := GLMTabulator new. acc := GLMAccumulator new. acc show: [ :a | a title: [ :x | x asString ]. a list display: [ :x | 1 to: x ] ]. browser column: [ :c | c row: #one span: 4; row: #two ]; column: #three. (browser transmit) to: #one; andShow: [ :a | a list display: [ :x | x to: 10 * x ] ]. (browser transmit) from: #one; to: #two; andShow: [ :a | a text display: [ :x | 'You have selected ' , x printString , '. Double cick to open to the right' ] ]. "When double-clicking on a number in the list, opens a new tab on the right side" (browser transmit) from: #one port: #strongSelection; to: #three; andShowIfNone: [ :a | a custom: acc ]. "When a number is selected in the list and a corresponding tab already exists on the right side, select the tab" (browser transmit) from: #one; to: #three port: #entityToSelect. "When a tab is selected on the right side, select the equivalent line in the first pane" (browser transmit) from: #three port: #activeEntity; to: #one port: #selection. ^ browser! ! !GLMBasicExamples methodsFor: 'private'! actionsFor: aPresentation |actions| aPresentation isMultiple ifTrue: [actions := (aPresentation selection) ifNil: [OrderedCollection new]] ifFalse: [actions := OrderedCollection with: aPresentation selection ]. ^ actions collect: [:i | (GLMGenericAction new) action: [:each | self inform: 'Menu - Item', i printString]; title: 'Menu - Item', i printString; yourself ]! ! !GLMBasicExamples methodsFor: 'others'! allowAllNil "self new allowAllNil openOn: 5" | browser | browser := GLMTabulator new. browser column: [: c | c row: #one; row: #two]; column: #details. browser transmit to: #one; andShow: [ :a | a tree display:[ :x| 1 to: x ]; allowDeselection ]. browser transmit to: #two; andShow: [ :a | a tree display: #(a b c); allowDeselection]. browser transmit to: #details; from: #one; from: #two; andShow: [ :a | a text display: [ :one :two | 'At least one is nil: ', one asString, '-', two asString]; allowNil. a text display: [ :one :two | 'All are nil: ', one asString, '-', two asString]; allowAllNil ]. "if you need initial display" browser transmit to: #details; andShow: [:a | a text display: [:x | 'All are nil' ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! allowNil "self new allowNil openOn: 42" | browser | browser := GLMTabulator new. browser column: [: c | c row: #one; row: #two]; column: #details. browser transmit to: #one; andShow: [ :a | a tree display: #(1 2 3); allowDeselection ]. browser transmit to: #two; andShow: [ :a | a tree display: #(a b c); allowDeselection]. browser transmit to: #details; from: #one; from: #two; andShow: [ :a | a text display: [ :one :two | one asString, two asString]; allowNil ]. ^ browser! ! !GLMBasicExamples methodsFor: 'actions examples' stamp: 'TudorGirba 11/28/2012 22:52'! browserWithToolbar "self new browserWithToolbar openOn: 'Browser with toolbar'" | wrapper | wrapper := GLMWrapper new. wrapper act: [:f | f inspect] icon: GLMUIThemeExtraIcons glamorousInspect on: $i entitled: 'Inspect with icon'. wrapper act: [:f | f inspect] on: $i entitled: 'Inspect without icon'. wrapper show: [:a | a text ]. ^ wrapper! ! !GLMBasicExamples methodsFor: 'others'! compoundTaggedTree "self new compoundTaggedTree openOn: #(window help home)" |browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a tree title: 'Combined Tags'; tags: [:each | { {ThemeIcons perform: (each, 'Icon') asSymbol . each asString }}]. a tree title: 'Image Tags'; tags: [:each | { ThemeIcons perform: (each, 'Icon') asSymbol}]. a tree title: 'Combined Tags - Filter by image'; tags: [:each | { each == #help ifTrue:[ {ThemeIcons smallDeleteIcon . 'no ok' } ] ifFalse:[ {ThemeIcons smallOkIcon . each asString } ]} ]; tagsFilter: [:each | { each == #help ifTrue:[ ThemeIcons smallDeleteIcon ] ifFalse:[ ThemeIcons smallOkIcon ] } ]. a tree title: 'Combined Tags - Filter by label'; tags: [:each | { {ThemeIcons perform: (each, 'Icon') asSymbol. each == #help ifTrue:[ 'no ok' ] ifFalse:[ 'ok' ]}} ]; tagsFilter: [:each | { each == #help ifTrue:[ 'no ok' ] ifFalse:[ 'ok' ] } ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:12'! dashboard "self new dashboard openOn: 42" |tmpBrowser| tmpBrowser := GLMDashboard new. tmpBrowser addPaneNamed: #first. tmpBrowser addPaneNamed: #second. tmpBrowser addPaneNamed: #third. tmpBrowser addPaneNamed: #fourth. tmpBrowser addPaneNamed: #fifth. tmpBrowser transmit to: #first; andShow: [:a | a list display: [:i | #(a b c d e f g)]; yourself ]. tmpBrowser transmit to: #second; andShow: [:a | a list display: [:i | #(a b c d e f g)] ]. tmpBrowser transmit to: #third; andShow: [:a | a list display: [:i | #(a b c d e f g)] ]. tmpBrowser transmit to: #fourth; andShow: [:a | a list display: [:i | #(a b c d e f g)] ]. tmpBrowser transmit to: #fifth; andShow: [:a | a list display: [:i | #(a b c d e f g h i j k l m n o p q r s t u v w x y z)] ]. ^ tmpBrowser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:12'! dashboardWithSpecificExtents "self new dashboardWithSpecificExtents openOn: 42" |tmpBrowser| tmpBrowser := GLMDashboard new. tmpBrowser rigidStrategy. tmpBrowser addPaneNamed: #first extent: 300@200. tmpBrowser addPaneNamed: #second extent: 200@200. tmpBrowser addPaneNamed: #third extent: 200@300. tmpBrowser addPaneNamed: #fourth extent: 300@300. tmpBrowser addPaneNamed: #fifth extent: 150@350. tmpBrowser transmit to: #first; andShow: [:a | a list display: [:i | #(a b c d e)]; yourself ]. tmpBrowser transmit to: #second; andShow: [:a | a list display: [:i | #(a b c d e)] ]. tmpBrowser transmit to: #third; andShow: [:a | a list display: [:i | #(a b c d e)] ]. tmpBrowser transmit to: #fourth; andShow: [:a | a list display: [:i | #(a b c d e)] ]. tmpBrowser transmit to: #fifth; andShow: [:a | a list display: [:i | #(a b c d e)] ]. ^ tmpBrowser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:12'! dashboardsInDashboard "self new dashboard openOn: 42" |tmpBrowser| tmpBrowser := GLMDashboard new. tmpBrowser addPaneNamed: #dashboard. tmpBrowser addPaneNamed: #second. tmpBrowser addPaneNamed: #third. tmpBrowser transmit to: #dashboard; andShow: [:a | a custom: (self dashboard) ]. tmpBrowser transmit to: #second; andShow: [:a | a custom: (self dashboard) ]. tmpBrowser transmit to: #third; andShow: [:a | a custom: (self dashboard) ]. ^ tmpBrowser! ! !GLMBasicExamples methodsFor: 'others' stamp: 'TudorGirba 4/25/2012 07:40'! diff "self new diff openOn: #(#(abc def ghi) #(abc xyz))" | browser | browser := GLMTabulator new. browser row: [:r | r column: #one; column: #two]; row: #diff. browser transmit to: #one; andShow: [ :a | a list display: #first ]. browser transmit to: #two; andShow: [ :a | a list display: #second ]. browser transmit to: #diff; from: #one; from: #two; andShow: [ :a | a diff display: [ :one :two | {one asString . two asString}] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'composite'! differentComposites "self new differentComposites openOn: (1 to: 100)" | browser | browser := GLMTabulator new. browser row: [:r | r column: #tabbed; column: #accordion; column: #stackedVertically] span: 4; row: #preview. browser transmit to: #tabbed; andShow: [:a | a title: 'Tabs'. a list title: 'List'. a text title: 'Text' ]. browser transmit to: #accordion; andShow: [:a | a accordionArrangement. a title: 'Accordion'. a list title: 'List'. a text title: 'Text' ]. browser transmit to: #stackedVertically; andShow: [:a | a title: 'Stack'. a stackedVerticallyArrangement. a list title: 'List'. a text title: 'Text' ]. browser transmit to: #preview; from: #tabbed; andShow: [:a | a text display: [:x | x printString, ' from tabbed' ]]. browser transmit to: #preview; from: #accordion; andShow: [:a | a text display: [:x | x printString, ' from accordion' ]]. browser transmit to: #preview; from: #stackedVertically; andShow: [:a | a text display: [:x | x printString, ' from stacked vertically' ]]. ^ browser ! ! !GLMBasicExamples methodsFor: 'others'! doubleClick "self new doubleClick openOn: 100" | browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a table display: [ :x | 1 to: x ]; column: 'value' evaluated: #asString; column: 'odd' evaluated: [:each | each odd asString ]]. browser transmit to: #two; from: #one port: #strongSelection; andShow: [:a | a list display: [ :x | 1 to: x ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! dropDownList "self new dropDownList openOn: 5" |browser | browser := GLMTabulator new. browser row: #one size: 30; row: #two. browser transmit to: #one; andShow: [:a | a dropDownList display: [:x | 1 to: x ]; format: [:number | Text string: number printString attribute: TextColor red]]. browser transmit from: #one; to: #two; andShow: [:a | a list display: [:x | 1 to: x * 2]]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! dropDownListWithInitialValue "self new dropDownListWithInitialValue openOn: 5" |browser | browser := GLMTabulator new. browser row: #one size: 30; row: #two. browser transmit to: #one; andShow: [:a | a dropDownList display: [:x | (1 to: x) + 10 ]; selectedIndex: 2 ]. browser transmit from: #one; to: #two; andShow: [:a | a list display: [:x | 1 to: x ]]. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! eyeseeBarDiagram "self new eyeseeBarDiagram openOn: #(5 2 10 6 12 8)." | browser | browser := GLMTabulator new. browser row: #one span: 3; row: #two. browser transmit to: #one; andShow: [:a | a eyesee title: 'Sample bar chart'; diagram: [:renderer :x | renderer verticalBarDiagram y: #yourself; models: x; width: 200; height: 150; baseAxisLine. renderer interaction popupText: #yourself ]]. browser transmit from: #one; to: #two; andShow: [:a | a text title: 'Preview']. ^ browser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 10/30/2012 19:33'! finderWithDifferentFirstPresentation "self new finderWithDifferentFirstPresentation openOn: (1 to: 42)" | finder | finder := GLMFinder new. finder with: [:f | f showFirst: [:a | a list]; show: [:a | a list display: [:x | 1 to: x] ]]. ^ finder! ! !GLMBasicExamples methodsFor: 'others'! fixSizePanes "self new fixSizePanes openOn: 1" | browser | browser := GLMTabulator new. browser row: #variable; row: #fix size: 20. browser transmit to: #fix; andShow: [ :a | a label display: 'Fix size']. browser transmit to: #variable; andShow: [ :a | a text display: 'Variable size']. ^ browser ! ! !GLMBasicExamples methodsFor: 'composite'! formatAsWords "self new formatAsWords openOn: (1 to: 100)" | browser | browser := GLMTabulator new. browser row: #list. browser transmit to: #list; andShow: [ :a | a tree format: [ :x | x asWords]; display: [:x | x]]. ^ browser ! ! !GLMBasicExamples methodsFor: 'others'! interdependentPanes "self new interdependentPanes openOn: 5" |browser | self flag: 'this example does not work'. browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a list display: [:x | 1 to: x * 3]]. browser transmit to: #two; from: #one; andShow: [ :a | a list display: [:x | 1 to: x * 3]]. browser transmit to: #one; from: #two; andShow: [ :a | a list display: [:x | 1 to: x * 3]]. ^ browser! ! !GLMBasicExamples methodsFor: 'drag and drop'! listDragAndDrop "self new listDragAndDrop openOn: (1 to: 5) asOrderedCollection" | browser | browser := GLMTabulator new. browser column: #source; column: #target. browser transmit to: #source; andShow: [:a | a list title: 'Source'; display: (1 to: 10); allowItemDrag: [:item :list | true ]; transformDraggedItem: [:item :list | item + 100 ] ]. browser transmit to: #target; andShow: [:a | a list title: 'Target'; display: [:collection | collection ]; allowDropOnItem: [:draggedObject :targetItem :list | draggedObject isNumber ]; dropOnItem: [:draggedObject :targetItem :list | list entity addLast: (targetItem + draggedObject). list update. true ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! listsInDashboardWithUpdatedSelection "self new listsInDashboardWithUpdatedSelection openOn: 10" | browser | browser := GLMDashboard new. browser addPaneNamed: #one; addPaneNamed: #two; addPaneNamed: #three. browser transmit to: #one; andShow: [ :a | a tree display: [:x | 1 to: x ]]. browser transmit to: #two; andShow: [ :a | a tree display: [:x | 1 to: x + 2 ]]. browser transmit to: #three; andShow: [ :a | a tree beMultiple; display: [:x | 1 to: x ]]. browser transmit to: #two port: #selection; from: #one; transformed: [:x | x + 2]. browser transmit to: #one port: #selection; from: #two; transformed: [:x | x - 2]. browser transmit to: #three port: #selection; from: #two; transformed: [:x | (1 to: (x - 2)) ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! listsWithUpdatedSelection "self new listsWithUpdatedSelection openOn: 10" | browser | browser := GLMTabulator new. browser column: #one; column: #two; column: #three. browser transmit to: #one; andShow: [ :a | a tree display: [:x | 1 to: x ]]. browser transmit to: #two; andShow: [ :a | a tree display: [:x | 1 to: x + 2 ]]. browser transmit to: #three; andShow: [ :a | a tree beMultiple; display: [:x | 1 to: x ]]. browser transmit to: #two port: #selection; from: #one; transformed: [:x | x + 2]. browser transmit to: #one port: #selection; from: #two; transformed: [:x | x - 2]. browser transmit to: #three port: #selection; from: #two; transformed: [:x | (1 to: (x - 2)) ]. ^ browser! ! !GLMBasicExamples methodsFor: 'others' stamp: 'AndreiChis 5/29/2013 14:02'! magritte "self new magritte openOn: GLMMagrittePersonExample sampleData" "GLMMagrittePersonExample sampleReset" "note, sampleData is aGLMAnnouncingCollection" | browser | browser := GLMTabulator new initialExtent: 600@300. browser column: #list; column: #detail. browser transmit to: #list ; andShow: [ :a | a list format: [ :person | person name ] ; updateOn: GLMItemAdded from: [ GLMMagrittePersonExample sampleData ] ; updateOn: GLMItemRemoved from: [ GLMMagrittePersonExample sampleData ] ; act: [ :listPresentation :glmAC | | newItem | newItem := GLMMagrittePersonExample new name: 'New...' . glmAC add: newItem beforeOrLast: listPresentation selection. listPresentation selection: newItem. ] icon: GLMUIThemeExtraIcons glamorousAdd entitled: 'Add' ; act: [ :listPresentation :glmAC | glmAC remove: listPresentation selection ifAbsent: [] ] icon: GLMUIThemeExtraIcons glamorousRemove entitled: 'Remove' . ]. browser transmit from: #list ; to: #detail ; andShow: [ :a | a magritte title: 'Details'; description: [:person | person magritteDescription] ; onAnswer: [ :person :presentation | browser update ] . ]. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! morphIcons "self new morphIcons openOn: (GLMUIThemeExtraIcons class selectors select: [:each | (each beginsWith: 'glamorous') and: [(GLMUIThemeExtraIcons perform: each) isForm ]])" | browser | browser := GLMTabulator new. browser column: #list; column: #preview. browser title: 'Glamorous Icons'. browser transmit to: #list; andShow: [ :a | a list title: 'GLMUIThemeExtraIcons' ]. browser transmit to: #preview; from: #list; andShow: [ :a | a morph title: [:symbol | symbol]; display: [:symbol | (GLMUIThemeExtraIcons perform: symbol) asMorph ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! multiInitialSelection " | browser | browser := self new multiInitialSelection. browser openOn: 5. (browser panes first port: #selection) value: #(2 5 3). " |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a tree beMultiple; display: [:x | 1 to: x * 3]]. browser transmit to: #two; from: #one; andShow: [ :a | a list ]. ^ browser! ! !GLMBasicExamples methodsFor: 'actions examples' stamp: 'TudorGirba 6/2/2012 00:32'! multipleActions "self new multipleActions openOn: 'This example shows how multiple actions are rendered.'" |browser | browser := GLMTabulator new. browser act: [:b | b inspect ] on: $/ entitled: 'Global action with shortcut'. browser column: #one. browser transmit to: #one; andShow: [ :a | a text title: 'Example'; selectionAct: [:text | text inspect ] on: $i entitled: 'Selection action'; act: [:text | text inspect ] entitled: 'Action without icon'; act: [:text | text inspect ] icon: GLMUIThemeExtraIcons glamorousInspect entitled: 'Action with icon' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'searching and filtering'! multipleFinderWithFilter "self new multipleFinderWithFilter openOn: ($a to: $z)" | finder | finder := GLMFinder new. finder show: [:a | a list title: 'List'; beMultiple; dynamicActions: [:list | self actionsFor: list]; filterOn: [:text :each | Compiler evaluate: '| each | each := self. ', text for: each logged: false ]; helpMessage: 'Enter a filtering request (e.g., "each > $f")'. a tree title: 'Tree'; dynamicActions: [:list | self actionsFor: list]; filterOn: [:text :each | Compiler evaluate: '| each | each := self. ', text for: each logged: false ]; helpMessage: 'Enter a filtering request (e.g., "each > $f")' ]. ^ finder ! ! !GLMBasicExamples methodsFor: 'searching and filtering'! multipleFinderWithFilterAndSearch "self new multipleFinderWithFilterAndSearch openOn: (1 to: 100)" | finder | finder := GLMFinder new. finder show: [:a | a list beMultiple; title: 'Simple'; dynamicActions: [:list | self actionsFor: list]. a list title: 'With filter'; beMultiple; dynamicActions: [:list | self actionsFor: list]; filterOn: [:text :each | (Compiler evaluate: '[:each | ', text, ']') value: each]; helpMessage: 'Enter a filtering request (e.g., "each > 10")'. a list title: 'With search'; beMultiple; dynamicActions: [:list | self actionsFor: list]; searchOn: [:text :each | (Compiler evaluate: '[:each | ', text, ']') value: each]; helpMessage: 'Enter a search request (e.g., "each > 10")' ]. ^ finder ! ! !GLMBasicExamples methodsFor: 'text'! populatePortAction "self new populatePortAction openOn: 'Select a piece of text and open on the next pane either with the overall button, or via the context menu'" | browser | browser := GLMFinder new. browser show: [:a | a text selectionPopulate: #selection on: $o entitled: 'Open selection on next pane' with: [:text | text selectedText ]; populate: #selection icon: GLMUIThemeExtraIcons glamorousRight on: $l entitled: 'Open complete text on next pane' with: [:text | text text ]]. ^ browser ! ! !GLMBasicExamples methodsFor: 'text' stamp: 'TudorGirba 1/20/2013 08:26'! populatePortActionsWithDifferentTargets "self new populatePortActionsWithDifferentTargets openOn: ($a to: $z)" | composer | composer := GLMCompositePresentation new. composer tabulator with: [:t | t column: #index; column: [:c | c row: #recepient1; row: #recepient2]. t transmit to: #index; andShow: [:a | a list selectionAct: [:list | (list pane port: #custom1) value: list selection ] on: $1 entitled: 'To recepient 1'; selectionPopulate: #custom2 on: $2 entitled: 'To recepient 2' with: [:list | list selection ] ]. t transmit from: #index port: #custom1; to: #recepient1; andShow: [:a | a text title: 'Recepient 1']. t transmit from: #index port: #custom2; to: #recepient2; andShow: [:a | a text title: 'Recepient 2']. ]. ^ composer! ! !GLMBasicExamples methodsFor: 'others' stamp: 'TudorGirba 6/11/2012 17:44'! roassalPainting "self new roassalPainting openOn: 42" | browser | browser := GLMTabulator withStatusbar. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a list title: 'Select and trigger from menu'; display: [:x | 1 to: x ]; selectionAct: [:list | | value | value := list selection * 10. "simulate some custom setup" (list pane port: #customSelection) value: value ] entitled: 'Multiply by 10 and then send outside' ]. browser transmit to: #two; from: #one port: #customSelection; andShow: [ :a | a roassal title: 'Numbers in Roassal'; painting: [:view :number | view shape label. view nodes: (1 to: number). view edgesFrom: [:each | each // 5 ]. view treeLayout ]]. ^ browser! ! !GLMBasicExamples methodsFor: 'roassal' stamp: 'TudorGirba 8/20/2013 21:45'! roassalWithCustomHighlight "self new roassalWithCustomHighlight openOn: (1 to: 42)" | browser | browser := GLMTabulator new . browser with: [:tabulator | tabulator column: #index; column: #visualization. tabulator transmit to: #index; andShow: [:a | a list ]. tabulator transmit to: #visualization; andShowIfNone:[ :a | a roassal painting: [:view :collection :roassal | view shape label. view interaction on: ROMouseLeftClick do: [:ann | (roassal pane port: #selection) value: ann element model ]. view nodes: collection. view gridLayout. roassal on: GLMContextChanged do: [:ann | ann property = #selection ifTrue: [ ann oldValue ifNotNil: [ ROBlink unhighlight: (ann presentation view raw elementFromModel: ann oldValue). ROBlink highlight: (ann presentation view raw elementFromModel: ann value) ]]]]]. tabulator transmit from: #index; to: #visualization port: #selection. tabulator transmit from: #visualization port: #selection; to: #index port: #selection. ]. ^ browser! ! !GLMBasicExamples methodsFor: 'roassal' stamp: 'TudorGirba 6/13/2012 14:56'! roassalWithMenu "self new roassalWithMenu openOn: 42" | browser | browser := GLMTabulator withStatusbar. browser column: #one. browser transmit to: #one; andShow: [ :a | a roassal title: 'Numbers in Roassal'; painting: [:view :number | view shape label. view interaction on: ROMouseClick do: [ :event | ROFocusView new on: event element view: view raw ]. view nodes: (1 to: number). view edgesFrom: [:each | each // 5 ]. view treeLayout. view addMenu: 'Zoom in' callBack: [ :stack | ROZoomInMove new on: stack firstView ]. view addMenu: 'Zoom out' callBack: [ :stack | ROZoomOutMove new on: stack firstView ]. ]]. ^ browser! ! !GLMBasicExamples methodsFor: 'actionlist'! simpleActionList "self new simpleActionList openOn: #(1 2 3)" | browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a actionList act: [:entity | entity inspect ] entitled: 'Inspect'; act: [:entity | entity explore ] entitled: 'Explore']. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! simpleExpander "self new simpleExpander openOn: #(a b c)" | browser | browser := GLMExpander new. browser show: [ :a | a title: [:x | x ]. a text title: 'text1'. a text title: 'text2'.]. ^ browser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:12'! simpleFinder "self new simpleFinder openOn: 42" | finder | finder := GLMFinder new. finder show: [:a | a list display: [ :x | 1 to: x ]]. ^ finder! ! !GLMBasicExamples methodsFor: 'actions examples'! simpleFinderWithMenu "self new simpleFinderWithMenu openOn: $z" | finder | finder := GLMFinder new variableSizePanes. finder show: [:a | a list title: 'List'; display: [:each | $a to: each]; dynamicActionsOnSelection: [:list | self actionsFor: list ]]. ^ finder! ! !GLMBasicExamples methodsFor: 'table' stamp: 'TudorGirba 9/20/2013 08:26'! simpleTable "| f | f := self new simpleTable. f openOn: 1000. (f panes first port: #selection) value: 1" | wrapper | wrapper := GLMWrapper new. wrapper show: [:a | a table display: [ :x | 1 to: x ]; column: [:x | 'Numbers from 1 to ', x asString] evaluated: #asString; column: 'Even' evaluated: [ :each | each even asString ]; column: 'Odd' evaluated: [ :each | each odd asString ] ]. ^ wrapper! ! !GLMBasicExamples methodsFor: 'explicit selection'! singleInitialSelection " | browser | browser := self new singleInitialSelection. browser openOn: 5. (browser panes first port: #selection) value: 3. " |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a tree display: [:x | 1 to: x]; format: [:number | Text string: number printString attribute: TextColor red]]. browser transmit to: #two; from: #one; andShow: [ :a | a list display: [:x | 1 to: x * 2]]. ^ browser! ! !GLMBasicExamples methodsFor: 'text'! smalltalkCode "self new smalltalkCode openOn: ''" | browser | browser := GLMTabulator new. browser row: #code span: 2; row: #preview. browser transmit to: #code; andShow: [ :a | a smalltalkCode title: 'Smalltalk Code'; populate: #acceptedCode icon: GLMUIThemeExtraIcons glamorousAccept on: $s entitled: 'Accept' with: [:text | text text ] ]. browser transmit from: #code port: #acceptedCode; to: #preview; andShow: [ :a | a text title: 'Evaluated result'; display: [:code | [Compiler evaluate: code ] on: Error do: ['Error']]; act: [:text | text displayValue explore] icon: GLMUIThemeExtraIcons glamorousInspect entitled: 'Explore' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'actions examples'! spawnBrowserActions "self new spawnBrowserActions openOn: #(1 2 3 4)" |browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a list title: 'Example'. ]. browser spawn: [:presentation | |tmpBrowser| tmpBrowser := GLMTabulator new row: #one; initialExtent: 200@200 ;yourself. tmpBrowser transmit to: #one ; andShow: [:b | b text display: [:input | input asString] ]. tmpBrowser startOn: presentation entity ] entitled: 'Open in new browser'. ^ browser! ! !GLMBasicExamples methodsFor: 'actions examples'! spawnBrowserSelectionActions "self new spawnBrowserSelectionActions openOn: #(1 2 3 4)" |browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a list title: 'Example'; selectionSpawn: [:listPresentation | |tmpBrowser| tmpBrowser := GLMTabulator new row: #one; initialExtent: 100@100 ;yourself. tmpBrowser transmit to: #one ; andShow: [:b | b text display: [:input | input asString] ]. tmpBrowser startOn: listPresentation selection ] entitled: 'Open in new browser' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! stacker "self new stacker openOn: 5" | browser | browser := GLMStacker new. browser aPane: #x; aPane: #y. browser transmit to: #x; andShow: [ :a | a title: 'x'. a list display: [:x | 1 to: x ]]. browser transmit to: #y; andShow: [:a | a title: '10 * x'. a list display: [:x | 1 to: (10*x )] ]. ^ browser ! ! !GLMBasicExamples methodsFor: 'actions examples'! staticAndDynamicMenu "self new staticAndDynamicMenu openOn: $z" | finder | finder := GLMFinder new. finder show: [ :a | a list title: 'List'; display: [:each | $a to: each]; dynamicActionsOnSelection: [:list | self actionsFor: list ]; selectionAct: [self inform: 'static action'] entitled: 'Static action'; selectionAct: [self inform: 'static sub action'] entitled: 'Static sub action' categorized: 'Sub menu'. a text title: 'Text'; display: [:each | 'Character ', each asString]; dynamicActionsOnSelection: [:text | OrderedCollection with: (GLMGenericAction new title: 'Print selection'; action: [text selectedText inspect ]; yourself) ]; selectionAct: [self inform: 'Text static action'] entitled: 'Static action']. ^ finder! ! !GLMBasicExamples methodsFor: 'table' stamp: 'TudorGirba 6/7/2013 13:03'! tableWithCustomWidth "self new tableWithCustomWidth openOn: 100" | wrapper textBlock | wrapper := GLMWrapper new. textBlock := [:x | (1 to: x) inject: '' into: [ :s :each | s, each asString]]. wrapper show: [:a | a table display: [ :x | 1 to: x ]; column: 'Large column' evaluated: textBlock width: 400; column: 'Small column' evaluated: textBlock width: 50; column: 'Default column' evaluated: textBlock; column: 'Last column' evaluated: textBlock ]. ^ wrapper! ! !GLMBasicExamples methodsFor: 'actions examples'! tableWithIcons "self new tableWithIcons openOn: ($A to: $z)" |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a act: [:presentation | presentation inspect] entitled: 'Inspect'. a table title: 'Table with actions'; act: [:presentation | presentation inspect] entitled: 'Inspect'; column: 'Character' evaluated: [ :each | each asString ]; column: 'ASCII' evaluated: [ :each | each asInteger printString ]; selectionAct: [:tree | tree selection inspect ] on: $i entitled: 'Inspect'; icon: [:each | each asInteger odd ifTrue: [ GLMUIThemeExtraIcons glamorousRedCircle ] ifFalse: [ GLMUIThemeExtraIcons glamorousGreenCircle ] ]]. browser transmit to: #two; from: #one; andShow: [:a | a text ]. ^ browser! ! !GLMBasicExamples methodsFor: 'tabs examples'! tabsWithDifferentActions "self new tabsWithDifferentActions openOn: 42" | browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [:a | a text display: 'Tab with multiple actions. Switch between tabs to check the toolbars on the right'; title: 'Tab with multiple actions'; act: [:x | x inspect] icon: GLMUIThemeExtraIcons glamorousInspect entitled: 'Inspect with icon'; act: [:x | x printString inspect] icon: GLMUIThemeExtraIcons glamorousBrowse entitled: 'Print it and inspect with icon'; act: [:x | x inspect] entitled: 'Inspect without icon'; act: [:x | x printString inspect] entitled: 'Print it and inspect without icon'. a text display: 'Tab without actions. Switch between tabs to check the toolbars on the right'; title: 'Tab without actions' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'tabs examples'! tabsWithDifferentLabels "self new tabsWithDifferentLabels openOn: 1" | finder | finder := GLMFinder new. (1 to: 3) do: [:i | finder show: [:a | a text title: i printString; display: [:x | i printString]. a text titleIcon: GLMUIThemeExtraIcons glamorousBrowse; display: [:x | i printString] ] ]. ^ finder! ! !GLMBasicExamples methodsFor: 'others'! taggedTree "self new taggedTree openOn: #(1 2 3 4 5)" |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a tree tags: [:each | {each even ifTrue: ['even'] ifFalse: ['odd']. each even ifTrue: ['x'] ifFalse: ['y']} ]]. browser transmit to: #two; from: #one; andShow: [ :a | a text display: [:x | 'You have selected ', x printString ]]. ^ browser! ! !GLMBasicExamples methodsFor: 'text'! textPortsExamples "self new textPortsExamples openOn: 'Type and select to see the results previewed.'" | browser | browser := GLMTabulator new. browser row: #main; row: [ :r | r column: #selectionInterval; column: #selectedText; column: #full ]. (browser transmit) to: #main; andShow: [ :a | a text ]. (browser transmit) to: #selectionInterval; from: #main port: #selectionInterval; andShow: [ :a | a text title: '#selectionInterval port' ]. (browser transmit) to: #selectedText; from: #main port: #selectedText; andShow: [ :a | a text title: '#selectedText port' ]. (browser transmit) to: #full; from: #main port: #text; andShow: [ :a | a text title: '#text port']. ^ browser! ! !GLMBasicExamples methodsFor: 'text'! textSelection " |browser | browser := self new textSelection. browser openOn: (1 to: 100). ((browser paneNamed: #start) port: #selection) value: 2. ((browser paneNamed: #end) port: #selection) value: 5. " | browser | browser := GLMTabulator new. browser row: [ :r | r column: #start; column: #end ]; row: #text. browser transmit to: #start; andShow: [ :a | a list title: 'Start' ]. browser transmit to: #end; andShow: [ :a | a list title: 'End' ]. browser transmit to: #text; andShow: [ :a | a text title: 'Text with selection'; display: 'some piece of text to test the selection interval on.']. browser transmit to: #text->#selectionInterval; from: #start; from: #end; when: [:s :e | s notNil & e notNil] ; transformed: [ :s :e | s to: e ]. " browser transmit to: #start->#selection; from: #text->#selectionInterval; transformed: [:interval | interval first]. browser transmit to: #end->#selection; from: #text->#selectionInterval; transformed: [:interval | interval last]. " ^ browser! ! !GLMBasicExamples methodsFor: 'others'! threeInterdependentPanes "self new threeInterdependentPanes openOn: 5" | browser | browser := GLMTabulator new. browser column: #one; column: #two; column: #three. (browser transmit) to: #one; andShow: [ :a | a tree display: [ :x | 1 to: x ] ]. (browser transmit) to: #two; from: #one; andShow: [ :a | a tree display: [ :x | 1 to: x * 2 ] ]. (browser transmit) to: #three; from: #two; andShow: [ :a | (a tree) display: [ :x | 1 to: x * 3 ]; populate: #focus on: $f entitled: 'Focus' with: [ :list | list selection ] ]. (browser transmit) toOutsidePort: #focus; from: #three port: #focus. (browser transmit) to: #one port: #selection; fromOutsidePort: #focus. (browser transmit) to: #two port: #selection; fromOutsidePort: #focus. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! treeWithAmountFiltering "self new treeWithAmountFiltering openOn: (1 to: 10000)" | browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a tree tags: [ :each | {each even printString} ]; showOnly: 50 ]. ^ browser ! ! !GLMBasicExamples methodsFor: 'explicit selection'! treeWithChildrenByLevel " self new treeWithChildrenByLevel openOn: #(1 2 3 4 5) " | browser | browser := GLMTabulator new. browser column: #one; column: [ :c | c row: #two; row: #three ]. (browser transmit) to: #one; andShow: [ :a | (a tree) title: 'Tree'; children: [ :item :x :level | level > 1 ifTrue: [ #() ] ifFalse: [ 1 to: item ] ] "Children must return a collection" ]. (browser transmit) to: #two; from: #one; andShow: [ :a | a text title: 'Selection preview' ]. (browser transmit) to: #three; from: #one port: #selectionPath; andShow: [ :a | a text title: 'Selection path preview' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'others'! treeWithExpansion "self new treeWithExpansion openOn: #(($a $b $c $d) ($e $f) ($g $h $i $j ($l $m $n)))" |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [:a | a tree title: 'No expansion'; children: [:x :i | x asString size > 1 ifTrue: [x] ifFalse: [OrderedCollection new] ]. a tree title: 'Roots expanded'; rootsExpanded; children: [:x :i | x asString size > 1 ifTrue: [x] ifFalse: [OrderedCollection new] ]. a tree title: 'All expanded'; allExpanded; children: [:x :i | x asString size > 1 ifTrue: [x] ifFalse: [OrderedCollection new] ] ]. browser transmit to: #two; from: #one; andShow: [ :a | a text ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection' stamp: 'TudorGirba 5/29/2012 23:12'! treeWithInitialSelection " | browser | browser := self new treeWithInitialSelection. browser openOn: { #first->{$a->{}. $c->{}. $d->{}}. #second->{$e->{}. $f->{}}. #third->{$h->{}} }. (browser panes first port: #selection) value: (browser panes first port: #entity) value first value first. " | browser | browser := GLMTabulator new. browser column: #one; column: [ :c | c row: #two; row: #three ]. (browser transmit) to: #one; andShow: [ :a | (a tree) title: 'first tree'; children: [ :x | x value ]. (a tree) title: 'second tree'; children: [ :x | x value ] ]. (browser transmit) to: #two; from: #one; andShow: [ :a | a text title: 'Selection preview' ]. (browser transmit) to: #three; from: #one port: #selectionPath; andShow: [ :a | a text title: 'Selection path preview' ]. ^ browser! ! !GLMBasicExamples methodsFor: 'actions examples'! treeWithMenu "self new treeWithMenu openOn: #(($a $b $c $d) ($e $f) ($g $h $i $j $l))" |browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [ :a | a tree children: [:x :i | x asString size > 1 ifTrue: [x] ifFalse: [OrderedCollection new] ]; selectionAct: [:tree | tree inspect ] on: $i entitled: 'Inspect'; icon: [:x | GLMUIThemeExtraIcons glamorousGrayCircle ]]. browser transmit to: #two; from: #one; andShow: [:a | a text ]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! treeWithTags " self new treeWithTags openOn: #(1 2 3 4 5 6 7 8 9 10) " |browser model| model := Dictionary new. model at: #some put: #(1 2 3 4). model at: #even put: #(2 6 8). model at: #odd put: #(3 7 9). browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a tree display: [model keys]; children: [:key | key isNumber ifFalse: [model at: key] ]; tags: [:item | item isNumber ifTrue: [item even ifTrue: [#('even')] ifFalse: [#('odd')]] ifFalse: [#()]]]. ^ browser! ! !GLMBasicExamples methodsFor: 'explicit selection'! treeWithTagsMoreLevels " self new treeWithTagsMoreLevels openOn: #(1 2 3 4 5 6 7 8 9 10) " |browser model| model := Dictionary new. model at: #some put: #(1 2 3 4). model at: #even put: #(2 6 8). model at: #odd put: #(3 7 9). browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a tree display: [model keys]; children: [:child | child isSymbol ifTrue: [Array with: ((model at: child) select: [:c | c < 4]) with: ((model at: child) select: [:c | c >= 4])] ifFalse: [child isCollection ifTrue: [child] ifFalse: [#()]]]; tags: [:item | Array streamContents: [:stream | item isNumber ifTrue: [ stream nextPut: (item even ifTrue: ['even'] ifFalse: ['odd']). stream nextPut: (item < 4 ifTrue: ['<4'] ifFalse: ['>=4' ])]]]]. ^ browser! ! !GLMBasicExamples methodsFor: 'updating'! updateableBrowser " |collection| collection := GLMAnnouncingCollection new. collection add: 1. self new updateableBrowser openOn: collection." | browser | browser := GLMTabulator new. browser column: #preview. browser act: [:b | b entity add: (b entity size + 1). b update ] icon: GLMUIThemeExtraIcons glamorousAdd entitled: 'Add an item in the collection'. browser act: [:b | b entity removeLast. b update ] icon: GLMUIThemeExtraIcons glamorousRemove entitled: 'Remove last item from the collection'. browser updateOn: GLMItemAdded from: #yourself; updateOn: GLMItemRemoved from: #yourself. browser transmit to: #preview; andShow: [ :a | a list title: [:collection | 'List: ', collection size printString ]; when: [:collection | collection size > 1 ]. a text title: 'Text'; format: [:collection | 'Current collection: ', collection printString, ' Add more items to show the list'] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'updating' stamp: 'TudorGirba 10/4/2013 23:25'! updateableIndividualPresentations " |collection| collection := GLMAnnouncingCollection new. collection add: 1; add: 2; add: 3. self new updateableIndividualPresentations openOn: collection." | browser | browser := GLMTabulator new. browser column: #automatic; column: #menu. browser act: [:b | b entity add: (b entity size + 1) ] icon: GLMUIThemeExtraIcons glamorousAdd entitled: 'Add an item in the collection'. browser act: [:b | b entity removeLast ] icon: GLMUIThemeExtraIcons glamorousRemove entitled: 'Remove last item from the collection'. browser act: [:b | b update ] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Update complete browser'. browser transmit to: #automatic; andShow: [ :a :x | a title: 'Updated automatically'. a stackedArrangement. a list title: [ 'List: ', x size printString ]; shouldValidate: true; updateOn: GLMItemAdded from: #yourself; updateOn: GLMItemRemoved from: #yourself. a text title: 'Text'; updateOn: GLMItemAdded from: #yourself; updateOn: GLMItemRemoved from: #yourself . a roassal title: 'Roassal'; updateOn: GLMItemAdded from: #yourself; updateOn: GLMItemRemoved from: #yourself; painting: [:view | view shape label. view nodes: x ] ]. browser transmit to: #menu; andShow: [ :a :x | a title: 'Updated via menu'. a stackedArrangement. a list title: 'List'; shouldValidate: true; act: [:p | p update] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Update'. a text title: 'Text'; act: [:p | p update] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Update'. a roassal title: 'Roassal'; act: [:p | p update] icon: GLMUIThemeExtraIcons glamorousRefresh entitled: 'Update'; painting: [:view | view shape label. view nodes: x ] ]. ^ browser! ! !GLMBasicExamples methodsFor: 'updating'! validatingPresentation " |collection| collection := GLMAnnouncingCollection new. collection add: 1; add: 2; add: 3. self new validatingPresentation openOn: collection." | browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [:a | a list title: 'List with port validation'; shouldValidate: true; updateOn: GLMItemRemoved from: #yourself; updateOn: GLMItemAdded from: #yourself; act: [:list :all | all removeLast ] icon: GLMUIThemeExtraIcons glamorousRemove entitled: 'Remove last'; act: [:list :all | all add: (all size + 1) ] icon: GLMUIThemeExtraIcons glamorousAdd entitled: 'Add last'. ]. browser transmit from: #one; to: #two; andShow: [:a | a text title: 'Preview' ]. ^ browser ! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:12'! validator "self new validator openOn: 42" | finder validator | finder := GLMFinder new. validator := GLMValidator new. validator validator: 'Ok' act: [:x | ]. validator show: [:a | a list display: [:x | 1 to: x ]]. finder show: [:a | a custom: validator]. ^ finder! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:13'! validatorDynamic "self new validatorDynamic openOn: 42" | finder validator | finder := GLMFinder new. validator := GLMValidator new. validator validator: 'Ok' act: [:x | ]. validator show: [:a | a dynamic display: [:x | GLMListPresentation new display: [:y | 1 to: y] ] ]. finder show: [:a | a custom: validator]. ^ finder! ! !GLMBasicExamples methodsFor: 'others' stamp: 'TudorGirba 5/14/2013 08:52'! watcher "self new watcher openOn: (Collection methods)" "You have to open the Watcher to see the effect." "GLMWatcherWindow uniqueInstance show." "" | browser | browser := GLMTabulator new. browser column: #one. browser transmit to: #one; andShow: [ :a | a list title: 'Collection methods'; format: #selector]. browser transmit from: #one; toWatcher; andShow: [ :a | a smalltalkCode display: #getSource ]. ^ browser! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:14'! wizard "" "self new wizard inspect openOn: 100" | wizard | self flag: 'this example does not work in the example browser'. wizard := GLMWizard new. (wizard genericStep: #step) show: [:a | a list display: [:list | 1 to: 100] ]; name: 'Wizard pane'; size: 2. ^ wizard! ! !GLMBasicExamples methodsFor: 'browsers' stamp: 'TudorGirba 5/19/2012 09:16'! wrapper "self new wrapper openOn: (1 to: 42)" | wrapper | wrapper := GLMWrapper new title: 'Wrapper'. wrapper show: [:a | a list title: 'List'. a text title: 'Text' ]. ^ wrapper! ! !GLMExamples class methodsFor: 'accessing'! allExamples ^ Pragma allNamed: #glmBrowser:input: in: self! ! !GLMExamples class methodsFor: 'opening' stamp: 'TudorGirba 5/25/2013 12:08'! open ^ GLMExamplesBrowser new title: self title; openOn: self! ! !GLMExamples class methodsFor: 'accessing'! title ^ 'Examples'! ! !GLMOtherExamples commentStamp: '' prior: 34283304! self open! !GLMOtherExamples methodsFor: 'other examples'! expander "self new expander openOn: Collection withAllSubclasses" | browser expander | browser := GLMTabulator new. browser title: 'Example'. expander := GLMExpander new. expander title: 'Methods'. expander display: [:class | class methods ]. expander show: [ :a | a title: [:x | x selector ]. a text display: #getSource]. browser column: #classes; column: #methods. browser transmit to: #classes; andShow: [:a | a list title: 'Classes' ]. browser transmit to: #methods; from: #classes; andShow: [:a | a custom: expander ]. ^ browser ! ! !GLMOtherExamples methodsFor: 'file examples' stamp: 'AndreHora 5/3/2013 14:31'! fileExplorer "self new fileExplorer openOn: FileDirectory default" | browser | browser := GLMTabulator new. browser column: #folders; column: [ :col | col row: #files span: 2; row: #preview ] span: 2. browser transmit to: #folders; andShow: [ :a | a tree title: 'Folders'; children: [ :fd | fd directoryNames collect: [ :each | FileSystem / fd pathName, fd pathNameDelimiter asString, each ] ]; format: [ :folder | folder localName ] ]. browser transmit to: #files; from: #folders; andShow: [ :a | a list format: [ :fd | fd localName ]; display: [ :fd | fd fileNames collect: [:each | FileSystem / fd pathName, fd pathNameDelimiter asString, each ] ] ]. browser transmit to: #preview; from: #files; andShow: [ :a | a text display: [ :file | file fullName ] ]. ^ browser! ! !GLMOtherExamples methodsFor: 'file examples' stamp: 'AndreHora 5/3/2013 14:25'! fileFinder "self new fileFinder openOn: FileDirectory default" | browser | browser := GLMFinder new. browser show: [ :a | a list display: [ :fd | fd entries collect: [:each | FileSystem / fd pathName, fd pathNameDelimiter asString, each name]]; format: [ :fd | fd localName ]; when: [ :fd | fd directoryEntry isDirectory ]]. browser show: [ :a | a text display: [ :fd | fd fullName ]; when: [ :fd | fd directoryEntry isDirectory not ] ]. ^ browser! ! !GLMLogger commentStamp: 'tg 5/24/2010 17:00' prior: 34283371! This is the abstract class for the Glamour loggers. These classes are typically used for debugging hte highly dynamic Glamour model.! !GLMLogger class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 17:03'! instance ^ instance ifNil: [ instance := self nullInstance ]! ! !GLMLogger class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 17:04'! instance: aLogger instance := aLogger ! ! !GLMLogger class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 16:47'! nullInstance ^ nullInstance ifNil: [ nullInstance := GLMNullLogger new ]! ! !GLMLogger class methodsFor: 'as yet unclassified' stamp: 'tg 5/24/2010 17:08'! reset instance := nil! ! !GLMLogger methodsFor: 'logging' stamp: 'tg 5/24/2010 16:45'! logAnnouncement: anAnnouncement from: aGLMObject ! ! !GLMMemoryLogger commentStamp: 'tg 5/24/2010 16:59' prior: 34283567! This class stores the announcements raised by the Glamour model in an ordered collection. The collection can later be used for debugging.! !GLMMemoryLogger methodsFor: 'accessing' stamp: 'tg 5/24/2010 17:30'! announcements ^ announcements! ! !GLMMemoryLogger methodsFor: 'accessing' stamp: 'tg 5/24/2010 17:30'! announcements: anObject announcements := anObject! ! !GLMMemoryLogger methodsFor: 'initialize-release' stamp: 'tg 5/24/2010 16:46'! initialize announcements := OrderedCollection new! ! !GLMMemoryLogger methodsFor: 'logging' stamp: 'tg 5/24/2010 17:31'! logAnnouncement: anAnnouncement from: aGLMObject announcements add: anAnnouncement! ! !GLMNullLogger commentStamp: 'tg 5/24/2010 16:58' prior: 34283767! This class simply implements the Null pattern.! !GLMMagrittePersonExample class methodsFor: 'as yet unclassified'! sampleData "self new magritteAddressBook openOn: self new magritteAddressBookModel " SampleData ifNil: [ SampleData := GLMAnnouncingCollection new. SampleData add: (GLMMagrittePersonExample new name: 'William Shakespeare' ; address: 'Stratford-upon-Avon' ). SampleData add: (GLMMagrittePersonExample new name: 'Victor Hugo' ; address: 'Besançon' ). SampleData add: (GLMMagrittePersonExample new name: 'Mark Twain' ; address: 'Florida' ). SampleData add: (GLMMagrittePersonExample new name: 'Banjo Paterson' ; address: 'Narrambla' ). ]. ^SampleData ! ! !GLMMagrittePersonExample class methodsFor: 'as yet unclassified'! sampleReset SampleData := nil. ! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! address ^ address! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! address: aString address := aString! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! descriptionAddress ^ MAStringDescription new accessor: #address; label: 'Address'; yourself! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! descriptionContainer ^ super descriptionContainer propertyAt: #containerBase put: nil; yourself! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! descriptionName ^ MAStringDescription new accessor: #name; label: 'Name'; yourself! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! exampleSupportIdentityInSample ^ self class sampleData includes: self. ! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! name ^ name! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! name: aString name := aString! ! !GLMMagrittePersonExample methodsFor: 'as yet unclassified'! printOn: aStream aStream nextPutAll: '('. self name printOn: aStream. aStream nextPutAll: ','. self address printOn: aStream. aStream nextPutAll: ')'. self exampleSupportIdentityInSample ifTrue: [ aStream nextPutAll: ' #original# '] ifFalse: [ aStream nextPutAll: ' #copy# ']. super printOn: aStream.! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'VeronicaUquillas 6/15/2010 10:33'! alignmentMorph: aCollectionOfMorphs "Answer a row-oriented AlignmentMorph holding the given collection" | morph | morph:= AlignmentMorph new listDirection: #leftToRight; borderWidth: 0; color: Color transparent; vResizing: #shrinkWrap; hResizing: #shrinkWrap; layoutInset: 1; wrapCentering: #center; cellPositioning: #center. aCollectionOfMorphs do: [ :each | morph addMorphBack: each]. ^morph! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'TudorGirba 1/21/2011 10:11'! containerMorph ^ PanelMorph new layoutPolicy: ProportionalLayout new; hResizing: #spaceFill; vResizing: #spaceFill; borderWidth: 0; yourself! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'TudorGirba 5/31/2012 22:37'! emptyMorph ^ self containerMorph fillStyle: (SolidFillStyle color: Color transparent ); yourself! ! !GLMMorphic class methodsFor: 'button styles' stamp: 'tg 9/23/2010 20:04'! grayRoundedButtonStyle: button morph: aMorph pressed: aBoolean button useRoundedCorners. (self isAlignmentMorph: aMorph) ifTrue: [ aBoolean ifTrue: [ aMorph lastSubmorph color: Color gray. button fillStyle: (button theme buttonSelectedFillStyleFor: button). button borderStyle: (button theme buttonSelectedBorderStyleFor: button) ] ifFalse:[ aMorph lastSubmorph color: Color white. button fillStyle: (button theme buttonNormalFillStyleFor: button). button borderStyle: (button theme buttonNormalBorderStyleFor: button) ] ] ifFalse: [ aBoolean ifTrue: [ aMorph color: Color gray. button color: Color veryLightGray ] ifFalse:[ aMorph color: Color white. button color: Color lightGray ] ] ! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'VeronicaUquillas 11/19/2009 20:08'! isAlignmentMorph: anObject ^anObject isMemberOf: AlignmentMorph! ! !GLMMorphic class methodsFor: 'button styles' stamp: 'VeronicaUquillas 6/15/2010 10:49'! isGrayRoundedButton: aSymbol ^aSymbol = #grayRoundedButton or:[ aSymbol = #default ]! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'VeronicaUquillas 11/19/2009 20:08'! isImageMorph: anObject ^anObject isMemberOf: ImageMorph! ! !GLMMorphic class methodsFor: 'button styles' stamp: 'tg 9/3/2010 14:07'! isWhiteRectangledButton: aSymbol ^aSymbol = #whiteRectangledButton! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'TudorGirba 1/20/2011 21:53'! morphElement: anObject anObject isString ifTrue:[ ^StringMorph contents: anObject font: (LogicalFont familyName: UITheme current buttonFont familyName pointSize: UITheme current buttonFont pointSize - 2) ]. anObject isCollection ifTrue: [ |row| row:= OrderedCollection new. anObject do: [ :e| row add: (self morphElement: e) ]. ^self alignmentMorph: row ]. anObject isForm ifTrue:[ ^ImageMorph new newForm: anObject ]. ^self containerMorph! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'tg 9/23/2010 19:59'! styleButton: button morph: m pressed: aBoolean style: aSymbol (self isGrayRoundedButton: aSymbol) ifTrue:[ self grayRoundedButtonStyle: button morph: m pressed: aBoolean ]. (self isWhiteRectangledButton: aSymbol) ifTrue:[ self whiteRectangledButtonStyle: button morph: m pressed: aBoolean ]! ! !GLMMorphic class methodsFor: 'as yet unclassified' stamp: 'tg 9/23/2010 21:17'! togglingButtonLabelled: anObject pressed: aBoolean style: aSymbol | button oldLabel m | button := SimpleButtonMorph new. (oldLabel := button findA: StringMorph) ifNotNil: [ oldLabel delete ]. m := self morphElement: anObject. button addMorph: m; borderColor: Color transparent. (self isAlignmentMorph: m) ifTrue:[ button extent: (m width + 6 ) @ (m height + 6 ). m position: 3 @ 3 ] ifFalse:[ (self isImageMorph: m) ifTrue: [ button extent: (m width + 6) @ (m height + 6) ] ifFalse:[ button extent: (m width + 6) @ (m height + 6) ]. m position: 3 @ 3. "button center - (m extent // 2)" ]. self styleButton: button morph: m pressed: aBoolean style: aSymbol. m lock. ^ button! ! !GLMMorphic class methodsFor: 'button styles' stamp: 'VeronicaUquillas 1/10/2011 17:13'! whiteRectangledButtonStyle: button morph: aMorph pressed: aBoolean button useSquareCorners. (self isAlignmentMorph: aMorph) ifTrue:[ aBoolean ifTrue: [ aMorph lastSubmorph color: Color white. button borderColor: Color gray. button color: Color gray ] ifFalse:[ aMorph lastSubmorph color: Color black. button borderColor: Color gray. button color: Color white ]. button extent: aMorph width @ (aMorph height - 2). aMorph position: 0 @ 0 ] ifFalse:[ aBoolean ifTrue: [ aMorph color: Color white. button borderColor: Color gray. button color: Color gray ] ifFalse:[ aMorph color: Color black. button borderColor: Color gray. button color: Color white ]. button extent: (aMorph width + 6) @ (aMorph height + 2). aMorph position: 3 @ 1 ]! ! !GLMMorphicIcons class methodsFor: 'as yet unclassified' stamp: 'tg 11/20/2010 15:45'! form16x16FromContents: aByteArray ^ Form extent: 16@16 depth: 32 fromArray: aByteArray offset: 0@0! ! !GLMMorphicIcons class methodsFor: 'as yet unclassified' stamp: 'tg 11/20/2010 15:45'! toolbarMenuForm ^self form16x16FromContents: self windowMenuFormContents ! ! !GLMMorphicIcons class methodsFor: 'as yet unclassified' stamp: 'tg 11/20/2010 15:46'! toolbarMenuInactiveForm ^self form16x16FromContents: self windowMenuInactiveFormContents ! ! !GLMMorphicIcons class methodsFor: 'as yet unclassified' stamp: 'tg 11/20/2010 15:44'! windowMenuFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 0 0 352321536 3556769792 4278190080 4278190080 3556769792 352321536 0 0 0 0 0 0 0 0 0 0 0 369098752 3556769792 3556769792 352321536 0 0 0 0 0 0 0 0 0 0 0 0 0 369098752 352321536 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMMorphicIcons class methodsFor: 'as yet unclassified' stamp: 'tg 11/20/2010 15:45'! windowMenuInactiveFormContents ^ #( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 4286611584 4286611584 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 0 0 360282489 3565191296 4286611584 4286611584 3565191296 360282489 0 0 0 0 0 0 0 0 0 0 0 377520256 3565191296 3565191296 360282489 0 0 0 0 0 0 0 0 0 0 0 0 0 377520256 360282489 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)! ! !GLMMorphicPresentationToolbarModel methodsFor: 'accessing' stamp: 'tg 11/6/2010 11:43'! presentation ^ presentation! ! !GLMMorphicPresentationToolbarModel methodsFor: 'accessing' stamp: 'tg 11/6/2010 11:43'! presentation: anObject presentation := anObject! ! !GLMMorphicPresentationToolbarModel methodsFor: 'accessing' stamp: 'tg 11/6/2010 11:43'! renderer ^ renderer! ! !GLMMorphicPresentationToolbarModel methodsFor: 'accessing' stamp: 'tg 11/6/2010 11:43'! renderer: anObject renderer := anObject! ! !GLMMorphicWidgetRenderer commentStamp: '' prior: 34283880! This is a helper class that is supposed to be subclassed for each rendering logic of a specific morph. For example, there will be a TreeRenderer, a TextRenderer etc! !GLMMorphicActionListRenderer class methodsFor: 'defaults' stamp: 'EstebanLorenzano 12/12/2011 20:05'! defaultWidth ^100! ! !GLMMorphicActionListRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 12/12/2011 22:00'! actOnPresentationUpdated: ann container removeAllMorphs. container addMorphBack: (self morphFrom: ann presentation)! ! !GLMMorphicActionListRenderer methodsFor: 'private' stamp: 'EstebanLorenzano 12/12/2011 19:40'! buttonMorph: aModel ^UITheme current newButtonIn: nil for: aModel getState: nil action: #execute arguments: nil getEnabled: nil label: aModel buttonLabel help: nil! ! !GLMMorphicActionListRenderer methodsFor: 'rendering' stamp: 'AndreiChis 8/6/2013 18:30'! morphFrom: anActionListPresentation | buttonsContainer buttonModel button | buttonsContainer := self rectangleMorphFrom: anActionListPresentation. anActionListPresentation allActions do: [ :each | buttonModel := GLMButtonModel new. buttonModel glamourPresentation: anActionListPresentation. buttonModel glamourAction: each. button := self buttonMorph: buttonModel. buttonsContainer addMorphBack: button. button width: self class defaultWidth ]. ^ buttonsContainer! ! !GLMMorphicActionListRenderer methodsFor: 'private' stamp: 'AndreiChis 8/6/2013 18:59'! rectangleMorphFrom: anActionListPresentation ^RectangleMorph new borderWidth: 0; color: Color transparent; layoutPolicy: TableLayout new; cellPositioning: #topLeft; hResizing: #spaceFill; vResizing: #spaceFill; listDirection: (anActionListPresentation isHorizontal ifTrue: [ #leftToRight ] ifFalse: [ #topToBottom ] ); listCentering: #topLeft; wrapCentering: #topLeft; cellInset: 5; yourself! ! !GLMMorphicActionListRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 12/12/2011 21:48'! render: anActionListPresentation container := GLMMorphic containerMorph. container changeTableLayout; listDirection: #leftToRight; vResizing: #spaceFill; hResizing: #spaceFill. container addMorphBack: (self morphFrom: anActionListPresentation). anActionListPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^container ! ! !GLMMorphicAccumulatorRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 12:25'! actOnPaneAdded: ann tabs addLazyPage: (GLMMorphicPaneWithoutTitleRenderer new render: ann pane) label: (self titleOrIconOf: ann pane presentations in: tabs) toolbar: nil collapsable: true. tabs selectedPageIndex: tabs pages size! ! !GLMMorphicAccumulatorRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 10:50'! actOnPaneSelected: anAnnouncement tabs selectedPageIndex: anAnnouncement position! ! !GLMMorphicAccumulatorRenderer methodsFor: 'as yet unclassified' stamp: 'TudorGirba 7/23/2011 20:26'! removePage: aPage | removedPageIndex | removedPageIndex := self pages indexOf: aPage. self announcer suspendAllWhile: [ super removePage: aPage ]. self announcer announce: (LazyTabPageRemoved new tabs: self; page: aPage; pageIndex: removedPageIndex; newIndex: self tabSelectorMorph selectedIndex). self pages isEmpty ifTrue: [ self contentMorph removeAllMorphs ]! ! !GLMMorphicAccumulatorRenderer methodsFor: 'rendering' stamp: 'TudorGirba 7/23/2011 20:21'! render: aBrowser aBrowser panes isEmpty ifTrue: [ ^ GLMMorphic emptyMorph ]. tabs := LazyTabGroupMorph new. tabs vResizing: #spaceFill; hResizing: #spaceFill; cornerStyle: (self theme tabGroupCornerStyleIn: nil); font: self theme labelFont. tabs announcer on: LazyTabPageChanged do: [:ann | aBrowser activeEntity: ((aBrowser panes at: ann pageIndex) port: #entity) value ]. tabs announcer on: LazyTabPageRemoved do: [:ann | aBrowser removePaneIndex: ann pageIndex. aBrowser panes isEmpty ifTrue: [aBrowser activeEntity: nil] ifFalse: [aBrowser activeEntity: ((aBrowser panes at: ann newIndex) port: #entity) value] ]. aBrowser panes do: [ :each | tabs addLazyPage: [ GLMMorphicPaneWithoutTitleRenderer new render: each ] label: (self titleOrIconOf: each presentations in: tabs) toolbar: (self renderToolbarForPresentation: each presentations inMorph: tabs ) collapsable: true ]. aBrowser on: GLMPaneSelected send: #actOnPaneSelected: to: self. aBrowser on: GLMPaneAdded send: #actOnPaneAdded: to: self. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. tabs selectedPageIndex: tabs pages size. ^ tabs! ! !GLMMorphicBrowserRenderer methodsFor: 'callbacks' stamp: 'TudorGirba 4/12/2011 12:49'! actOnBrowserClosed: ann self renderer window delete! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:07'! firstColumnMaxCellSizeFrom: aGLMDashboard |tmpMaxVerticalSize tmpMaxHorizontalSize| tmpMaxHorizontalSize := 0. tmpMaxVerticalSize := 0. (self firstColumnPanesFrom: aGLMDashboard) do: [:aGLMPane | |tmpPaneExtent| tmpPaneExtent := aGLMDashboard extentOfPaneNamed: aGLMPane name. tmpPaneExtent x > tmpMaxHorizontalSize ifTrue: [tmpMaxHorizontalSize := tmpPaneExtent x]. tmpPaneExtent y > tmpMaxVerticalSize ifTrue: [tmpMaxVerticalSize := tmpPaneExtent y]. ]. ^ tmpMaxHorizontalSize @ tmpMaxVerticalSize ! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:31'! firstColumnMinCellSizeFrom: aGLMDashboard |tmpMinVerticalSize tmpMinHorizontalSize| tmpMinHorizontalSize := (aGLMDashboard extentOfPaneNamed: (aGLMDashboard panes anyOne name)) x . tmpMinVerticalSize := (aGLMDashboard extentOfPaneNamed: (aGLMDashboard panes anyOne name)) y. (self firstColumnPanesFrom: aGLMDashboard) do: [:aGLMPane | |tmpPaneExtent| tmpPaneExtent := aGLMDashboard extentOfPaneNamed: aGLMPane name. tmpPaneExtent x < tmpMinHorizontalSize ifTrue: [tmpMinHorizontalSize := tmpPaneExtent x]. tmpPaneExtent y < tmpMinVerticalSize ifTrue: [tmpMinVerticalSize := tmpPaneExtent y]. ]. ^ tmpMinHorizontalSize @ tmpMinVerticalSize ! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:00'! firstColumnPanesFrom: aGLMDashboard |tmpHalfSizePanes tmpResult| aGLMDashboard panes isEmpty ifTrue: [^#()]. tmpResult := OrderedCollection new. tmpHalfSizePanes := (aGLMDashboard panes size / 2) asFloat rounded. 1 to: tmpHalfSizePanes do: [:anIndex | tmpResult add: (aGLMDashboard panes at: anIndex) ]. ^ tmpResult! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 7/29/2011 13:47'! render: aBrowser | container firstColumnContainer secondColumnContainer scrollPane panesMidSize| firstColumnContainer := PanelMorph new. secondColumnContainer := PanelMorph new. container := PanelMorph new. aBrowser defaultPaneExtent: #glamourOptimalExtent. firstColumnContainer fillStyle: Color transparent; fillStyle: Color transparent; changeTableLayout; cellPositioning: #topRight; layoutInset: 2; "maxCellSize: (self firstColumnMaxCellSizeFrom: aBrowser) ;" "minCellSize: 20@20 ;" cellInset: 2. secondColumnContainer fillStyle: Color transparent; changeTableLayout; cellPositioning: #topLeft; layoutInset: 2; "maxCellSize: (self secondColumnMaxCellSizeFrom: aBrowser) ;" "minCellSize: (self secondColumnMaxCellSizeFrom: aBrowser);" cellInset: 2. container fillStyle: Color transparent; changeTableLayout; extent: 200@200; layoutInset: 2; cellPositioning: #topLeft; "maxCellSize: 400@200; minCellSize: 400@150;" listDirection: #leftToRight; cellInset: 2. aBrowser extentStrategy initializeContainer: container. aBrowser extentStrategy initializeFirstColumn: firstColumnContainer. aBrowser extentStrategy initializeSecondColumn: secondColumnContainer. scrollPane := GeneralScrollPane new. scrollPane changeScrollerTableLayout; scrollTarget: container. (self firstColumnPanesFrom: aBrowser) reverseDo: [:aGLMPane | self renderPane: aGLMPane inUI: firstColumnContainer from: aBrowser. ]. (self secondColumnPanesFrom: aBrowser) reverseDo: [:aGLMPane | self renderPane: aGLMPane inUI: secondColumnContainer from: aBrowser ]. container addMorph: secondColumnContainer. container addMorph: firstColumnContainer. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. ^ scrollPane! ! !GLMMorphicDashboardRenderer methodsFor: 'private' stamp: 'AndreiChis 12/3/2012 17:27'! renderPane: aPane inUI: aMorph from: aGLMDashboard | pane totalSpans currentSpanPosition currentOffset tmpExtent| pane := self renderObject: (aPane). "pane hResizing: #rigid; vResizing: #rigid." "self haltIf: [aPane name = #dashboard]." "pane extent: (aGLMDashboard extentOfPaneNamed: aPane name). " aGLMDashboard extentStrategy initializePane: pane. pane extent: ((aGLMDashboard extentOfPaneNamed: aPane name) glamourValue: pane). "self haltIf: [pane submorphs contains: [:a | a isKindOf: GeneralScrollPane]]." aMorph addMorph: pane. ! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:08'! secondColumnMaxCellSizeFrom: aGLMDashboard |tmpMaxVerticalSize tmpMaxHorizontalSize| tmpMaxHorizontalSize := 0. tmpMaxVerticalSize := 0. (self secondColumnPanesFrom: aGLMDashboard) do: [:aGLMPane | |tmpPaneExtent| tmpPaneExtent := aGLMDashboard extentOfPaneNamed: aGLMPane name. tmpPaneExtent x > tmpMaxHorizontalSize ifTrue: [tmpMaxHorizontalSize := tmpPaneExtent x]. tmpPaneExtent y > tmpMaxVerticalSize ifTrue: [tmpMaxVerticalSize := tmpPaneExtent y]. ]. ^ tmpMaxHorizontalSize @ tmpMaxVerticalSize ! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:32'! secondColumnMinCellSizeFrom: aGLMDashboard |tmpMinVerticalSize tmpMinHorizontalSize| tmpMinHorizontalSize := (aGLMDashboard extentOfPaneNamed: (aGLMDashboard panes anyOne name)) x . tmpMinVerticalSize := (aGLMDashboard extentOfPaneNamed: (aGLMDashboard panes anyOne name)) y. (self secondColumnPanesFrom: aGLMDashboard) do: [:aGLMPane | |tmpPaneExtent| tmpPaneExtent := aGLMDashboard extentOfPaneNamed: aGLMPane name. tmpPaneExtent x < tmpMinHorizontalSize ifTrue: [tmpMinHorizontalSize := tmpPaneExtent x]. tmpPaneExtent y < tmpMinVerticalSize ifTrue: [tmpMinVerticalSize := tmpPaneExtent y]. ]. ^ tmpMinHorizontalSize @ tmpMinVerticalSize ! ! !GLMMorphicDashboardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/17/2011 11:42'! secondColumnPanesFrom: aGLMDashboard |tmpHalfSizePanes tmpResult| aGLMDashboard panes isEmpty ifTrue: [^#()]. tmpResult := OrderedCollection new. tmpHalfSizePanes := (aGLMDashboard panes size / 2) asFloat rounded. (tmpHalfSizePanes + 1) to: aGLMDashboard panes size do: [:anIndex | tmpResult add: (aGLMDashboard panes at: anIndex) ]. ^ tmpResult! ! !GLMMorphicDropDownRenderer methodsFor: 'as yet unclassified' stamp: 'AndreiChis 8/20/2013 23:11'! actOnContextChanged: ann ann property = #selection ifTrue: [ listModel announcer suspendAllWhile: [ dropDownMorph listSelectionIndex: (listModel glamourPresentation displayValue indexOf: ann value) ] ]! ! !GLMMorphicDropDownRenderer methodsFor: 'as yet unclassified' stamp: 'AndreiChis 8/21/2013 16:02'! actOnPresentationUpdated: ann listModel resetData. dropDownMorph updateList; updateListSelectionIndex ! ! !GLMMorphicDropDownRenderer methodsFor: 'as yet unclassified' stamp: 'AndreiChis 8/21/2013 15:23'! render: aDropListPresentation listModel:= GLMDropListModel new glamourPresentation: aDropListPresentation. "When the morph changes, we want to update the glamour model" listModel announcer on: GLMDropDownListMorphSelectionChanged do: [ :ann | aDropListPresentation selectedIndex: ann selectionIndex. aDropListPresentation selection: ann selectionValue ]. listModel selectionIndex: aDropListPresentation selectedIndex. dropDownMorph := (MorphDropListMorph on: listModel list: #list selected: #selectionIndex changeSelected: #selectionIndex: useIndex: true ) hResizing: #spaceFill; vResizing: #shrinkWrap. aDropListPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. aDropListPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ dropDownMorph ! ! !GLMMorphicExpanderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/26/2012 10:47'! render: aBrowser ^ self renderWithExpanders: aBrowser ! ! !GLMMorphicExpanderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 3/9/2011 10:20'! renderWithExpanders: aBrowser | morph scroll panel expander | panel := PanelMorph new. panel fillStyle: Color transparent; hResizing: #spaceFill; vResizing: #shrinkWrap; changeTableLayout; layoutInset: 2; cellInset: 2. scroll := GeneralScrollPane new. scroll changeScrollerTableLayout; scrollTarget: panel. aBrowser panes do: [:each | expander := ExpanderMorph titleText: (each presentations titleValue ifNil: ['noname']). morph := GLMMorphicPaneWithoutTitleRenderer new render: each. morph borderStyle: (UITheme current buttonSelectedBorderStyleFor: morph). expander addMorphBack: morph. panel addMorph: expander ]. ^ scroll! ! !GLMMorphicExpanderRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 2/13/2012 13:18'! renderWithTree: aBrowser | treeMorph treeModel | treeModel := GLMExpanderTreeMorphModel new glamourExpander: aBrowser. treeMorph := MorphTreeMorph new. treeMorph makeLastColumnUnbounded; getMenuSelector: #menu:shifted:; keystrokeActionSelector: #keyStroke:from:; cornerStyle: treeMorph preferredCornerStyle; borderStyle: (BorderStyle inset width: 1); hResizing: #spaceFill; vResizing: #spaceFill; layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); preferedPaneColor: Color white; model: treeModel; columns: ( OrderedCollection with: (MorphTreeColumn new rowMorphGetSelector: #elementColumn)). treeMorph vShowScrollBar. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. ^ treeMorph buildContents! ! !GLMMorphicFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:10'! actOnPaneAdded: ann self subclassResponsibility! ! !GLMMorphicFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:11'! actOnPaneRemoved: ann self subclassResponsibility! ! !GLMMorphicFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:11'! actOnPaneReplaced: ann self subclassResponsibility! ! !GLMMorphicFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:49'! registerAnnouncementsFor: aBrowser aBrowser on: GLMPaneRemoved send: #actOnPaneRemoved: to: self. aBrowser on: GLMPaneAdded send: #actOnPaneAdded: to: self. aBrowser on: GLMPaneReplaced send: #actOnPaneReplaced: to: self. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self.! ! !GLMMorphicFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:09'! render: aBrowser ^ self subclassResponsibility! ! !GLMMorphicFixedPanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:10'! actOnPaneAdded: ann container pushPane: (self renderObject: ann pane)! ! !GLMMorphicFixedPanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:10'! actOnPaneRemoved: ann container popPane! ! !GLMMorphicFixedPanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:10'! actOnPaneReplaced: ann container popAndReplacePane: (self renderObject: ann newPane)! ! !GLMMorphicFixedPanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:11'! render: aBrowser container := GLMPaneScroller new name: 'scroller'; vResizing: #spaceFill; hResizing: #spaceFill; yourself. container maxPanes: aBrowser fixedSizePanes. self registerAnnouncementsFor: aBrowser. aBrowser panes do: [ :each | container pushPane: (self renderObject: each) ]. ^ container! ! !GLMMorphicVariablePanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:12'! actOnPaneAdded: ann self addMorphFromObject: ann pane toContainer: container. scrollPane hScrollbar glmAnimateValue: 1.0 duration: 2000! ! !GLMMorphicVariablePanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:12'! actOnPaneRemoved: ann container removeMorph: container submorphs last. container removeMorph: container submorphs last! ! !GLMMorphicVariablePanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:13'! actOnPaneReplaced: ann container removeMorph: container submorphs last. container removeMorph: container submorphs last. self addMorphFromObject: ann newPane toContainer: container. scrollPane hScrollbar glmAnimateValue: 1.0 duration: 200! ! !GLMMorphicVariablePanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:11'! addMorphFromObject: anObject toContainer: aContainerMorph | renderedMorph | renderedMorph := (self renderObject: anObject) vResizing: #spaceFill; hResizing: #rigid; minimumExtent: 200@10; extent: 200@10; yourself. aContainerMorph addMorphBack: renderedMorph. aContainerMorph addMorphBack: (EdgeGripMorph new width: ProportionalSplitterMorph splitterWidth; hResizing: #rigid; "not the default this time, vResizing is also #spaceFill by default" target: renderedMorph)! ! !GLMMorphicVariablePanesFinderRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 18:13'! render: aBrowser container := GLMMorphic containerMorph. container changeTableLayout; listDirection: #leftToRight; vResizing: #spaceFill; hResizing: #shrinkWrap. scrollPane := GeneralScrollPane new changeScrollerTableLayout; scrollTarget: container; yourself. self registerAnnouncementsFor: aBrowser. aBrowser panes do: [ :each | self addMorphFromObject: each toContainer: container ]. ^ scrollPane! ! !GLMMorphicStackerRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:49'! render: aBrowser | tabs | aBrowser panes isEmpty ifTrue: [ ^ GLMMorphic emptyMorph ]. tabs := LazyTabGroupMorph new. tabs vResizing: #spaceFill; hResizing: #spaceFill; cornerStyle: (self theme tabGroupCornerStyleIn: nil); font: self theme labelFont. aBrowser panes do: [ :each | self flag: 'add toolbar'. tabs addLazyPage: [ GLMMorphicPaneWithoutTitleRenderer new render: each ] label: (self titleOrIconOf: each presentations in: tabs) toolbar: (self renderToolbarForPresentation: each presentations inMorph: tabs) ]. tabs selectedPageIndex: 1. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. ^ tabs! ! !GLMMorphicTabulatorRenderer methodsFor: 'private' stamp: 'TudorGirba 5/20/2013 06:51'! margin ^ 5! ! !GLMMorphicTabulatorRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:49'! render: aBrowser | container | container := GLMMorphic containerMorph. aBrowser cell isRow ifTrue: [ self renderCustomRow: aBrowser cell ofPane: aBrowser pane inUI: container inBrowser: aBrowser ] ifFalse: [ self renderCustomColumn: aBrowser cell ofPane: aBrowser pane inUI: container inBrowser: aBrowser ]. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. ^ container! ! !GLMMorphicTabulatorRenderer methodsFor: 'private' stamp: 'TudorGirba 5/20/2013 06:50'! renderCustomColumn: aCell ofPane: aPane inUI: aMorph inBrowser: aBrowser | pane totalSpans currentSpanPosition currentOffset | totalSpans := aCell children inject: 0 into: [ :sum :each | sum + each span ]. currentSpanPosition := 0. currentOffset := 0. aCell children keysAndValuesDo: [ :index :each | each hasId ifTrue: [ pane := self renderObject: (aBrowser paneNamed: each id) ] ifFalse: [ pane := GLMMorphic containerMorph. self renderCustomRow: each ofPane: aPane inUI: pane inBrowser: aBrowser. pane addPaneSplitters ]. pane layoutFrame: (LayoutFrame new topFraction: currentSpanPosition / totalSpans offset: currentOffset + self margin; leftFraction: 0 offset: 0; bottomFraction: (currentSpanPosition + each span) / totalSpans offset: currentOffset + each size - self margin; rightFraction: 1 offset: 0; yourself). aMorph addMorphBack: pane. currentSpanPosition := currentSpanPosition + each span. currentOffset := currentOffset + each size ]. aCell children last size > 0 ifTrue: [ (aMorph submorphs atLast: 2) layoutFrame bottomOffset: (aMorph submorphs atLast: 2) layoutFrame bottomOffset - aCell children last size. aMorph submorphs last layoutFrame topOffset: aMorph submorphs last layoutFrame topOffset - aCell children last size. aMorph submorphs last layoutFrame bottomOffset: aMorph submorphs last layoutFrame bottomOffset - aCell children last size ]. aMorph addPaneSplitters! ! !GLMMorphicTabulatorRenderer methodsFor: 'private' stamp: 'TudorGirba 5/20/2013 06:50'! renderCustomRow: aCell ofPane: aPane inUI: aMorph inBrowser: aBrowser | pane totalSpans currentSpanPosition currentOffset | totalSpans := aCell children inject: 0 into: [ :sum :each | sum + each span ]. currentSpanPosition := 0. currentOffset := 0. aCell children keysAndValuesDo: [ :index :each | each hasId ifTrue: [ pane := self renderObject: (aBrowser paneNamed: each id) ] ifFalse: [ pane := GLMMorphic containerMorph. self renderCustomColumn: each ofPane: aPane inUI: pane inBrowser: aBrowser. pane addPaneSplitters ]. pane layoutFrame: (LayoutFrame new topFraction: 0 offset: 0; leftFraction: currentSpanPosition / totalSpans offset: currentOffset + self margin; bottomFraction: 1 offset: 0; rightFraction: (currentSpanPosition + each span) / totalSpans offset: currentOffset + each size - self margin; yourself). aMorph addMorphBack: pane. currentSpanPosition := currentSpanPosition + each span. currentOffset := currentOffset + each size ]. (aCell children last size > 0) ifTrue: [ (aMorph submorphs atLast: 2) layoutFrame rightOffset: (aMorph submorphs atLast: 2) layoutFrame rightOffset - aCell children last size. aMorph submorphs last layoutFrame leftOffset: aMorph submorphs last layoutFrame leftOffset - aCell children last size. aMorph submorphs last layoutFrame rightOffset: aMorph submorphs last layoutFrame rightOffset - aCell children last size.]. aMorph addPaneSplitters! ! !GLMMorphicValidatorRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 5/5/2011 12:10'! render: aBrowser |tmpButtons| tmpButtons := OrderedCollection new. aBrowser panes isEmpty ifTrue: [ "|tmpPane| tmpPane := (GLMPane in: aBrowser) addPresentation: aBrowser presentations; yourself. (tmpPane port: #entity) value: aBrowser entity. aBrowser panes add: tmpPane" ]. aBrowser buttonActions do: [:aGLMAction | |buttonModel| buttonModel := GLMButtonModel new. buttonModel glamourPresentation: aBrowser. buttonModel glamourAction: aGLMAction. tmpButtons add: (PluggableButtonMorph on: buttonModel getState: nil action: #execute label: #buttonLabel) ]. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. container := (GLMMorphicValidatorPaneRenderer new buttons: tmpButtons; render: aBrowser panes anyOne). ^ container ! ! !GLMMorphicValidatorRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/23/2011 13:25'! render: aBrowser from: aGLMRenderer self renderer: aGLMRenderer. ^ self render: aBrowser ! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 4/4/2011 14:52'! actOnPaneAdded: ann container removeMorph: container submorphs last. self addMorphFromObject: ann pane toContainer: container.! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 4/4/2011 15:53'! actOnPaneRemoved: ann! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/31/2011 16:33'! actOnPaneReplaced: ann container removeMorph: container submorphs last. self addMorphFromObject: ann newPane toContainer: container. "scrollPane hScrollbar glmAnimateValue: 1.0 duration: 200"! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/31/2011 17:25'! addMorphFromObject: anObject toContainer: aContainerMorph | renderedMorph | renderedMorph := (self renderObject: anObject). "vResizing: #spaceFill; hResizing: #rigid; minimumExtent: 200@10; extent: 200@10; yourself." aContainerMorph addMorphBack: renderedMorph.! ! !GLMMorphicWizardRenderer methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/1/2011 14:16'! parentRenderer ^ parentRenderer! ! !GLMMorphicWizardRenderer methodsFor: 'accessing' stamp: 'cyrilledelaunay 4/1/2011 14:17'! parentRenderer: aGLMMorphicRenderer parentRenderer := aGLMMorphicRenderer! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 12:50'! registerAnnouncementsFor: aBrowser aBrowser on: GLMPaneRemoved send: #actOnPaneRemoved: to: self. aBrowser on: GLMPaneAdded send: #actOnPaneAdded: to: self. aBrowser on: GLMPaneReplaced send: #actOnPaneReplaced: to: self. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self.! ! !GLMMorphicWizardRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 4/4/2011 16:43'! render: aBrowser container := GLMMorphic containerMorph. container changeTableLayout; listDirection: #leftToRight; vResizing: #spaceFill; hResizing: #spaceFill. scrollPane := GeneralScrollPane new changeScrollerTableLayout; scrollTarget: container; yourself. self registerAnnouncementsFor: aBrowser. self addMorphFromObject: (aBrowser stepsAndPanes at: aBrowser currentStep) last toContainer: container . ^ scrollPane! ! !GLMMorphicWrapperRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/18/2012 22:38'! render: aBrowser | paneMorph | container := GLMMorphic containerMorph. paneMorph := self renderObject: aBrowser defaultPane. paneMorph layoutFrame: (LayoutFrame fractions: (0@0 corner: 1@1)). container addMorphBack: paneMorph. aBrowser on: GLMBrowserClosed send: #actOnBrowserClosed: to: self. ^ container ! ! !GLMMorphicAccordionRenderer methodsFor: 'rendering' stamp: 'TudorGirba 1/31/2011 02:12'! render: aPresentation | presentations container expander | presentations := aPresentation matchingPresentations. presentations isEmpty ifTrue: [ ^ GLMMorphic emptyMorph ]. presentations size = 1 ifTrue: [ ^ self renderWithToolbar: presentations first ]. container := GLMMorphic containerMorph. container changeTableLayout. presentations do: [ :each | expander := self theme newExpanderIn: container label: (self titleOrIconOf: each in: container) forAll: {(self renderWithToolbar: each)}. container addMorphBack: expander. (aPresentation pane lastActivePresentation notNil and: [ each title = aPresentation pane lastActivePresentation title ]) ifTrue: [ expander expanded: true]]. (aPresentation pane lastActivePresentation isNil and: [container submorphs notEmpty]) ifTrue: [ container submorphs first expanded: true]. ^ container! ! !GLMMorphicTabbedRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 11/3/2011 17:40'! actOnPresentationUpdated: ann | index presentations | presentations := ann presentation matchingPresentations. tabs pages size to: 1 by: -1 do: [ :i | tabs removePageIndex: i ]. presentations do: [ :each | tabs addLazyPage: [ self renderObject: each ] label: (self titleOrIconOf: each in: tabs) toolbar: (self renderToolbarForPresentation: each inMorph: tabs ) ]. index := 1. presentations withIndexDo: [ :each :i | ann presentation pane lastActivePresentation notNil and: [ each title = ann presentation pane lastActivePresentation title ifTrue: [ index := i ] ] ]. tabs selectedPageIndex: index.! ! !GLMMorphicTabbedRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/21/2012 05:10'! render: aPresentation | presentations index | presentations := aPresentation matchingPresentations. presentations isEmpty ifTrue: [ ^ GLMMorphic emptyMorph ]. (presentations size = 1 and: [ presentations first hasTitleIcon not ]) ifTrue: [ ^ self renderWithTitleOrNil: presentations first ]. tabs := LazyTabGroupMorph new. tabs vResizing: #spaceFill; hResizing: #spaceFill; cornerStyle: (self theme tabGroupCornerStyleIn: nil); font: self theme buttonFont. tabs announcer when: LazyTabPageChanged do: [:ann | aPresentation pane lastActivePresentation: (aPresentation matchingPresentations at: (ann pageIndex)) ]. presentations do: [ :each | tabs addLazyPage: [ self renderObject: each ] label: (self titleOrIconOf: each in: tabs) toolbar: (self renderToolbarForPresentation: each inMorph: tabs ) ]. index := 1. presentations withIndexDo: [ :each :i | (aPresentation pane isLastActivePresentation: each) ifTrue: [ index := i ] ]. tabs selectedPageIndex: index. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ tabs! ! !GLMMorphicVerticallyStackedRenderer methodsFor: 'rendering' stamp: 'TudorGirba 1/20/2011 21:55'! render: aPresentation | presentations container | presentations := aPresentation matchingPresentations. presentations isEmpty ifTrue: [ ^ GLMMorphic emptyMorph ]. container := GLMMorphic containerMorph. container changeTableLayout. presentations do: [ :each | container addMorphBack: (self renderWithTitle: each) ]. ^ container! ! !GLMMorphicDiffRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/4/2011 18:16'! render: aPresentation | textMorph | textMorph := (DiffMorph from: aPresentation displayValue first to: aPresentation displayValue last) " onKeyStrokeSend: #keystroke:from: to: textModel; " layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); vResizing: #spaceFill; hResizing: #spaceFill; color: Color white; yourself. " self installActionsOnUI: textModel fromPresentation: aTextPresentation. aTextPresentation selectedTextBlock: [ textMorph textMorph editor selection ]. aTextPresentation textBlock: [ textMorph textMorph editor text ]. " ^textMorph! ! !GLMMorphicDynamicRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 10:54'! actOnPresentationUpdated: anAnnouncement container removeAllMorphs. container addMorph: (self renderObject: anAnnouncement presentation currentPresentation) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)) ! ! !GLMMorphicDynamicRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/21/2012 05:17'! render: aPresentation container := GLMMorphic containerMorph. container addMorph: (self renderObject: aPresentation currentPresentation) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)). aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ container! ! !GLMMorphicEyeSeeRenderer methodsFor: 'private' stamp: 'TudorGirba 4/12/2011 11:28'! actOnContextChanged: ann "ann property = #selection ifTrue: [ eyeseeCanvas selected: (eyeseeCanvas root deepFindNodeWithEntity: ann value) ]"! ! !GLMMorphicEyeSeeRenderer methodsFor: 'private' stamp: 'TudorGirba 4/12/2011 11:08'! actOnPresentationUpdate: ann ann presentation diagram: ESDiagramRenderer new. canvasScrollPane scroller removeMorph: canvasScrollPane scroller submorphs first. self eyeseeCanvasFor: ann presentation! ! !GLMMorphicEyeSeeRenderer methodsFor: 'private' stamp: 'TudorGirba 4/19/2011 13:34'! eyeseeCanvasFor: aPresentation | eyeseeRenderer | eyeseeRenderer := aPresentation eyeseeRenderer. aPresentation renderOn: eyeseeRenderer. eyeseeRenderer interaction when: ESElementSelection do: [ :ann | aPresentation selection: ann element ]. eyeseeRenderer interaction when: ESElementDeselection do: [ :ann | aPresentation status: ann element ]. eyeseeRenderer interaction when: ESMouseLeave do: [ :ann | aPresentation status: nil ]. eyeseeCanvas := aPresentation canvas. canvasScrollPane scroller addMorph: eyeseeCanvas! ! !GLMMorphicEyeSeeRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/12/2011 10:25'! render: aPresentation canvasScrollPane := ScrollPane new. self eyeseeCanvasFor: aPresentation. canvasScrollPane color: Color white; vResizing: #spaceFill; hResizing: #spaceFill. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdate: to: self. aPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. ^ canvasScrollPane! ! !GLMMorphicLabelRenderer methodsFor: 'rendering' stamp: 'TudorGirba 7/1/2011 23:18'! actOnPresentationUpdated: anAnnouncement labelMorph contents: anAnnouncement presentation formatedDisplayValue! ! !GLMMorphicLabelRenderer methodsFor: 'rendering' stamp: 'TudorGirba 7/1/2011 23:16'! render: aLabelPresentation labelMorph := (LabelMorph contents: aLabelPresentation formatedDisplayValue) layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); vResizing: #spaceFill; hResizing: #spaceFill; font: StandardFonts haloFont; yourself. aLabelPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^labelMorph! ! !GLMMorphicListingRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 10:47'! actOnContextChanged: anAnnouncement anAnnouncement property = #selection ifTrue: [ treeModel announcer suspendAllWhile: [ treeMorph model explicitSelection: anAnnouncement value ] ] ! ! !GLMMorphicListingRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/20/2012 15:18'! actOnUpdatedPresentation: anAnnouncement treeMorph model updateRoots. self flag: 'Calling update list explicitly here is a hack. This should be solvable by the model through a notification mechanism'. treeMorph updateList! ! !GLMMorphicListingRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/19/2013 16:39'! render: aPresentation | container textInput | treeModel := GLMTreeMorphModel new glamourPresentation: aPresentation. container := GLMMorphic containerMorph. treeMorph := self treeMorphFor: treeModel and: aPresentation. aPresentation allowsInput ifTrue: [ textInput := self textInputFor: treeModel withHelpMessage: aPresentation helpMessage. treeMorph layoutFrame bottomOffset: -26. container addMorphBack: textInput ]. container addMorphBack: treeMorph. self installActionsOnModel: treeModel fromPresentation: aPresentation. self installKeystrokeActionsOnMorph: treeMorph fromPresentation: aPresentation. aPresentation selection notNil ifTrue: [ treeModel announcer suspendAllWhile: [ treeMorph model explicitSelection: aPresentation selection ] ]. "When the morph changes, we want to update the glamour model" treeModel announcer on: GLMTreeMorphSelectionChanged do: [ :ann | aPresentation announcer suspendAllWhile: [ aPresentation selection: ann selectionValue. aPresentation selectionPath: ann selectionPathValue ] ]. treeModel announcer on: GLMTreeMorphStrongSelectionChanged do: [ :ann | aPresentation strongSelection: ann strongSelectionValue ]. "When the glamour model changes, we want to update the morph" aPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. aPresentation on: GLMPresentationUpdated send: #actOnUpdatedPresentation: to: self. ^ container! ! !GLMMorphicListingRenderer methodsFor: 'private' stamp: 'TudorGirba 5/23/2013 06:33'! textInputFor: aTreeModel withHelpMessage: helpStringMessage | textInput | textInput := self theme newTextEntryIn: nil for: aTreeModel get: #inputText set: #inputText: class: String getEnabled: #inputTextEnabled help: helpStringMessage. textInput askBeforeDiscardingEdits: false. textInput layoutFrame: (LayoutFrame fractions: (0 @ 1 corner: 1 @ 1) offsets: (0 @ -26 corner: 0 @ -4)). textInput ghostText: 'enter search query'. ^ textInput! ! !GLMMorphicListingRenderer methodsFor: 'private' stamp: 'TudorGirba 10/19/2013 03:54'! treeMorphFor: tmpTreeModel and: aPresentation | tmpTreeMorph columns | tmpTreeMorph := PaginatedMorphTreeMorph new. tmpTreeMorph makeLastColumnUnbounded; doubleClickSelector: #onDoubleClick; getMenuSelector: #menu:shifted:; keystrokeActionSelector: #keyStroke:from:; columnInset: 3; cornerStyle: tmpTreeMorph preferredCornerStyle; borderStyle: (BorderStyle inset width: 1); autoDeselection: aPresentation allowsDeselection; dragEnabled: tmpTreeModel dragEnabled; dropEnabled: tmpTreeModel dropEnabled; hResizing: #spaceFill; vResizing: #spaceFill; layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)). columns := aPresentation columns isEmpty ifTrue: [ OrderedCollection with: (MorphTreeColumn new rowMorphGetSelector: #elementColumn)] ifFalse: [ aPresentation columns collect: [:each | GLMMorphTreeColumn new startWidth: each width; glamourColumn: each; headerButtonLabel: (aPresentation titleValueOfColumn: each) font: StandardFonts menuFont target: nil actionSelector: nil arguments: #(); yourself ]. ]. tmpTreeMorph preferedPaneColor: Color white; model: tmpTreeModel; columns: columns. aPresentation isMultiple ifTrue: [tmpTreeMorph beMultiple] ifFalse: [tmpTreeMorph beSingle]. tmpTreeMorph chunkSize: aPresentation amountToShow. tmpTreeMorph pageSize: aPresentation amountToShow. tmpTreeMorph vShowScrollBar. ^ tmpTreeMorph buildContents! ! !GLMMorphicTreeRenderer methodsFor: 'rendering' stamp: 'JanKurs 5/27/2013 14:32'! render: aPresentation | container | container := super render: aPresentation. aPresentation shouldAllExpand ifTrue: [container submorphs first expandAll ]. aPresentation shouldRootsExpand ifTrue: [container submorphs first expandRoots ]. aPresentation shouldExpandToLevel ifTrue: [ container submorphs first expandAllTo: aPresentation expandLevel ]. ^ container! ! !GLMMorphicMagritteRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/30/2011 15:54'! actOnPresentationUpdated: ann scrollPane scrollTarget: (self magritteMorphFrom: ann presentation) ! ! !GLMMorphicMagritteRenderer methodsFor: 'rendering' stamp: 'TudorGirba 9/16/2011 10:54'! magritteMorphFrom: aMagrittePresentation | toShow description magritteMorph magritteDescriptionMorph | toShow := aMagrittePresentation displayValue. description := (aMagrittePresentation magritteDescription glamourValue: toShow) copy. "Using MAContainerMorph can raise some problems, as it try to delete morphs after commiting. We don't want this behavior." (description morphClass = MAContainerMorph) ifTrue: [description morphClass: MASilentContainerMorph]. magritteDescriptionMorph := (description asMorphOn: toShow) onAnswer: [ :value | aMagrittePresentation reactOnAnswerFor: value ]. magritteMorph := magritteDescriptionMorph addButtons; morph. magritteMorph hResizing: #spaceFill; vResizing: #shrinkWrap; layoutChanged. ^ magritteMorph! ! !GLMMorphicMagritteRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/21/2011 11:30'! render: aMagrittePresentation . scrollPane := GeneralScrollPane new. scrollPane changeScrollerTableLayout. scrollPane scrollTarget: (self magritteMorphFrom: aMagrittePresentation). scrollPane layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1) offsets: (0 @ 25 corner: 0 @ 0)). aMagrittePresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ scrollPane! ! !GLMMorphicMondrianRenderer methodsFor: 'private' stamp: 'TudorGirba 2/15/2011 12:47'! actOnContextChanged: ann ann property = #selection ifTrue: [ mondrianCanvas selected: (mondrianCanvas root deepFindNodeWithEntity: ann value) ]! ! !GLMMorphicMondrianRenderer methodsFor: 'private' stamp: 'TudorGirba 4/4/2013 03:35'! actOnPresentationUpdate: ann ann presentation view: MOViewRenderer new. canvasScrollPane scroller removeMorph: canvasScrollPane scroller submorphs first. self mondrianCanvasFor: ann presentation! ! !GLMMorphicMondrianRenderer methodsFor: 'private' stamp: 'TudorGirba 2/15/2011 17:50'! mondrianCanvasFor: aPresentation | view | view := aPresentation view. view root interaction menu: [ :x | self menuIn: MenuMorph new for: aPresentation ]. aPresentation renderOn: view. mondrianCanvas := aPresentation canvas. mondrianCanvas announcer when: MOElementSelection do: [ :ann | aPresentation selection: ann element model ]. mondrianCanvas announcer when: MOMouseEnter do: [ :ann | aPresentation status: ann element model ]. mondrianCanvas announcer when: MOMouseLeave do: [ :ann | aPresentation status: nil ]. canvasScrollPane scroller addMorph: mondrianCanvas! ! !GLMMorphicMondrianRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 17:51'! render: aPresentation canvasScrollPane := ScrollPane new. self mondrianCanvasFor: aPresentation. canvasScrollPane color: Color white; vResizing: #spaceFill; hResizing: #spaceFill. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdate: to: self. aPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. ^ canvasScrollPane! ! !GLMMorphicMorphRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 11/8/2011 02:06'! actOnKeyStroke: aPresentation event: anEvent from: aMorph | action | anEvent commandKeyPressed ifFalse: [ ^self ]. action := (self allKeyboardActionsFor: aPresentation) detect: [ :each | each shortcut = anEvent keyCharacter ] ifNone: [ nil ]. action ifNotNil: [ action actOn: aPresentation].! ! !GLMMorphicMorphRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 11/7/2011 11:23'! actOnPresentationUpdated: ann container removeAllMorphs. container addMorphBack: (self morphFrom: ann presentation)! ! !GLMMorphicMorphRenderer methodsFor: 'private' stamp: 'EstebanLorenzano 11/8/2011 00:22'! allKeyboardActionsFor: aPresentation ^(aPresentation allActions, aPresentation allSelectionActions) select: [ :action | action hasShortcut ]! ! !GLMMorphicMorphRenderer methodsFor: 'rendering' stamp: 'EstebanLorenzano 11/8/2011 00:22'! morphFrom: aMorphPresentation | morph allActions | morph := aMorphPresentation displayValue vResizing: #spaceFill; hResizing: #spaceFill; yourself. (self allKeyboardActionsFor: aMorphPresentation) ifNotEmpty: [ morph on: #keyStroke send: #actOnKeyStroke:event:from: to: self withValue: aMorphPresentation ]. ^morph! ! !GLMMorphicMorphRenderer methodsFor: 'rendering' stamp: 'TudorGirba 4/3/2013 16:57'! render: aMorphPresentation container := GLMMorphic containerMorph. container changeTableLayout; listDirection: #leftToRight; vResizing: #spaceFill; hResizing: #spaceFill. container addMorphBack: (self morphFrom: aMorphPresentation). aMorphPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ container! ! !GLMMorphicPaneRenderer methodsFor: 'rendering' stamp: 'TudorGirba 10/8/2011 15:07'! actOnMatchingPresentationChanged: anAnnouncement container removeAllMorphs. self renderContainerFor: anAnnouncement pane. self renderer window isNil ifFalse: [ self flag: 'this check is fishy'. self renderer window fullBounds]! ! !GLMMorphicPaneRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 11:06'! render: aPane container := GLMMorphic containerMorph. self renderContainerFor: aPane. aPane on: GLMMatchingPresentationsChanged send: #actOnMatchingPresentationChanged: to: self. ^ container! ! !GLMMorphicPaneRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/28/2012 00:25'! renderContainerFor: aPane container addMorph: (self renderWithTitleOrNil: aPane presentations) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); adoptPaneColor: Color transparent! ! !GLMMorphicPaneWithoutTitleRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 12:31'! actOnMatchingPresentationsChanged: anAnnouncement paneMorph removeAllMorphs. self renderMorphFor: anAnnouncement pane. self renderer window fullBounds! ! !GLMMorphicPaneWithoutTitleRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 12:29'! render: aPane paneMorph := GLMMorphic containerMorph. aPane on: GLMMatchingPresentationsChanged send: #actOnMatchingPresentationsChanged: to: self. self renderMorphFor: aPane. ^ paneMorph! ! !GLMMorphicPaneWithoutTitleRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 12:29'! renderMorphFor: aPane paneMorph addMorph: (self renderObject: aPane presentations) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); adoptPaneColor: paneMorph paneColor! ! !GLMMorphicRoassalRenderer methodsFor: 'rendering' stamp: 'TudorGirba 1/22/2013 20:21'! actOnPresentationUpdate: ann | aView | aView := ROMondrianViewBuilder new. ann presentation renderOn: aView. myMorph setView: aView stack! ! !GLMMorphicRoassalRenderer methodsFor: 'rendering' stamp: 'TudorGirba 10/19/2013 03:47'! render: aRoassalPresentation | view | view := aRoassalPresentation view. aRoassalPresentation renderOn: view. aRoassalPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdate: to: self. ^ myMorph := ROPlatform current widgetFactory forView: view stack! ! !GLMMorphicRubricSmalltalkCodeRenderer methodsFor: 'rendering' stamp: 'TudorGirba 6/3/2013 23:55'! morph ^ RubScrolledTextMorph new model: textModel; beForSmalltalkCode; yourself! ! !GLMMorphicRubricTextRenderer methodsFor: 'private' stamp: 'AlainPlantec 8/2/2013 18:23'! actOnContextChanged: ann ann property = #selectionInterval ifTrue: [ ann value notNil ifTrue: [textMorph setSelection: ann value ] ifFalse: [textMorph setSelection: (1 to: 0)] ]! ! !GLMMorphicRubricTextRenderer methodsFor: 'private' stamp: 'AlainPlantec 8/2/2013 15:51'! actOnPresentationUpdated: ann textMorph setText: ann presentation formatedDisplayValue! ! !GLMMorphicRubricTextRenderer methodsFor: 'rendering' stamp: 'TudorGirba 6/3/2013 23:47'! modelFor: aPresentation ^ GLMRubricTextModel new glamourPresentation: aPresentation; yourself! ! !GLMMorphicRubricTextRenderer methodsFor: 'rendering' stamp: 'AlainPlantec 9/18/2013 22:02'! morph ^ RubScrolledTextMorph new getSelectionSelector: #primarySelectionInterval; model: textModel; yourself! ! !GLMMorphicRubricTextRenderer methodsFor: 'rendering' stamp: 'AlainPlantec 9/18/2013 22:00'! render: aPresentation textModel := self modelFor: aPresentation. textModel primarySelectionInterval: aPresentation primarySelectionInterval. textMorph := self morph. aPresentation text: textMorph text. aPresentation withLineNumbers ifTrue: [ textMorph withLineNumbers ] ifFalse: [ textMorph withoutLineNumbers ]. aPresentation withAnnotation ifTrue: [ textMorph withAnnotation ] ifFalse: [ textMorph withoutAnnotation ]. aPresentation withColumns ifTrue: [ textMorph withColumns ] ifFalse: [ textMorph withoutColumns ]. textMorph wrapped: aPresentation wrapped. textMorph tabWidth: aPresentation tabWidth. textMorph addAllSegments: aPresentation textSegments. (aPresentation textSegments anySatisfy: [ :ts | ts icon notNil ]) ifTrue: [ textMorph withTextSegmentIcons ] ifFalse: [ textMorph withoutTextSegmentIcons ]. textMorph announcer on: RubTextChanged do: [ :ann | aPresentation announcer suspendAllWhile: [ aPresentation text: textMorph text ] ]. textMorph textArea announcer on: RubSelectionChanged do: [ :ann | aPresentation announcer suspendAllWhile: [ aPresentation selectionInterval: textMorph selectionInterval. aPresentation selectedText: textMorph textArea selection ] ]. textMorph announcer on: RubTextAccepted do: [ :ann | aPresentation suspendAllWhile: [ aPresentation text: ann text ] ]. self installActionsOnModel: textModel fromPresentation: aPresentation . self installKeystrokeActionsOnMorph: textMorph textArea fromPresentation: aPresentation. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. aPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. ^ textMorph! ! !GLMMorphicSpecRenderer methodsFor: 'as yet unclassified' stamp: 'TudorGirba 4/3/2013 17:00'! actOnPresentationUpdated: ann container removeAllMorphs. container addMorphBack: (self morphFrom: ann presentation)! ! !GLMMorphicSpecRenderer methodsFor: 'as yet unclassified' stamp: 'TudorGirba 4/3/2013 17:03'! render: aPresentation container := GLMMorphic containerMorph. container changeTableLayout; listDirection: #leftToRight; vResizing: #spaceFill; hResizing: #spaceFill. container addMorphBack: aPresentation displayValue widget. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. ^ container! ! !GLMMorphicSmalltalkCodeRenderer methodsFor: 'rendering' stamp: 'TudorGirba 9/20/2011 23:44'! textModelFor: aPresentation | tm | tm := GLMSmalltalkCodeModel new text: aPresentation formatedDisplayValue; glamourPresentation: aPresentation; highlightSmalltalk: true; highlightSmalltalkContext: aPresentation highlightSmalltalkContext. aPresentation variableBindings do: [ :each | tm addVariableBinding: each ]. ^ tm! ! !GLMMorphicSmalltalkCodeRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/10/2013 22:46'! textMorphForModel: aTextModel | morph | morph := GLMPluggableTextMorph new. morph styler workspace: aTextModel. morph on: aTextModel text: #text accept: #accept:notifying: readSelection: #selection menu: #menu:shifted:; changedAction: [:aText| aText asString trimBoth ifNotEmpty: [aTextModel text: aText] ]; onKeyStrokeSend: #keystroke:from: to: aTextModel; layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); vResizing: #spaceFill; hResizing: #spaceFill; color: Color white; font: StandardFonts codeFont; yourself. ^ morph! ! !GLMMorphicTextRenderer methodsFor: 'rendering' stamp: 'TudorGirba 11/28/2012 22:02'! actOnContextChanged: ann ann property = #selectionInterval ifTrue: [ ann value notNil ifTrue: [textMorph setSelection: ann value ] ifFalse: [textMorph setSelection: (1 to: 0)] ]! ! !GLMMorphicTextRenderer methodsFor: 'rendering' stamp: 'TudorGirba 6/3/2013 08:21'! actOnPresentationUpdated: ann textModel text: ann presentation formatedDisplayValue. textModel changed: #text! ! !GLMMorphicTextRenderer methodsFor: 'rendering' stamp: 'AndreiChis 6/20/2013 15:49'! render: aPresentation textModel := self textModelFor: aPresentation. textMorph := self textMorphForModel: textModel. "this is a horrible hack: because we cannot get the update of when the text changes from the morph, we get the reference to the mutable text object :) :)" textModel text: textMorph text. textMorph setSelection: textModel selection. "Without setting the selection again the smalltalkcode presentation shows no selection. Seems to be cause by the font: message send when creating a GLMPluggableTextMorph" self installActionsOnModel: textModel fromPresentation: aPresentation . self installKeystrokeActionsOnMorph: textMorph textMorph fromPresentation: aPresentation. textMorph announcer on: GLMSelectedTextChanged do: [ :ann | aPresentation announcer suspendAllWhile: [ aPresentation selectionInterval: ann interval. aPresentation selectedText: ann selectedText ] ]. textMorph announcer on: GLMTextChanged do: [ :ann | aPresentation suspendAllWhile: [ aPresentation text: ann text ] ]. aPresentation on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. aPresentation on: GLMContextChanged send: #actOnContextChanged: to: self. ^ textMorph! ! !GLMMorphicTextRenderer methodsFor: 'rendering' stamp: 'TudorGirba 9/20/2011 23:39'! textModelFor: aPresentation ^ GLMTextModel new text: aPresentation formatedDisplayValue; glamourPresentation: aPresentation! ! !GLMMorphicTextRenderer methodsFor: 'rendering' stamp: 'TudorGirba 3/24/2013 20:56'! textMorphForModel: aTextModel ^ (GLMPluggableTextMorph on: aTextModel text: #text accept: #accept:notifying: readSelection: #selection menu: #menu:shifted:) changedAction: [:aText| aText asString trimBoth ifNotEmpty: [aTextModel text: aText] ]; onKeyStrokeSend: #keystroke:from: to: aTextModel; layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); vResizing: #spaceFill; hResizing: #spaceFill; color: Color white; detachAllKeymapCategories; yourself! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/23/2011 14:06'! actOnMatchingPresentationsChanged: anAnnouncement paneMorph removeAllMorphs. self renderMorphFor: anAnnouncement pane. self renderer window fullBounds! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/23/2011 14:07'! buttonRowFrom: aCollectionOfButtons "Answer a new ok/cancel button row." |answer buttons e| buttons := aCollectionOfButtons. e := 0@0. buttons do: [:b | e := e max: b minExtent]. buttons do: [:b | b extent: e]. answer := Morph new color: Color transparent; changeTableLayout; cellInset: 8; listDirection: #leftToRight; listCentering: #bottomRight; hResizing: #spaceFill; vResizing: #shrinkWrap. buttons do: [:b | answer addMorphBack: b]. ^answer ! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/23/2011 14:11'! buttons ^ buttons! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'accessing' stamp: 'cyrilledelaunay 3/23/2011 14:12'! buttons: aCollectionOfButtons buttons := aCollectionOfButtons! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/23/2011 16:39'! newColumnWith: aCollectionOfMorphElements "use this method to create a new column in your block" |answer| answer := PanelMorph new hResizing: #spaceFill; vResizing: #spaceFill; fillStyle: Color transparent; "non pane color tracking" changeTableLayout; cellInset: 8; yourself. aCollectionOfMorphElements do: [:m | answer addMorphBack: m]. ^answer! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/23/2011 14:14'! render: aPane paneMorph := GLMMorphic containerMorph. aPane on: GLMMatchingPresentationsChanged send: #actOnMatchingPresentationsChanged: to: self. self renderMorphFor: aPane. ^ paneMorph! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 3/31/2011 17:13'! renderCompositiePresentation: aCompositePresentation paneMorph := GLMMorphic containerMorph. paneMorph addMorph: (self newColumnWith: { (self renderObject: aCompositePresentation). (self buttonRowFrom: self buttons) }) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1)); "addMorphBack: (self buttonRowFrom: self buttons) ; " adoptPaneColor: paneMorph paneColor. ^ paneMorph! ! !GLMMorphicValidatorPaneRenderer methodsFor: 'rendering' stamp: 'cyrilledelaunay 4/8/2011 12:07'! renderMorphFor: aPane paneMorph addMorph: ("self newColumnWith: {" (self renderObject: aPane presentations)". (self buttonRowFrom: self buttons) }") fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0.90)); addMorph: (self buttonRowFrom: self buttons) fullFrame: (LayoutFrame fractions: (0 @ 0.93 corner: 1 @ 1)); adoptPaneColor: paneMorph paneColor! ! !GLMMorphicWatcherRenderer commentStamp: '' prior: 34284112! This is a special widget renderer in that it will get to render multiple panes on the same container morph provided by a unique instance of the GLMWatcherWindow.! !GLMMorphicWatcherRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/28/2012 14:41'! actOnMatchingPresentationsChanged: anAnnouncement "whenever a relevant pane changes its presentations, we override the contents from the GLMWatcherWindow" GLMWatcherWindow uniqueInstance addContent: [ self renderObject: anAnnouncement pane presentations ]! ! !GLMMorphicWatcherRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/27/2012 01:47'! render: aPane "we just register for the announcement" aPane on: GLMMatchingPresentationsChanged send: #actOnMatchingPresentationsChanged: to: self ! ! !GLMMorphicWidgetRenderer class methodsFor: 'instance creation' stamp: 'tg 8/22/2010 20:20'! render: aPresentation from: aRenderer ^ self new renderer: aRenderer; render: aPresentation! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 3/24/2013 21:58'! installActionsOnModel: aMorphicModel fromPresentation: aPresentation aMorphicModel when: GLMMenuItemSelected do: [ :ann | ann action morphicActOn: aPresentation ]. aMorphicModel when: GLMKeyStroke do: [ :ann | ann action actOn: aPresentation ].! ! !GLMMorphicWidgetRenderer methodsFor: 'rendering' stamp: 'TudorGirba 3/24/2013 22:15'! installKeystrokeActionsOnMorph: aMorph fromPresentation: aPresentation aPresentation allActionsWithShortcuts do: [ :each | aMorph on: each shortcut command do: [ each actOn: aPresentation ] ]! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 11/28/2012 22:23'! menuIn: aMenuMorph for: aPresentation | subMenus targetMenuMorph subMenu | subMenus := Dictionary new. (aPresentation allActions select: [:each | each isMenu ]) do: [ :action | targetMenuMorph := action category notNil ifTrue: [ subMenus at: action category ifAbsentPut: [ subMenu := MenuMorph new. aMenuMorph add: action category subMenu: subMenu. subMenu ] ] ifFalse: [ aMenuMorph ]. (targetMenuMorph add: action title target: action selector: #morphicActOn: argument: aPresentation) icon: action icon; keyText: (action hasShortcut ifTrue: [ action shortcutAsString ] ifFalse: [ nil ]) ]. ^ aMenuMorph! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'tg 8/22/2010 23:52'! moreToolbarActions: noIconActions on: aBrowser | menuMorph | menuMorph := MenuMorph new. noIconActions do: [ :each | menuMorph add: each title target: each selector: #actOn: argument: aBrowser ]. ^ menuMorph! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/23/2011 12:49'! morph: aMorph withTitleOf: aPresentation | tabs | tabs := LazyTabGroupMorph new. tabs vResizing: #spaceFill; hResizing: #spaceFill; cornerStyle: (self theme tabGroupCornerStyleIn: nil); font: self theme labelFont. self flag: 'add a regular page instead of a lazy one'. self flag: 'handle the PresentationChanged announcement to update the label in the morph. The problem is that at the moment I do not know how to link to the label in the tabSelectorMorph'. tabs addLazyPage: [aMorph] label: (self titleOrIconOf: aPresentation in: tabs) toolbar: (self renderToolbarForPresentation: aPresentation inMorph: aMorph). tabs selectedPageIndex: 1. ^ tabs! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/31/2011 02:19'! morph: aMorph withTitleOrNilOf: aPresentation (aPresentation hasTitle or: [aPresentation hasTitleIcon]) ifFalse: [ "we render at least the toolbar" ^ self morph: aMorph withToolbarOf: aPresentation ]. ^ self morph: aMorph withTitleOf: aPresentation! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/31/2011 02:21'! morph: aMorph withToolbarOf: aPresentation | container offset dock | aPresentation hasActions ifFalse: [ ^ aMorph ]. container := GLMMorphic containerMorph. offset := 0. dock := self renderToolbarForPresentation: aPresentation inMorph: container. offset := dock minExtent y. container addMorph: dock fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0) offsets: (0 @ 0 corner: 0 @ offset)). container addMorph: aMorph fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1) offsets: (0 @ offset corner: 0 @ 0)). ^ container! ! !GLMMorphicWidgetRenderer methodsFor: 'rendering' stamp: 'tg 8/22/2010 20:17'! render: aPresentation ^ self subclassResponsibility ! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/5/2011 23:47'! renderObject: anObject ^ self renderer render: anObject ! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'EstebanLorenzano 4/20/2012 16:16'! renderToolbarForPresentation: aPresentation inMorph: aMorph | dock tools buttons noIconActions | dock := aMorph theme newToolDockingBarIn: aMorph. buttons := (aPresentation allActions select: [:each | each isButton ]) collect: [:each | (each renderGlamorouslyOn: self renderer) arguments: { aPresentation }; yourself ]. noIconActions := aPresentation allActions select: #isMenu. tools := aMorph theme newToolbarIn: aMorph for: buttons. noIconActions isEmpty ifFalse: [ | activeForm passiveForm menuButton | activeForm := GLMMorphicIcons toolbarMenuForm. passiveForm := GLMMorphicIcons toolbarMenuInactiveForm. menuButton := MultistateButtonMorph new extent: activeForm extent. menuButton extent: activeForm extent; activeEnabledOverUpFillStyle: (ImageFillStyle form: activeForm); passiveEnabledOverUpFillStyle: (ImageFillStyle form: activeForm); activeEnabledOverDownFillStyle: (ImageFillStyle form: passiveForm); passiveEnabledOverDownFillStyle: (ImageFillStyle form: passiveForm); addUpAction: [ | menu | menu := self menuIn: MenuMorph new for: aPresentation. menu popUpEvent: self currentEvent in: aMorph world ]; setBalloonText: 'Menu' translated. buttons do: [:each | dock addMorphBack: each ]. dock addMorphBack: menuButton. "isEmpty ifFalse: [dock addMorphBack: tools]" ] ifTrue: [ dock addAllMorphs: buttons ]. ^ dock! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/28/2011 19:20'! renderWithTitle: aPresentation | morph | morph := self renderObject: aPresentation. ^ self morph: morph withTitleOf: aPresentation! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/31/2011 02:19'! renderWithTitleOrNil: aPresentation | morph | morph := self renderObject: aPresentation. ^ self morph: morph withTitleOrNilOf: aPresentation! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 1/31/2011 02:20'! renderWithToolbar: aPresentation | presentationMorph | presentationMorph := self renderObject: aPresentation. ^ self morph: presentationMorph withToolbarOf: aPresentation! ! !GLMMorphicWidgetRenderer methodsFor: 'accessing' stamp: 'TudorGirba 1/5/2011 23:42'! renderer ^ renderer ifNil: [renderer := GLMMorphicRenderer new]! ! !GLMMorphicWidgetRenderer methodsFor: 'accessing' stamp: 'tg 8/22/2010 20:20'! renderer: anObject renderer := anObject! ! !GLMMorphicWidgetRenderer methodsFor: 'factory' stamp: 'tg 8/23/2010 00:02'! theme ^ UITheme current! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 8/23/2011 23:10'! titleOrIconOf: aPresentation in: container ^ aPresentation hasTitleIcon ifTrue: [ | image | image := self theme newImageIn: container form: aPresentation titleIconValue. aPresentation titleValue isNil ifFalse: [ image setBalloonText: aPresentation titleValue maxLineLength: 100 ]. image ] ifFalse: [ aPresentation titleValue ifNil: [''] ]! ! !GLMMorphicWidgetRenderer methodsFor: 'private' stamp: 'TudorGirba 4/14/2011 23:59'! titleOrIconOrNilOf: aPresentation in: container ^ aPresentation hasTitleIcon ifTrue: [ | image | image := self theme newImageIn: container form: aPresentation titleIconValue. aPresentation titleValue isNil ifFalse: [ image setBalloonText: aPresentation titleValue maxLineLength: 10 ] ] ifFalse: [ aPresentation hasTitle ifTrue: [ aPresentation titleValue ] ifFalse: [ nil ] ]! ! !GLMMorphicWindowRenderer commentStamp: '' prior: 34284340! This renders the top most browser or composite presentation in a window.! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'TudorGirba 2/15/2011 11:23'! actOnPresentationUpdated: ann self setLabelOf: window for: ann presentation! ! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'TudorGirba 3/3/2013 21:52'! handlePotentialStatusbarFor: aRenderable | statusbarMorph bottomOffset | bottomOffset := 0. aRenderable hasStatusbar ifTrue: [ statusbarMorph := GLMMorphicPaneWithoutTitleRenderer render: aRenderable statusbarPane from: self renderer. bottomOffset := (0 - (LabelMorph contents: 'XXX') minHeight) * 1.2. window addMorph: statusbarMorph fullFrame: (LayoutFrame fractions: (0 @ 1 corner: 1 @ 1) offsets: (2 @ bottomOffset corner: -2 @ 0)) ]. ^ bottomOffset! ! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'TudorGirba 5/19/2013 21:08'! render: aRenderable | dock offset bottomOffset | window := GLMSystemWindow new model: aRenderable. self installActionsOnModel: window fromPresentation: aRenderable . self installKeystrokeActionsOnMorph: window fromPresentation: aRenderable. self setLabelOf: window for: aRenderable. offset := 4. bottomOffset := 0. dock := self renderToolbarForPresentation: aRenderable inMorph: window. dock hResizing: #shrinkWrap. window toolbarBox: dock. bottomOffset := self handlePotentialStatusbarFor: aRenderable. window addMorph: (self renderObject: aRenderable) fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 1) offsets: (0 @ offset corner: 0 @ bottomOffset)). self setPotentialBackgroundColorFor: aRenderable. aRenderable on: GLMPresentationUpdated send: #actOnPresentationUpdated: to: self. aRenderable watcherPane notNil ifTrue: [ GLMMorphicWatcherRenderer render: aRenderable watcherPane from: self renderer ]. ^ window! ! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'tg 8/24/2010 22:06'! setLabelOf: window for: aRenderable window setLabel: (self titleFor: aRenderable).! ! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'TudorGirba 9/11/2011 21:59'! setPotentialBackgroundColorFor: aRenderable (self theme isKindOf: UIThemeWatery) ifFalse: [ aRenderable colorValue ifNotNil: [ window paneColor: aRenderable colorValue ] ]! ! !GLMMorphicWindowRenderer methodsFor: 'rendering' stamp: 'tg 8/24/2010 22:04'! titleFor: aRenderable ^ aRenderable titleValue ifNil: [ 'Glamorous Browser' ]! ! !GLMPortIdentifier commentStamp: '' prior: 34284472! This class is a simple data structure to be used for identifying a port by name.! !GLMPortIdentifier class methodsFor: 'instance creation' stamp: 'tg 10/25/2010 02:09'! defaultOriginOf: aPaneName ^ self new paneName: aPaneName; portName: self defaultOriginPortName! ! !GLMPortIdentifier class methodsFor: 'accessing' stamp: 'tg 10/25/2010 02:07'! defaultOriginPortName ^ #selection! ! !GLMPortIdentifier class methodsFor: 'instance creation' stamp: 'tg 10/25/2010 02:09'! defaultTargetOf: aPaneName ^ self new paneName: aPaneName; portName: self defaultTargetPortName! ! !GLMPortIdentifier class methodsFor: 'accessing' stamp: 'tg 10/25/2010 02:07'! defaultTargetPortName ^ #entity! ! !GLMPortIdentifier class methodsFor: 'instance creation' stamp: 'tg 11/3/2010 13:35'! pane: aPaneName port: aPortName ^ self new paneName: aPaneName; portName: aPortName! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 02:07'! asGlamourOriginIdentifier self portName isNil ifTrue: [self portName: self class defaultOriginPortName]. ^ self ! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 02:07'! asGlamourTargetIdentifier self portName isNil ifTrue: [self portName: self class defaultTargetPortName]. ^ self ! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 01:56'! paneName ^ paneName! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 01:56'! paneName: anObject paneName := anObject! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 01:56'! portName ^ portName! ! !GLMPortIdentifier methodsFor: 'accessing' stamp: 'tg 10/25/2010 01:56'! portName: anObject portName := anObject! ! !GLMPortReference commentStamp: 'tg 1/5/2010 22:18' prior: 34284616! A PortReference is used in Transmissions to bahavior that is specific to a Transmission instance.! !GLMOriginPortReference commentStamp: '' prior: 34284778! Used by BundleTransmission to annotate its originating ports whether they are active or passive. When a BundleTransmission consideres a port as active, the browser will trigger it when the corresponding port changes.! !GLMOriginPortReference methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! beActive active := true! ! !GLMOriginPortReference methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! bePassive active := false! ! !GLMOriginPortReference methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isActive ^active ifNil: [active := true]! ! !GLMOriginPortReference methodsFor: 'testing' stamp: ' 4/5/09 22:18'! isPassive ^self isActive not! ! !GLMOriginPortReference methodsFor: 'accessing' stamp: 'tg 1/5/2010 22:11'! transformation ^ transformation! ! !GLMOriginPortReference methodsFor: 'accessing' stamp: 'tg 1/5/2010 22:11'! transformation: anObject transformation := anObject! ! !GLMOriginPortReference methodsFor: 'accessing-convenience' stamp: 'tg 1/5/2010 22:11'! value ^ self transformation isNil ifTrue: [self port value] ifFalse: [self transformation value: self port value]! ! !GLMPortReference methodsFor: 'accessing' stamp: 'tg 1/5/2010 22:06'! port ^port! ! !GLMPortReference methodsFor: 'accessing' stamp: 'tg 1/5/2010 22:07'! port: aPort port := aPort! ! !GLMPortReference methodsFor: 'as yet unclassified' stamp: 'DamienCassou 7/19/2011 17:55'! postCopy port := port copy! ! !GLMPortReference methodsFor: 'printing' stamp: 'tg 1/13/2010 16:37'! printOn: aStream super printOn: aStream. aStream nextPut: Character space; nextPutAll: self identityHash printString; nextPutAll: ' ('. port printOn: aStream. aStream nextPut: $)! ! !GLMPortUpdater commentStamp: '' prior: 34285052! This is a strategy that populates a portSymbol with the result of evaluating valueBlock.! !GLMPortUpdater methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! glamourValueWithArgs: anArray (anArray first pane port: self portSymbol) value: (self valueBlock glamourValueWithArgs: anArray)! ! !GLMPortUpdater methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! portSymbol ^portSymbol! ! !GLMPortUpdater methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! portSymbol: anObject portSymbol := anObject! ! !GLMPortUpdater methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! valueBlock ^valueBlock! ! !GLMPortUpdater methodsFor: 'accessing' stamp: ' 4/5/09 22:18'! valueBlock: anObject valueBlock := anObject! ! !GLMRenderer commentStamp: 'tg 9/20/2009 12:43' prior: 34285200! A GLMRenderer is the abstract class for the renderer hierarchy. This should be subclassed for each rendering platform (e.g. Morphic)! !GLMMorphicRenderer commentStamp: 'tg 4/1/2010 07:11' prior: 34285398! This is the class responsible for the binding to Morphic. | browser | browser := GLMTabulator new. browser column: #one; column: #two. browser transmit to: #one; andShow: [:a | a list.]. browser transmit to: #two; from: #one; andShow: [ :a | a text.]. browser openOn: #(a b c d)! !GLMMorphicRenderer methodsFor: 'opening' stamp: 'TudorGirba 10/19/2013 03:48'! open: aRenderable window := GLMMorphicWindowRenderer render: aRenderable from: self. ^ window openInWorld ! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:31'! renderAccordionCompositePresentation: aCompositePresentation ^ GLMMorphicAccordionRenderer render: aCompositePresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'tg 8/24/2010 21:51'! renderAccumulator: aBrowser ^ GLMMorphicAccumulatorRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering actions' stamp: 'TudorGirba 11/28/2012 22:24'! renderAction: anAction ^(UITheme current newButtonIn: nil for: anAction getState: nil action: #morphicActOn: arguments: {} getEnabled: nil label: (AlphaImageMorph new image: anAction icon) help: (anAction title, Character tab asString, anAction shortcutAsString) trimBoth) valueOfProperty: #noBorder ifAbsentPut: [true]; "this is a hack to tell the GLMUITheme to not draw the border and the fill" valueOfProperty: #noFill ifAbsentPut: [true]; setProperty: #wantsKeyboardFocusNavigation toValue: false; "to disable the focus" yourself! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'EstebanLorenzano 4/20/2012 16:14'! renderActionListPresentation: anActionListPresentation ^GLMMorphicActionListRenderer render: anActionListPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'cyrilledelaunay 6/7/2011 17:01'! renderDashboard: aBrowser ^ GLMMorphicDashboardRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 9/3/2010 13:56'! renderDiffPresentation: aPresentation ^ GLMMorphicDiffRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 6/29/2012 09:47'! renderDropDownListPresentation: aDropListPresentation ^ GLMMorphicDropDownRenderer render: aDropListPresentation from: self ! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 2/4/2011 18:10'! renderDynamicPresentation: aPresentation ^ GLMMorphicDynamicRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'TudorGirba 1/2/2011 18:58'! renderExpander: aBrowser ^ GLMMorphicExpanderRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 4/12/2011 10:33'! renderEyeSeePresentation: aPresentation ^ GLMMorphicEyeSeeRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'TudorGirba 2/15/2011 18:07'! renderFinder: aBrowser ^ aBrowser hasFixedSizePanes ifTrue: [GLMMorphicFixedPanesFinderRenderer render: aBrowser from: self] ifFalse: [GLMMorphicVariablePanesFinderRenderer render: aBrowser from: self]! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 1/20/2011 21:53'! renderInputPresentation: aPresentation | morph | self flag: 'hook the cuis editor'. morph := GLMMorphic containerMorph. ^ morph! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 7/1/2011 23:15'! renderLabelPresentation: aLabelPresentation ^ GLMMorphicLabelRenderer render: aLabelPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:14'! renderListPresentation: aListPresentation ^ GLMMorphicListRenderer render: aListPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:12'! renderListingPresentation: aPresentation ^ GLMMorphicListingRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 1/13/2011 13:46'! renderMagrittePresentation: aMagrittePresentation ^ GLMMorphicMagritteRenderer render: aMagrittePresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/23/2010 00:22'! renderMondrianPresentation: aPresentation ^ GLMMorphicMondrianRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'EstebanLorenzano 10/6/2011 22:29'! renderMorphPresentation: aMorphPresentation ^ GLMMorphicMorphRenderer render: aMorphPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering' stamp: 'tg 8/24/2010 21:51'! renderPane: aPane ^ GLMMorphicPaneRenderer render: aPane from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 5/5/2012 14:41'! renderRoassalPresentation: aPresentation ^ GLMMorphicRoassalRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 6/3/2013 23:44'! renderRubricSmalltalkCodePresentation: aPresentation ^ GLMMorphicRubricSmalltalkCodeRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 6/2/2013 21:48'! renderRubricTextPresentation: aPresentation ^ GLMMorphicRubricTextRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 8/29/2011 23:51'! renderSmalltalkCodePresentation: aSmalltalkCodePresentation ^ GLMMorphicSmalltalkCodeRenderer render: aSmalltalkCodePresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'TudorGirba 4/3/2013 16:57'! renderSpecPresentation: aPresentation ^ GLMMorphicSpecRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:31'! renderStackedVerticallyCompositePresentation: aCompositePresentation ^ GLMMorphicVerticallyStackedRenderer render: aCompositePresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'tg 8/24/2010 21:50'! renderStacker: aBrowser ^ GLMMorphicStackerRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:33'! renderTabbedCompositePresentation: aCompositePresentation ^ GLMMorphicTabbedRenderer render: aCompositePresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:15'! renderTablePresentation: aPresentation ^ GLMMorphicTableRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'tg 8/24/2010 21:50'! renderTabulator: aBrowser ^ GLMMorphicTabulatorRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 20:22'! renderTextPresentation: aTextPresentation ^ GLMMorphicTextRenderer render: aTextPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering presentations' stamp: 'tg 8/22/2010 23:16'! renderTreePresentation: aPresentation ^ GLMMorphicTreeRenderer render: aPresentation from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'cyrilledelaunay 5/5/2011 12:03'! renderValidator: aBrowser | tmpValidatorRenderer | tmpValidatorRenderer := GLMMorphicValidatorRenderer new. aBrowser setSpecificAnnouncementActionsTo: tmpValidatorRenderer. ^ tmpValidatorRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'TudorGirba 4/12/2011 13:49'! renderWizard: aGLMWizard |tmpRenderer| tmpRenderer := GLMMorphicWizardRenderer new. aGLMWizard setSpecificAnnouncementActionsTo: tmpRenderer. ^ (tmpRenderer renderer: self) render: aGLMWizard! ! !GLMMorphicRenderer methodsFor: 'rendering browsers' stamp: 'TudorGirba 5/18/2012 22:29'! renderWrapper: aBrowser ^ GLMMorphicWrapperRenderer render: aBrowser from: self! ! !GLMMorphicRenderer methodsFor: 'accessing' stamp: 'tg 8/23/2010 00:33'! window ^ window! ! !GLMMorphicRenderer methodsFor: 'accessing' stamp: 'tg 8/23/2010 00:33'! window: anObject window := anObject! ! !GLMRenderer methodsFor: 'rendering' stamp: ' 4/5/09 22:18'! doOpen: aUI ^self subclassResponsibility! ! !GLMRenderer methodsFor: 'rendering' stamp: ' 4/5/09 22:18'! open: aRenderable ^self doOpen: (self render: aRenderable)! ! !GLMRenderer methodsFor: 'rendering' stamp: ' 4/5/09 22:18'! render: aRenderable ^aRenderable renderGlamorouslyOn: self! ! !GLMRenderer methodsFor: 'rendering' stamp: ' 4/5/09 22:18'! renderPane: aPane ^nil! ! !GLMRenderer methodsFor: 'rendering' stamp: 'tg 5/24/2009 19:30'! renderPresentation: aPresentation ^ nil! ! !GLMSTBrowserExample commentStamp: 'TudorGirba 1/4/2012 08:21' prior: 34285754! self new browser openOn: (RBBrowserEnvironment new forPackageNames: #('Glamour'))! !GLMSTBrowserExample methodsFor: 'accessing'! browser " self new browser openOn: (BrowserEnvironment new forPackageNames: #('Glamour')) " | browser | browser := GLMTabulator new. browser row: [ :row | row column: #category; column: #class; column: #protocol; column: #selector ]. browser row: #source. " categories " browser transmit to: #category; andShow: [ :a | self categoriesIn: a ]. browser transmit to: #class; from: #outer port: #entity; from: #category; andShow: [ :a | self classesIn: a ]. browser transmit to: #protocol; from: #outer port: #entity; from: #class; andShow: [ :a | self protocolsIn: a ]. browser transmit to: #selector; from: #outer port: #entity; from: #class; from: #protocol; andShow: [ :a | self methodsIn: a ]. browser transmit to: #source; from: #category; from: #class; from: #selector; andShow: [ :a | self sourceIn: a ]. ^ browser! ! !GLMSTBrowserExample methodsFor: 'accessing'! categoriesIn: a ^ a list display: [ :environment | environment categories ]! ! !GLMSTBrowserExample methodsFor: 'accessing'! classesIn: a a list title: 'Instance'; display: [ :environment :category | (environment classes select: [ :each | each isMeta not ]) select: [ :each | each category = category ] ]; sorted: [ :a1 :b | a1 name < b name ]; format: [ :class | class name ]. ^ a list title: 'Class'; display: [ :environment :category | (environment classes select: [ :each | each isMeta ]) select: [ :each | each theNonMetaClass category = category ] ]; sorted: [ :a1 :b | a1 name < b name ]; format: [ :class | class theNonMetaClass name ]! ! !GLMSTBrowserExample methodsFor: 'accessing' stamp: 'TudorGirba 10/4/2013 23:37'! complexityIn: a ^ a roassal title: 'Complexity'; useExplicitNotNil; painting: [ :view :category :class :selector | view nodeShape height: [ :model | model linesOfCode min: 50 max: 5 ]; width: [ :model | model instVarNames size + 5 ]; fillColor: [ :model | model = class ifTrue: [ Color red ] ifFalse: [ Color white ] ]. view nodes: (((Smalltalk organization listAtCategoryNamed: category) collect: [ :each | Smalltalk classNamed: each ]) reject: [ :each | each isTrait ]). view edgesFrom: [ :each | each superclass ]. view treeLayout ]; when: [ :category :class :selector | category notNil ]! ! !GLMSTBrowserExample methodsFor: 'accessing'! methodsIn: a a list useExplicitNotNil; when: [ :environment :class :protocol | class notNil and: [ protocol notNil ] ]; display: [ :environment :class :protocol | environment selectorsFor: protocol in: class ]; sorted. ^ a list useExplicitNotNil; when: [ :environment :class :protocol | class notNil and: [ protocol isNil ] ]; display: [ :environment :class :protocol | environment selectorsForClass: class ]; sorted! ! !GLMSTBrowserExample methodsFor: 'accessing'! protocolsIn: a ^ a list when: [ :environment :class | class notNil ]; display: [ :environment :class | environment protocolsFor: class ]; sorted! ! !GLMSTBrowserExample methodsFor: 'accessing'! sourceIn: a a text title: 'Source'; useExplicitNotNil; when: [ :category :class :selector | class notNil and: [ selector notNil ] ]; display: [ :category :class :selector | class sourceCodeAt: selector ifAbsent: [ String new ] ]. a text title: 'Source'; useExplicitNotNil; when: [ :category :class :selector | class notNil and: [ selector isNil ] ]; display: [ :category :class :selector | class definition ]. ^ self complexityIn: a! ! !GLMTableColumn commentStamp: 'TudorGirba 2/4/2011 21:14' prior: 34285905! This is a helper class for the TablePresentation. Instance Variables: title computation ! !GLMTableColumn methodsFor: 'accessing'! computation ^ computation! ! !GLMTableColumn methodsFor: 'accessing'! computation: anObject computation := anObject! ! !GLMTableColumn methodsFor: 'accessing'! title ^ title! ! !GLMTableColumn methodsFor: 'accessing'! title: anObject title := anObject! ! !GLMTableColumn methodsFor: 'accessing'! width ^ width ifNil: [200]! ! !GLMTableColumn methodsFor: 'accessing'! width: anObject width := anObject! ! !GLMTransmissionContext commentStamp: 'DamienCassou 7/9/2011 23:44' prior: 34286135! This class models the context in which a set of transmissions take place. In essence, it records all ports that were reached after an outside event. That is necessary for ensuring that transmissions do not get propagated forever. When the first transmission is triggered, a context is created and this context will then store all ports that any subsequent transmission touches. This info is used to break possible cycles Instance Variables ports: Collection of Ports! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'TudorGirba 7/21/2011 13:43'! addPort: aPort self ports add: aPort! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:26'! can: aPane announce: anAnnouncement ^ ((self forbiddenAnnouncements at: aPane ifAbsent: [Set new]) includes: anAnnouncement ) not! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:25'! canAnnounceMatchingPresentationsChanged: aPane ^ self can: aPane announce: GLMMatchingPresentationsChanged! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:23'! canAnnouncePresentationsChanged: aPane self can: aPane announce: GLMPresentationsChanged! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:21'! forbid: aPane toAnnounce: anAnnouncement (self forbiddenAnnouncements at: aPane ifAbsentPut: [Set new]) add: anAnnouncement! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:22'! forbidToAnnounceMatchingPresentationsChanged: aPane self forbid: aPane toAnnounce: GLMMatchingPresentationsChanged! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:22'! forbidToAnnouncePresentationsChanged: aPane self forbid: aPane toAnnounce: GLMPresentationsChanged! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:20'! forbiddenAnnouncements "forbiddenAnnouncements holds a dictionary in which the key is a pane and the value is a collection of announcements" ^ forbiddenAnnouncements ifNil: [forbiddenAnnouncements := IdentityDictionary new]! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/19/2009 00:19'! forbiddenAnnouncements: anObject forbiddenAnnouncements := anObject! ! !GLMTransmissionContext methodsFor: 'testing' stamp: 'TudorGirba 7/21/2011 13:46'! includesPort: aPort ^ self ports includes: aPort! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:33'! ports ^ ports ifNil: [ports := OrderedCollection new]! ! !GLMTransmissionContext methodsFor: 'accessing' stamp: 'tg 12/18/2009 23:32'! ports: anObject ports := anObject! ! !GLMTransmissionContext methodsFor: 'copying' stamp: 'TudorGirba 7/9/2011 23:54'! postCopy ports := ports copy! ! !GLMTransmissionContext methodsFor: 'printing' stamp: 'TudorGirba 7/21/2011 13:39'! printOn: aStream super printOn: aStream. aStream nextPut: $(. ports printOn: aStream. aStream nextPut: $) ! ! !GLMTransmissionStrategy commentStamp: 'tg 2/20/2010 14:45' prior: 34286679! The classes from this hierarchy define strategies for what should happen after the value have been set to the destination port.! !GLMNoStrategy commentStamp: 'tg 2/20/2010 14:53' prior: 34286868! This is the default strategy that does nothing (an implementation of the Null pattern)! !GLMNoStrategy methodsFor: 'transmitting' stamp: 'tg 2/20/2010 14:06'! transmitIn: aContext "do nothing else then was already done by the transmission"! ! !GLMPresentStrategy commentStamp: 'DamienCassou 7/9/2011 23:02' prior: 34287030! The abstract strategy that deals with setting of presentations on the pane of the destination port.! !GLMPresentIfNoneStrategy commentStamp: 'tg 2/20/2010 14:52' prior: 34287202! This strategy sets presentations only if none exits in the pane of the destination port.! !GLMPresentIfNoneStrategy methodsFor: 'transmitting' stamp: 'TudorGirba 3/15/2013 21:15'! transmitIn: aContext (self transmission destination hasPane and: [ self transmission destination pane presentations isEmpty]) ifTrue: [ self transmission destination pane notingPresentationChangeDo: [ self transmission destination pane clearIn: aContext. self transmission destination pane presentations: self presentations copy ] ]! ! !GLMPresentStrategy methodsFor: 'accessing-convenience' stamp: 'AndreiChis 5/30/2013 18:01'! addPresentation: aPresentation |currentPresentations| currentPresentations := self presentations. self presentationsFactory: [ :composite | currentPresentations do: [ :each | composite add: each ]. composite add: aPresentation copy ]! ! !GLMPresentStrategy methodsFor: 'accessing-convenience' stamp: 'tg 1/14/2010 17:07'! addPresentations: aCollection aCollection do: [:each | self addPresentation: each ]! ! !GLMPresentStrategy methodsFor: 'accessing' stamp: 'AndreiChis 8/11/2013 18:40'! presentations | presentations | presentations := GLMCompositePresentation new. self presentationsFactory glamourValue: ( presentations asGlamorousMultiValue, (self transmission origins collect: #value )). ^ presentations! ! !GLMPresentStrategy methodsFor: 'accessing' stamp: 'AndreiChis 5/30/2013 17:13'! presentations: anObject "self presentationsFactory: anObject "! ! !GLMPresentStrategy methodsFor: 'accessing' stamp: 'AndreiChis 5/29/2013 12:54'! presentationsFactory ^ presentationsFactory! ! !GLMPresentStrategy methodsFor: 'accessing' stamp: 'AndreiChis 5/29/2013 12:54'! presentationsFactory: anObject presentationsFactory := anObject! ! !GLMReplacePresentationsStrategy commentStamp: 'tg 2/20/2010 14:52' prior: 34287370! This strategy replaces the presentations from the pane of the destination port.! !GLMReplacePresentationsStrategy methodsFor: 'transmitting' stamp: 'tg 4/11/2010 23:36'! transmitIn: aContext "it is important for the destination to be set after the presentation, because when the presentation is a browser, we might forward the entity internally" self transmission destination hasPane ifTrue: [ self transmission destination pane notingPresentationChangeDo: [ self transmission destination pane clearIn: aContext. self transmission destination pane presentations: self presentations copy ]]. ! ! !GLMTransmissionStrategy class methodsFor: 'instance creation' stamp: 'tg 1/14/2010 15:45'! of: aTransmission ^ self new transmission: aTransmission; yourself! ! !GLMTransmissionStrategy methodsFor: 'accessing' stamp: 'tg 1/14/2010 16:53'! addPresentation: aPresentation "do nothing by default"! ! !GLMTransmissionStrategy methodsFor: 'accessing' stamp: 'tg 1/14/2010 17:07'! addPresentations: aCollection "do nothing by default"! ! !GLMTransmissionStrategy methodsFor: 'accessing' stamp: 'tg 1/14/2010 17:11'! presentations ^ OrderedCollection new! ! !GLMTransmissionStrategy methodsFor: 'accessing' stamp: 'tg 1/14/2010 15:44'! transmission ^ transmission! ! !GLMTransmissionStrategy methodsFor: 'accessing' stamp: 'tg 1/14/2010 15:44'! transmission: anObject transmission := anObject! ! !GLMTransmissionStrategy methodsFor: 'transmitting' stamp: 'tg 2/20/2010 14:05'! transmitIn: aContext "override this method to add the desired semantics" self subclassResponsibility! ! !GLMUIThemeExtraIcons commentStamp: 'TudorGirba 1/30/2011 22:55' prior: 34287526! This class offers a number of extra icons that work with the Glamorous Theme.! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousAccept ^ self icons at: #glamorousAccept ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 33554432 2969567232 4278190080 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 50331648 2969567232 4143972352 4043309056 973078528 16777215 16777215 16777215 16777215 16777215 16777215 16777215 536870912 16777215 16777215 50331648 2969567232 4143972352 4110417920 922746880 16777215 16777215 16777215 16777215 16777215 16777215 184549376 3758096384 4278190080 603979776 50331648 2969567232 4143972352 4110417920 922746880 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2365587456 4261412864 3976200192 3137339392 4143972352 4110417920 922746880 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 100663296 3405774848 4227858432 4261412864 4143972352 922746880 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 167772160 4177526784 4278190080 1375731712 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 167772160 671088640 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousAdd ^ self icons at: #glamorousAdd ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousAlarm ^ self icons at: #glamorousAlarm ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777216 436207616 16777215 16777215 16777215 402653184 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 100663296 3003121664 2399141888 16777215 16777215 16777215 2315255808 2969567232 100663296 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1442840576 2097152000 1644496133 3122733345 3625852446 3122733345 1644496133 2113929216 1526726656 16777215 16777215 16777215 16777215 16777215 16777215 16777215 553648128 3171749133 4030939971 4289440683 4291282887 4289440683 4030939971 2133469738 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1594361864 4129761063 4291546059 4291546059 4291546059 4291546059 4291546059 4030939971 1594361864 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3122733345 4289440683 4291546059 4291546059 4291546059 4291546059 4291546059 4289440683 3122733345 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3625852446 4291282887 4291546059 4291546059 4291546059 4291546059 4291546059 4291282887 3625852446 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3122733345 4289440683 4291546059 4291546059 4291546059 4291546059 4291546059 4289440683 3122733345 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1594361864 4081205826 4291546059 4291546059 4291546059 4291546059 4291546059 4163315495 1594361864 16777215 16777215 16777215 16777215 16777215 16777215 16777215 536870912 4194961930 4129761063 4289440683 4291282887 4289440683 4030939971 4194961930 520093696 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1979711488 1056964608 1594361864 3122733345 3625852446 3122733345 1594361864 1073741824 1979711488 16777215 16777215 16777215 16777215 16777215 16777215 16777215 520093696 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousBookmark ^ self icons at: #glamorousBookmark ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3321888768 4009754624 4194304000 3909091328 3254779904 2130706432 251658240 2147483648 3254779904 3909091328 4194304000 4009754624 3321888768 16777215 16777215 16777215 4278190080 285212672 33554432 335544320 1157627904 3456106496 4278190080 3422552064 1157627904 335544320 33554432 285212672 4278190080 16777215 16777215 16777215 4261412864 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4261412864 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 4278190080 1946157056 2181038080 1862270976 1191182336 268435456 4278190080 268435456 1191182336 1862270976 2181038080 1946157056 4278190080 16777215 16777215 16777215 1862270976 2348810240 2063597568 2399141888 3221225472 4278190080 4278190080 4278190080 3221225472 2399141888 2063597568 2348810240 1862270976 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 637534208 4278190080 654311424 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousBrowse ^ self icons at: #glamorousBrowse ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2248146944 2113929216 2130706432 2113929216 2113929216 2130706432 2113929216 2130706432 2130706432 2113929216 3305111552 3388997632 788529152 16777215 16777215 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3271557120 2281701376 553648128 16777215 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1996488704 687865856 2986344448 721420288 16777215 2130706432 16777215 16777215 16777215 1056964608 2130706432 2130706432 2130706432 2130706432 2130706432 1056964608 2113929216 1996488704 2952790016 3976200192 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3355443200 16777215 2130706432 16777215 16777215 16777215 1056964608 2130706432 2130706432 2130706432 2130706432 2130706432 1056964608 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 1056964608 1073741824 2130706432 2130706432 2130706432 2130706432 1073741824 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 1056964608 1073741824 2130706432 2130706432 2130706432 2130706432 1073741824 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 1056964608 1073741824 2130706432 2130706432 2130706432 2130706432 1073741824 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 16777215 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 16777215 2113929216 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2130706432 2113929216) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousBug ^ self icons at: #glamorousBug ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1224736768 503316480 16777215 1224736768 503316480 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 268435456 4278190080 4278190080 2181038080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2734686208 4278190080 4177526784 4278190080 2365587456 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 150994944 4278190080 4278190080 4278190080 4278190080 4043309056 150994944 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2634746635 4278190080 4283190348 4286216826 4283190348 4278190080 1478895142 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2450065673 4278190080 4293454056 4294967295 4294967295 4294967295 4293454056 4179171609 2450065673 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3976923915 4292532954 4294967295 4294967295 4294967295 4294967295 4294967295 4292532954 3976923915 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3976923915 4292532954 4294967295 4294967295 4294967295 4294967295 4294967295 4292532954 3976923915 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2450065673 4179237402 4293388263 4294967295 4294967295 4294967295 4293388263 4278190080 2450065673 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2685078283 4278190080 4065349712 4202462332 4065349712 4278190080 2282819857 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 469762048 1543503872 2147483648 1543503872 469762048 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousCancel ^ self icons at: #glamorousCancel ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 587202560 2348810240 234881024 16777215 318767104 939524096 369098752 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3925868544 4127195136 2801795072 201326592 3472883712 4093640704 2466250752 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 436207616 4127195136 4143972352 3992977408 4143972352 3959422976 570425344 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1157627904 4244635648 4261412864 4160749568 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 184549376 3472883712 4160749568 4261412864 4160749568 2801795072 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3472883712 4244635648 3959422976 1442840576 4110417920 4227858432 1493172224 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1895825408 3976200192 520093696 16777215 1157627904 4160749568 1258291200 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 520093696 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousDown ^ self icons at: #glamorousDown ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 956301312 1073741824 1073741824 4278190080 4278190080 1073741824 1073741824 956301312 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2852126720 4278190080 4278190080 4278190080 4278190080 2852126720 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 3640655872 4278190080 4278190080 3640655872 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 4127195136 4127195136 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousEdit ^ self icons at: #glamorousEdit ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2248146944 4278190080 570425344 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2315255808 3456106496 1593835520 3875536896 687865856 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2315255808 3456106496 301989888 16777215 1509949440 3875536896 687865856 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2315255808 3456106496 301989888 16777215 16777215 218103808 3003121664 2634022912 16777215 16777215 16777215 16777215 16777215 16777215 16777215 989855744 3070230528 50331648 16777215 16777215 301989888 3489660928 2281701376 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1862270976 2600468480 16777215 16777215 301989888 3489660928 2281701376 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3103784960 1358954496 67108864 1140850688 3640655872 2281701376 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 150994944 4278190080 2952790016 4194304000 4278190080 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 2449473536 1560281088 352321536 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousExample ^ self icons at: #glamorousExample ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1291845632 1593835520 16777215 16777215 16777215 1593835520 3439329280 2667577344 2566914048 83886080 16777215 83886080 2365587456 3221225472 3087007744 3422552064 2449473536 2785017856 16777215 16777215 1090519040 4278190080 1409286144 16777215 3305111552 2214592512 16777215 1677721600 4278190080 1275068416 150994944 4160749568 2550136832 16777215 16777215 16777215 2634022912 4278190080 1795162112 1375731712 3456106496 3321888768 16777215 1879048192 4278190080 1124073472 100663296 4110417920 2969567232 16777215 16777215 16777215 2835349504 4278190080 1543503872 989855744 989855744 889192448 16777215 218103808 3422552064 3472883712 2801795072 3405774848 654311424 16777215 16777215 16777215 1694498816 4278190080 1728053248 16777215 33554432 1795162112 16777215 1207959552 2298478592 419430400 251658240 33554432 16777215 16777215 16777215 16777215 33554432 2415919104 3992977408 2483027968 2483027968 704643072 16777215 1073741824 4127195136 4244635648 4278190080 4227858432 3238002688 83886080 16777215 16777215 16777215 16777215 100663296 318767104 16777215 16777215 16777215 1291845632 2785017856 1795162112 1526726656 1711276032 3690987520 1006632960 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1962934272 2701131776 939524096 889192448 1577058304 2885681152 33554432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 687865856 1291845632 1308622848 838860800 16777216 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousGrayCircle ^ self icons at: #glamorousGrayCircle ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 109084800 2274464145 3885142674 3885142674 2274464145 109084800 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2274464145 4287795858 4287795858 4287795858 4287795858 2274464145 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3885142674 4287795858 4287795858 4287795858 4287795858 3885142674 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3885142674 4287795858 4287795858 4287795858 4287795858 3885142674 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2274464145 4287795858 4287795858 4287795858 4287795858 2274464145 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 109084800 2274464145 3885142674 3885142674 2274464145 109084800 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousGreenCircle ^ self icons at: #glamorousGreenCircle ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 100696064 2264962304 3875575296 3875575296 2264962304 100696064 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2264962304 4278228736 4278228736 4278228736 4278228736 2264962304 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3875575296 4278228736 4278228736 4278228736 4278228736 3875575296 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3875575296 4278228736 4278228736 4278228736 4278228736 3875575296 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2264962304 4278228736 4278228736 4278228736 4278228736 2264962304 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 100696064 2264962304 3875575296 3875575296 2264962304 100696064 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousHelp ^ self icons at: #glamorousHelp ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 167772160 117440512 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777216 3489660928 3003121664 4278190080 3003121664 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 452984832 4278190080 352321536 1778384896 4278190080 536870912 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 452984832 4278190080 1442840576 1442840576 4278190080 637534208 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 285212672 16777215 3741319168 4278190080 33554432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 637534208 4278190080 167772160 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2348810240 452984832 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 872415232 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 285212672 4278190080 3489660928 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 285212672 4278190080 3489660928 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 33554432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousInspect ^ self icons at: #glamorousInspect ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777216 4009754624 2566914048 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 167772160 4278190080 4009754624 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 117440512 33554432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2147483648 2785017856 2348810240 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 67108864 4278190080 3741319168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3489660928 3741319168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3489660928 3741319168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3489660928 3741319168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2566914048 4278190080 4278190080 2785017856 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousInto ^ self icons at: #glamorousInto ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1258291200 4278190080 4278190080 4278190080 4278190080 4278190080 1258291200 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 251658240 4009754624 4278190080 4278190080 4278190080 4009754624 251658240 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1442840576 4076863488 4278190080 4076863488 1459617792 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3238002688 4177526784 3254779904 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 536870912 3992977408 536870912 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousLeft ^ self icons at: #glamorousLeft ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 956301312 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 2852126720 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 3640655872 4278190080 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 4127195136 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 4127195136 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 3640655872 4278190080 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 2852126720 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 956301312 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousLeftSide ^ self icons at: #glamorousLeftSide ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousOpen ^ self icons at: #glamorousOpen ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 16777215 16777215 16777215 4143972352 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 1208683275 16777215 4278190080 16777215 16777215 16777215 2600929031 4181934915 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4286479998 4093903876 201326592 4278190080 16777215 16777215 16777215 520093696 4144301317 4287203721 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4096667182 1996620290 4278190080 16777215 16777215 16777215 16777215 2869364487 4283058762 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4286085240 4026860805 4278190080 16777215 16777215 16777215 16777215 704643072 4278650631 4287466893 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4287795858 4079363622 4278190080 16777215 16777215 16777215 16777215 16777215 4262005001 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261610243 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousOver ^ self icons at: #glamorousOver ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1258291200 251658240 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4043309056 1509949440 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4093640704 3355443200 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4194304000 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4093640704 3355443200 570425344 16777215 16777215 16777215 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4261412864 16777215 4278190080 4026531840 1509949440 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 1258291200 251658240 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousPlay ^ self icons at: #glamorousPlay ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4110417920 1879048192 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4076863488 3456106496 603979776 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4227858432 4110417920 1895825408 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4076863488 3456106496 603979776 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4194304000 4009754624 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4076863488 3456106496 570425344 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4227858432 4110417920 1895825408 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4076863488 3472883712 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4110417920 1895825408 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRedCircle ^ self icons at: #glamorousRedCircle ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 114622464 2279547942 3890160678 3890160678 2279547942 114622464 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2279547942 4292879654 4292879654 4292879654 4292879654 2279547942 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3890160678 4292879654 4292879654 4292879654 4292879654 3890160678 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3890160678 4292879654 4292879654 4292879654 4292879654 3890160678 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2279547942 4292879654 4292879654 4292879654 4292879654 2279547942 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 114622464 2279547942 3890160678 3890160678 2279547942 114622464 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRedo ^ self icons at: #glamorousRedo ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 956301312 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 2852126720 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 4278190080 3640655872 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4127195136 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4127195136 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 1073741824 4278190080 4278190080 3640655872 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 1073741824 4278190080 2852126720 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 956301312 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRefresh ^ self icons at: #glamorousRefresh ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 3875536896 3036676096 1660944384 16777216 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 3221225472 402653184 16777215 16777215 16777215 16777215 16777215 687865856 4009754624 704643072 16777215 16777215 16777215 402653184 1476395008 3791650816 4278190080 3154116608 33554432 16777215 16777215 16777215 167772160 3758096384 4227858432 3791650816 167772160 16777215 16777215 16777215 16777215 301989888 3808428032 4278190080 1694498816 16777215 16777215 16777215 2801795072 4127195136 4278190080 4110417920 2835349504 16777215 16777215 16777215 16777215 16777215 1493172224 4278190080 2986344448 16777215 16777215 1593835520 4110417920 4278190080 4278190080 4278190080 4093640704 1627389952 16777215 16777215 16777215 16777215 369098752 4278190080 3992977408 16777215 16777215 4127195136 4278190080 4278190080 4278190080 4278190080 4278190080 4127195136 16777215 16777215 16777215 16777215 469762048 4278190080 4076863488 16777215 16777215 16777215 16777215 3355443200 4278190080 1509949440 16777215 16777215 16777215 16777215 16777215 16777215 1493172224 4278190080 3338665984 16777215 16777215 16777215 16777215 1778384896 4278190080 3808428032 335544320 16777215 16777215 16777215 16777215 335544320 3774873600 4278190080 1577058304 16777215 16777215 16777215 16777215 33554432 3120562176 4278190080 3774873600 1493172224 469762048 369098752 1509949440 3808428032 4278190080 3271557120 16777215 16777215 16777215 16777215 16777215 16777215 369098752 3271557120 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3120562176 369098752 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777216 1577058304 3338665984 4076863488 4093640704 3355443200 1778384896 33554432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRemove ^ self icons at: #glamorousRemove ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2130706432 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 2130706432 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRestart ^ self icons at: #glamorousRestart ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 721420288 1073741824 855638016 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2717908992 4278190080 3724541952 16777215 16777215 16777215 16777215 16777215 654311424 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2835349504 4278190080 3640655872 16777215 16777215 16777215 822083584 3623878656 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2936012800 4278190080 3523215360 16777215 402653184 2952790016 4177526784 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3053453312 4278190080 3388997632 16777215 4278190080 4227858432 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3154116608 4278190080 3271557120 16777215 3053453312 4160749568 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3271557120 4278190080 3154116608 16777215 16777215 704643072 3422552064 4194304000 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 3388997632 4278190080 3053453312 16777215 16777215 16777215 16777215 1291845632 2885681152 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 1073741824 805306368 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRight ^ self icons at: #glamorousRight ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 956301312 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 2852126720 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 4278190080 3640655872 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4127195136 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4127195136 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 4278190080 3640655872 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1073741824 4278190080 2852126720 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 956301312 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousRightSide ^ self icons at: #glamorousRightSide ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4261412864) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousSearch ^ self icons at: #glamorousSearch ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 989855744 3019898880 3875536896 3875536896 3019898880 989855744 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2046820352 4244635648 4278190080 4278190080 4278190080 4278190080 4244635648 2046820352 16777215 16777215 16777215 16777215 16777215 16777215 16777215 989855744 4244635648 4177526784 2013265920 402653184 402653184 2013265920 4177526784 4244635648 989855744 16777215 16777215 16777215 16777215 16777215 16777215 3019898880 4278190080 2013265920 16777215 16777215 16777215 16777215 2013265920 4278190080 3019898880 16777215 16777215 16777215 16777215 16777215 16777215 3875536896 4278190080 402653184 16777215 16777215 16777215 16777215 402653184 4278190080 3875536896 16777215 16777215 16777215 16777215 16777215 16777215 3875536896 4278190080 402653184 16777215 16777215 16777215 16777215 402653184 4278190080 3875536896 16777215 16777215 16777215 16777215 16777215 16777215 3019898880 4278190080 2013265920 16777215 16777215 16777215 16777215 2013265920 4278190080 3019898880 16777215 16777215 16777215 16777215 16777215 16777215 989855744 4244635648 4177526784 2013265920 402653184 402653184 2080374784 4211081216 4278190080 1644167168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2046820352 4244635648 4278190080 4278190080 4278190080 4278190080 4261412864 4278190080 4060086272 822083584 16777215 16777215 16777215 16777215 16777215 16777215 16777215 989855744 3019898880 3875536896 3875536896 3036676096 4110417920 4278190080 4278190080 4060086272 83886080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 805306368 4060086272 4278190080 3992977408 2281701376 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 989855744 4278190080 1476395008 150994944 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 553648128 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousSpawn ^ self icons at: #glamorousSpawn ifAbsentPut: [(Form extent: (16@18) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 587202560 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 1979711488 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 503316480 4278190080 3992977408 2919235584 184549376 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 754974720 2852126720 3909091328 4278190080 4278190080 4278190080 4060086272 3674210304 620756992 16777215 16777215 16777215 16777215 16777215 16777215 1711276032 4143972352 4278190080 4278190080 3825205248 4278190080 4278190080 4278190080 4127195136 1912602624 16777215 16777215 16777215 16777215 16777215 973078528 4244635648 4261412864 2399141888 452984832 16777215 4278190080 4278190080 4026531840 2751463424 268435456 16777215 16777215 16777215 16777215 16777215 3556769792 4278190080 2046820352 16777215 16777215 16777215 4278190080 4060086272 1778384896 16777215 16777215 16777215 16777215 16777215 16777215 469762048 4278190080 3858759680 67108864 16777215 16777215 16777215 3590324224 1006632960 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1308622848 4278190080 2969567232 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1426063360 3758096384 2315255808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousThrough ^ self icons at: #glamorousThrough ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 1258291200 251658240 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4009754624 1459617792 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4076863488 3254779904 536870912 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4177526784 3992977408 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4076863488 3238002688 536870912 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4009754624 1442840576 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 1258291200 251658240 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4261412864 4278190080 4261412864 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousUndo ^ self icons at: #glamorousUndo ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 956301312 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 2852126720 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 3640655872 4278190080 4278190080 1073741824 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 4127195136 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 4127195136 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 3640655872 4278190080 4278190080 1073741824 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 2852126720 4278190080 1073741824 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 956301312 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousUp ^ self icons at: #glamorousUp ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1627389952 1627389952 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 771751936 4127195136 4127195136 771751936 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 218103808 3640655872 4278190080 4278190080 3640655872 218103808 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 2852126720 4278190080 4278190080 4278190080 4278190080 2852126720 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1828716544 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 1828716544 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 956301312 1073741824 1073741824 4278190080 4278190080 1073741824 1073741824 956301312 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousZoomIn ^ self icons at: #glamorousZoomIn ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1644167168 3036676096 3875536896 3875536896 3036676096 1644167168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 419430400 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 419430400 16777215 16777215 16777215 16777215 16777215 16777215 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 16777215 16777215 16777215 16777215 16777215 1644167168 4278190080 4278190080 4278190080 4278190080 16777215 16777215 4278190080 4278190080 4278190080 4278190080 1644167168 16777215 16777215 16777215 16777215 3036676096 4278190080 4278190080 4278190080 4278190080 16777215 16777215 4278190080 4278190080 4278190080 4278190080 3036676096 16777215 16777215 16777215 16777215 3875536896 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 3875536896 16777215 16777215 16777215 16777215 3875536896 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 3875536896 16777215 16777215 16777215 16777215 3036676096 4278190080 4278190080 4278190080 4278190080 16777215 16777215 4278190080 4278190080 4278190080 4278190080 3036676096 16777215 16777215 16777215 16777215 1644167168 4278190080 4278190080 4278190080 4278190080 16777215 16777215 4278190080 4278190080 4278190080 4278190080 1644167168 16777215 16777215 16777215 16777215 16777215 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 16777215 16777215 16777215 16777215 16777215 16777215 419430400 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 419430400 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1644167168 3036676096 3875536896 3875536896 3036676096 1644167168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'icons' stamp: 'TudorGirba 6/21/2013 11:58'! glamorousZoomOut ^ self icons at: #glamorousZoomOut ifAbsentPut: [(Form extent: (16@16) depth: 32 fromArray: #( 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1644167168 3036676096 3875536896 3875536896 3036676096 1644167168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 419430400 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 419430400 16777215 16777215 16777215 16777215 16777215 16777215 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 16777215 16777215 16777215 16777215 16777215 1644167168 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 1644167168 16777215 16777215 16777215 16777215 3036676096 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3036676096 16777215 16777215 16777215 16777215 3875536896 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 3875536896 16777215 16777215 16777215 16777215 3875536896 4278190080 4278190080 16777215 16777215 16777215 16777215 16777215 16777215 4278190080 4278190080 3875536896 16777215 16777215 16777215 16777215 3036676096 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3036676096 16777215 16777215 16777215 16777215 1644167168 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 1644167168 16777215 16777215 16777215 16777215 16777215 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 16777215 16777215 16777215 16777215 16777215 16777215 419430400 3137339392 4278190080 4278190080 4278190080 4278190080 4278190080 4278190080 3137339392 419430400 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 1644167168 3036676096 3875536896 3875536896 3036676096 1644167168 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215 16777215) offset: (0@0))]! ! !GLMUIThemeExtraIcons class methodsFor: 'utils' stamp: 'TudorGirba 1/31/2011 00:16'! icons ^ icons ifNil: [icons := Dictionary new] ! ! !GLMUIThemeExtraIcons class methodsFor: 'utils' stamp: 'TudorGirba 6/21/2013 11:57'! importIcons "self importIcons" | wantedIcons | self resetIcons. wantedIcons := #( 'glamorousInspect' 'glamorousExample' 'glamorousHelp' 'glamorousSearch' 'glamorousAccept' 'glamorousCancel' 'glamorousBrowse' 'glamorousAdd' 'glamorousRemove' 'glamorousUp' 'glamorousDown' 'glamorousLeft' 'glamorousRight' 'glamorousEdit' 'glamorousAlarm' 'glamorousRedCircle' 'glamorousGreenCircle' 'glamorousGrayCircle' 'glamorousUndo' 'glamorousRedo' 'glamorousPlay' 'glamorousRestart' 'glamorousOver' 'glamorousInto' 'glamorousThrough' 'glamorousBookmark' 'glamorousOpen' 'glamorousRefresh' 'glamorousSpawn' 'glamorousBug' 'glamorousLeftSide' 'glamorousRightSide' 'glamorousZoomIn' 'glamorousZoomOut'). (Smalltalk at: #MooseScripts) importIcons: wantedIcons fromFolder: 'icons' inClass: self category: 'icons'! ! !GLMUIThemeExtraIcons class methodsFor: 'utils' stamp: 'TudorGirba 1/31/2011 00:16'! resetIcons icons := nil! ! !GLMUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:30' prior: 34287674! GLMUpdateAction is used for controlling the updating of a presentation when an announcement. is sent by the announcerObjects. Instance Variables: condition presentation announcement announcerObjects <(Collection of: Objects)> transformation ! !GLMMultipleUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:31' prior: 34288057! This class simply specifies that the updating announcement could come from any of the objects in the announcer objects collection.! !GLMMultipleUpdateAction methodsFor: 'public' stamp: 'tg 5/3/2010 01:18'! computeAnnouncerObjects ^ self transformation glamourValue: self presentation entity! ! !GLMSingleUpdateAction commentStamp: 'TudorGirba 1/7/2011 07:31' prior: 34288264! This class specifies that the updating announcement should come only from the single announcer object.! !GLMSingleUpdateAction methodsFor: 'public' stamp: 'TudorGirba 7/1/2011 23:59'! computeAnnouncerObjects self flag: 'We catch the error because if there is a problem in the computation of the announcer object, we still want to be able to continue the execution'. ^ OrderedCollection with: ([self transformation glamourValue: self presentation entity] on: Error do: [:e | self presentation entity. e resume])! ! !GLMUpdateAction methodsFor: 'announcement handling' stamp: 'TudorGirba 2/15/2011 10:40'! actOn: anAnnouncement | allowedToTrigger | allowedToTrigger := self condition glamourValue: ( anAnnouncement asGlamorousMultiValue, self presentation entity asGlamorousMultiValue). allowedToTrigger ifTrue: [ self presentation update ]! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:50'! announcement ^ announcement! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:50'! announcement: anObject announcement := anObject! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/3/2010 00:19'! announcerObjects ^ announcerObjects := self computeAnnouncerObjects ifNil: [OrderedCollection new]! ! !GLMUpdateAction methodsFor: 'public' stamp: 'tg 5/3/2010 00:12'! computeAnnouncerObjects self subclassResponsibility! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:46'! condition ^ condition! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:46'! condition: anObject condition := anObject! ! !GLMUpdateAction methodsFor: 'initialize-release' stamp: 'tg 5/24/2010 17:19'! initialize super initialize. condition := true! ! !GLMUpdateAction methodsFor: 'copying' stamp: 'tg 5/3/2010 01:19'! postCopy super postCopy. announcerObjects := nil! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:46'! presentation ^ presentation! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/2/2010 23:46'! presentation: anObject presentation := anObject! ! !GLMUpdateAction methodsFor: 'public' stamp: 'EstebanLorenzano 6/16/2011 15:23'! registerInPresentation self announcerObjects do: [: announcerObject | announcerObject notNil ifTrue: [ (announcerObject on: self announcement send: #actOn: to: self) makeWeak. "we remember the announcer object to be able to unregister from it when the presentation goes away" self presentation registeredAnnouncers add: announcerObject ] ]! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/3/2010 01:18'! transformation ^ transformation! ! !GLMUpdateAction methodsFor: 'accessing' stamp: 'tg 5/3/2010 01:18'! transformation: anObject transformation := anObject! ! !GLMUpdateAction methodsFor: 'public' stamp: 'HenrikSperreJohansen 3/12/2011 11:59'! unregisterFromAllAnnouncements self announcerObjects do: [:each | [each unsubscribe: self] on: Error do: [:e | e resume]] ! ! !ManifestRoassal class methodsFor: 'meta data' stamp: 'AlexandreBergel 5/7/2013 18:36'! rejectClasses ^ #()! ! !ManifestRoassal class methodsFor: 'meta data' stamp: 'AlexandreBergel 5/7/2013 18:36'! rejectRules ^ #()! ! !ManifestRoassalMorphic class methodsFor: 'meta data' stamp: 'AlexandreBergel 5/7/2013 18:36'! rejectClasses ^ #()! ! !ManifestRoassalMorphic class methodsFor: 'meta data' stamp: 'AlexandreBergel 5/7/2013 18:36'! rejectRules ^ #()! ! !Object methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! asGlamorousArray ^Array with: self! ! !Object methodsFor: '*Glamour-Helpers' stamp: 'tg 9/9/2009 01:02'! asGlamorousMultiValue ^ GLMMultiValue with: self! ! !Object methodsFor: '*petitparser-core-converting' stamp: 'lr 12/18/2011 15:58'! asParser "Answer a parser accepting the receiving object." ^ PPPredicateObjectParser expect: self! ! !Object methodsFor: '*collectionextensions' stamp: 'simondenier 2/4/2011 22:57'! deepFlattenInto: stream stream nextPut: self! ! !Object methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! glamourValue: anObject | args | args := anObject asGlamorousArray. ^self glamourValueWithArgs: args! ! !Object methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! glamourValueWithArgs: anArray ^self! ! !Object methodsFor: '*petitparser-core-testing' stamp: 'lr 2/7/2010 20:54'! isPetitFailure ^ false! ! !Object methodsFor: '*petitparser-core-testing' stamp: 'lr 8/6/2010 16:44'! isPetitParser ^ false! ! !Object methodsFor: '*Glamour-Helpers' stamp: ' 4/5/09 22:18'! renderGlamorouslyOn: aRenderer ^aRenderer renderObject: self! ! !Object methodsFor: '*roassal-core'! roValue: anArgument ^ self! ! !PPCharSetPredicate class methodsFor: 'instance creation' stamp: 'lr 8/25/2010 11:05'! on: aBlock ^ self basicNew initializeOn: aBlock! ! !PPCharSetPredicate methodsFor: 'initialization' stamp: 'lr 8/30/2010 12:19'! initializeOn: aBlock block := aBlock. classification := Array new: 255. 1 to: classification size do: [ :index | classification at: index put: (block value: (Character value: index)) ]! ! !PPCharSetPredicate methodsFor: 'evaluating' stamp: 'lr 8/30/2010 12:19'! value: aCharacter | index | index := aCharacter asInteger. index == 0 ifTrue: [ ^ block value: aCharacter ]. index > 255 ifTrue: [ ^ block value: aCharacter ]. ^ classification at: index! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'lr 1/30/2013 19:26'! browseClassesOn: aBrowser aBrowser tree title: 'Grammars'; format: [ :class | class name ]; children: [ :class | self subclassesOf: class ]; selectionAct: [ | className | className := UIManager default request: 'Class name' initialAnswer: '' title: 'New Parser'. className isNil ifFalse: [ PPRefactoringUtils new performRefactoring: (PPAddParserRefactoring name: className asSymbol category: #ParserExample superclass: self selectedClass). self selectedClass: (self class environment classNamed: className) ] ] on: $n entitled: 'New ... (n)'; selectionAct: [ | superclass | superclass := self selectedClass superclass. self performRefactoring: (PPRemoveParserRefactoring onClass: self selectedClass). self selectedClass: superclass ] on: $r entitled: 'Remove (x)'; selectionAct: [ self selectedClass browse ] on: $b entitled: 'Browse (b)'! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'lr 11/20/2009 16:19'! browseCyclesOn: aBrowser aBrowser list title: 'Cycles'; useExplicitNotNil; format: [ :parser | parser displayName ]; display: [ :parsers | self production cycleSet ]! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'lr 4/16/2010 00:02'! browseDynamicOn: aBrowser | tabulator | aBrowser useExplicitNotNil. tabulator := aBrowser tabulator. tabulator title: 'Dynamic'; useExplicitNotNil; row: #input; row: #output. tabulator transmit to: #input; andShow: [ :a | self browseInputOn: a ]. tabulator transmit to: #output; from: #input; andShow: [ :a | self browseOutputOn: a ]. tabulator transmit from: #output; to: #input->#selectionInterval; when: [ :selection | selection notNil ]; transformed: [ :selection | selection second to: selection third ] ! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'lr 11/11/2009 20:45'! browseExampleOn: aBrowser aBrowser text title: 'Example'; useExplicitNotNil; display: [ :parsers | self production example ]! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'lr 6/26/2010 14:36'! browseFirstOn: aBrowser aBrowser list title: 'First'; useExplicitNotNil; format: [ :parser | parser displayName ]; display: [ :parsers | self production firstSet ]! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'lr 6/26/2010 14:37'! browseFollowOn: aBrowser aBrowser list title: 'Follow'; useExplicitNotNil; format: [ :parser | parser displayName ]; display: [ :parsers | | parser | parser := self selectedClass new. parser followSets at: (parser productionAt: self selectedSelector) ifAbsent: [ Array with: nil asParser ] ]! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'tg 8/25/2010 11:08'! browseGraphOn: aBrowser aBrowser morph title: 'Graph'; useExplicitNotNil; display: [ :parsers | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: self production morphicProduction. morph ]! ! !PPDrabBrowser methodsFor: 'browse-dynamic' stamp: 'TudorGirba 12/2/2010 18:36'! browseInputOn: aBrowser aBrowser text useExplicitNotNil; display: [ :class :selector | input ]; selectionPopulate: #selection on: $s entitled: 'Parse (s)' with: [ :presentation | input := presentation text asString. stream := PPBrowserStream on: input. output := self production end parse: stream. output isPetitFailure ifTrue: [ presentation selectionInterval: (output position + 1 to: output position) ]. output ]! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'lr 1/30/2013 18:48'! browseOn: aComposite aComposite title: PPBrowser label; color: Color yellow muchDarker. aComposite row: [ :row | row column: #class; column: #selector ]. aComposite row: [ :row | row column: #part span: 2 ] span: 2. aComposite transmit to: #class; andShow: [ :composite | self browseClassesOn: composite ]. aComposite transmit to: #selector; from: #class; andShow: [ :composite | self browseSelectorsOn: composite ]. aComposite transmit to: #part; from: #class; from: #selector; andShow: [ :composite | self browsePartsOn: composite ]! ! !PPDrabBrowser methodsFor: 'browse-dynamic' stamp: 'TudorGirba 11/28/2010 23:08'! browseOutputOn: aBrowser aBrowser text title: 'Result'; display: [ output ]; act: [:text | output inspect ] entitled: 'Inspect'. aBrowser list title: 'Debugger'; format: [ :each | (String new: 2 * each fourth withAll: $ ) asText , each first, ' - ', each last printString ]; selectionAct: [:list | list selection last inspect ] entitled: 'Inspect token'; display: [ | depth trace | depth := -1. trace := OrderedCollection new. (self production end transform: [ :each | each name notNil ifTrue: [ each >=> [ :s :cc | | t r | depth := depth + 1. trace addLast: (t := Array with: each name with: s position + 1 with: s position with: depth with: Object new with: nil). r := cc value. t at: t size put: r. t at: 3 put: s position. r isPetitFailure ifFalse: [ t at: 1 put: (t at: 1) asText allBold ]. depth := depth - 1. r ] ] ifFalse: [ each ] ]) parse: input. trace ]. aBrowser table title: 'Tally'; column: 'Parser' evaluated: [ :each | each first displayName ]; column: 'Count' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ stream asFrequencyTable ]. aBrowser table title: 'Profile'; column: 'Parser' evaluated: [ :each | each first displayName ]; column: 'Time (ms)' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ stream asTimingTable ]. aBrowser morph title: 'Progress'; display: [ | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: stream asPositionMorph. morph ]! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'TudorGirba 3/5/2011 23:21'! browsePartsOn: aComposite aComposite useExplicitNotNil. aComposite tabbedArrangement. self browseStaticOn: aComposite. self browseDynamicOn: aComposite! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'lr 1/30/2013 19:31'! browseSelectorsOn: aBrowser aBrowser list title: 'Productions'; format: [ :class | class asString ]; display: [ :class | ((((class allInstVarNames copyWithoutAll: class ignoredNames) copyWithoutAll: self rootClass allInstVarNames) collect: [ :each | each asSymbol ]) select: [ :each | class includesSelector: each ]) asSortedCollection ]; selectionAct: [ | selector | selector := UIManager default request: 'Production name' initialAnswer: self selectedSelector title: 'New production'. selector isNil ifFalse: [ self performRefactoring: (PPRenameProdcutionRefactoring onClass: self selectedClass rename: self selectedSelector to: selector asSymbol). self selectedSelector: selector asSymbol ] ] on: $r entitled: 'Rename... (r)'; selectionAct: [ self performRefactoring: (PPRemoveProdcutionRefactoring onClass: self selectedClass production: self selectedSelector). self selectedSelector: nil ] on: $r entitled: 'Remove (x)'; selectionAct: [ Smalltalk tools browser fullOnClass: self selectedClass selector: self selectedSelector ] on: $b entitled: 'Browse (b)'! ! !PPDrabBrowser methodsFor: 'browse-static' stamp: 'lr 1/30/2013 19:19'! browseSourceOn: aBrowser aBrowser smalltalkCode title: 'Source'; useExplicitNotNil; display: [ self sourceCode ]; smalltalkClass: [ self selectedClass ]; act: [ :node | | refactoring | refactoring := PPDefineProdcutionRefactoring onClass: self selectedClass source: node text asString protocols: #(production). self performRefactoring: refactoring. self selectedSelector: refactoring selector ] on: $s entitled: 'accept (s)'! ! !PPDrabBrowser methodsFor: 'browse' stamp: 'lr 1/30/2013 19:34'! browseStaticOn: aBrowser aBrowser useExplicitNotNil. aBrowser tabbedArrangement. self browseSourceOn: aBrowser. self browseGraphOn: aBrowser. self browseCyclesOn: aBrowser. self browseFirstOn: aBrowser. self browseFollowOn: aBrowser. self browseExampleOn: aBrowser! ! !PPDrabBrowser methodsFor: 'initialize-release' stamp: 'lr 4/14/2010 21:05'! initialize super initialize. input := String new. output := String new. stream := PPBrowserStream on: input! ! !PPDrabBrowser methodsFor: 'public' stamp: 'lr 1/30/2013 19:03'! openOn: aClass rootClass := aClass. browser := GLMTabulator new. self browseOn: browser. browser openOn: self rootModel! ! !PPDrabBrowser methodsFor: 'querying' stamp: 'lr 1/30/2013 18:54'! performRefactoring: aRefactoring ^ PPRefactoringUtils new performRefactoring: aRefactoring! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 11/23/2009 22:24'! production | parser | ^ (parser := self selectedClass new) productionAt: (self selectedSelector ifNil: [ ^ parser ])! ! !PPDrabBrowser methodsFor: 'accessing' stamp: 'lr 1/30/2013 18:47'! rootClass ^ rootClass! ! !PPDrabBrowser methodsFor: 'accessing' stamp: 'lr 1/30/2013 18:47'! rootModel ^ self subclassesOf: self rootClass! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 4/15/2010 10:47'! selectedClass ^ ((browser paneNamed: #class) port: #selection) value! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 1/30/2013 19:20'! selectedClass: aClass ((browser paneNamed: #class) update; port: #selection) value: aClass! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 4/15/2010 10:47'! selectedSelector ^ ((browser paneNamed: #selector) port: #selection) value! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 1/30/2013 19:20'! selectedSelector: aSelector ((browser paneNamed: #selector) update; port: #selection) value: aSelector! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 11/11/2009 20:42'! sourceCode ^ (self selectedClass ifNil: [ ^ String new ]) sourceCodeAt: (self selectedSelector ifNil: [ #start ]) ifAbsent: [ String new ]! ! !PPDrabBrowser methodsFor: 'accessing-view' stamp: 'lr 1/30/2013 18:49'! sourceCode: aString in: aClass | tree source selector | tree := RBParser parseMethod: aString onError: [ :msg :pos | nil ]. source := tree isNil ifTrue: [ aString ] ifFalse: [ | rewriter | rewriter := RBParseTreeRewriter new. rewriter replace: '`#literal' with: '`#literal asParser' when: [ :node | (node isLiteralNode and: [ node value isString or: [ node value isCharacter ] ]) and: [ (node parent isNil or: [ node parent isMessage not or: [ node parent selector ~= #asParser ] ]) and: [ (node parents noneSatisfy: [ :each | each isBlock ]) ] ] ]; replaceMethod: '`@method: `@args | `@temps | ``@.statements. ``.statement `{ :node | node isReturn not }' with: '`@method: `@args | `@temps | ``@.statements. ^ ``.statement'. (rewriter executeTree: tree) ifTrue: [ rewriter tree newSource ] ifFalse: [ aString ] ]. selector := aClass compile: source. (aString numArgs = 0 and: [ (aClass allInstVarNames includes: selector) not ]) ifTrue: [ aClass addInstVarNamed: selector asString ]. ^ selector! ! !PPDrabBrowser methodsFor: 'querying' stamp: 'lr 11/11/2009 08:44'! subclassesOf: aBehavior ^ aBehavior subclasses asSortedCollection: [ :a :b | a name < b name ]! ! !PPDrabBrowser methodsFor: 'public' stamp: 'lr 1/30/2013 19:02'! update browser entity: self rootModel! ! !PPFailure commentStamp: '' prior: 34288418! The failure object in PetitParser. It is the only class that responds to #isPetitFailure with true. It contains an error message and a position of the occurrence of the failure. Instance Variables: message The error message of this failure. position The position of this failure in the input stream. ! !PPFailure class methodsFor: 'instance creation' stamp: 'lr 5/5/2010 13:56'! message: aString at: anInteger ^ self basicNew initializeMessage: aString at: anInteger! ! !PPFailure methodsFor: 'initialization' stamp: 'lr 5/5/2010 13:55'! initializeMessage: aString at: anInteger message := aString. position := anInteger! ! !PPFailure methodsFor: 'testing' stamp: 'lr 2/7/2010 20:54'! isPetitFailure "I am the only class that should implement this method to return true." ^ true! ! !PPFailure methodsFor: 'accessing' stamp: 'lr 5/5/2010 13:56'! message "Answer a human readable error message of this parse failure." ^ message! ! !PPFailure methodsFor: 'accessing' stamp: 'lr 5/5/2010 13:55'! position "Answer the position in the source string that caused this parse failure." ^ position! ! !PPFailure methodsFor: 'printing' stamp: 'lr 5/5/2010 14:01'! printOn: aStream aStream nextPutAll: self message; nextPutAll: ' at '; print: position! ! !PPMemento commentStamp: '' prior: 34288792! PPMemento is an internal class used by PPMemoizedParser to cache results and detect left-recursive calls. Instance Variables: result The cached result. count The number of recursive cycles followed. position The position of the cached result in the input stream.! !PPMemento class methodsFor: 'instance creation' stamp: 'lr 4/22/2008 18:21'! new ^ self basicNew initialize! ! !PPMemento methodsFor: 'accessing-readonly' stamp: 'lr 4/22/2008 18:23'! count ^ count! ! !PPMemento methodsFor: 'actions' stamp: 'lr 4/22/2008 18:20'! increment count := count + 1! ! !PPMemento methodsFor: 'initialization' stamp: 'lr 4/22/2008 18:21'! initialize count := 0 ! ! !PPMemento methodsFor: 'accessing' stamp: 'lr 4/22/2008 18:23'! position ^ position! ! !PPMemento methodsFor: 'accessing' stamp: 'lr 4/26/2008 15:48'! position: anInteger position := anInteger! ! !PPMemento methodsFor: 'accessing' stamp: 'lr 4/24/2008 10:15'! result ^ result! ! !PPMemento methodsFor: 'accessing' stamp: 'lr 4/22/2008 18:23'! result: anObject result := anObject! ! !PPParser commentStamp: '' prior: 34289138! An abstract parser for all parsers in PetitParser. Subclasses implement #parseOn: to perform the actual recursive-descent parsing. All parsers support a variety of methods to perform an actual parse, see the methods in the #parsing protocol. Parsers are combined with a series of operators that can be found in the #operations protocol. Instance Variables: properties Stores additional state in the parser object.! !PPDelegateParser commentStamp: '' prior: 34289625! A parser that delegates to another parser. Instance Variables: parser The parser to delegate to.! !PPActionParser commentStamp: '' prior: 34289791! A parser that performs an action block with the successful parse result of the delegate. Instance Variables: block The action block to be executed. ! !PPActionParser class methodsFor: 'instance creation' stamp: 'lr 5/2/2010 16:58'! on: aParser block: aBlock ^ (self on: aParser) setBlock: aBlock! ! !PPActionParser methodsFor: 'accessing' stamp: 'lr 4/30/2010 11:10'! block "Answer the action block of the receiver." ^ block! ! !PPActionParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 5/7/2011 15:08'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]! ! !PPActionParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:10'! parseOn: aStream | element | ^ (element := parser parseOn: aStream) isPetitFailure ifFalse: [ block value: element ] ifTrue: [ element ]! ! !PPActionParser methodsFor: 'initialization' stamp: 'lr 5/2/2010 16:58'! setBlock: aBlock block := aBlock! ! !PPWrappingParser commentStamp: '' prior: 34290015! A parser that performs an action block upon activation with the stream and a continuation block.! !PPWrappingParser methodsFor: 'parsing' stamp: 'lr 5/12/2010 20:19'! parseOn: aStream ^ block value: aStream value: [ parser parseOn: aStream ]! ! !PPAndParser commentStamp: 'TudorGirba 2/27/2011 22:22' prior: 34290179! The and-predicate, a parser that succeeds whenever its delegate does, but does not consume the input stream [Parr 1994, 1995].! !PPAndParser methodsFor: 'operators' stamp: 'lr 5/1/2010 16:16'! and ^ self! ! !PPAndParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:17'! displayDescription ^ 'and'! ! !PPAndParser methodsFor: '*petitgui-accessing' stamp: 'lr 5/1/2010 16:16'! exampleOn: aStream! ! !PPAndParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:10'! parseOn: aStream | element position | position := aStream position. element := parser parseOn: aStream. aStream position: position. ^ element! ! !PPCompositeParser commentStamp: 'lr 12/4/2009 18:38' prior: 34290371! A PPCompositeParser is composed parser built from various primitive parsers. Every production in the receiver is specified as a method that returns its parser. Note that every production requires an instance variable of the same name, otherwise the production is not cached and cannot be used in recursive grammars. Productions should refer to each other by reading the respective inst-var. Note: these inst-vars are typically not written, as the assignment happens in the initialize method using reflection. The start production is defined in the method start. It is aliased to the inst-var parser defined in the superclass of PPCompositeParser.! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 2/25/2013 23:46'! addition ^ (factors separatedBy: ($+ asParser / $- asParser) trim) foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 9/15/2008 09:28'! factors ^ multiplication / power! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 2/25/2013 23:47'! multiplication ^ (power separatedBy: ($* asParser / $/ asParser) trim) foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 2/25/2013 23:47'! number ^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim ==> [ :value | value asNumber ]! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 2/25/2013 23:49'! parentheses ^ $( asParser trim , terms , $) asParser trim ==> [ :nodes | nodes second ]! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 2/25/2013 23:49'! power ^ (primary separatedBy: $^ asParser trim) foldRight: [ :a :op :b | a raisedTo: b ]! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 9/15/2008 09:28'! primary ^ number / parentheses! ! !PPArithmeticParser methodsFor: 'accessing' stamp: 'lr 7/3/2008 17:06'! start ^ terms end! ! !PPArithmeticParser methodsFor: 'grammar' stamp: 'lr 9/15/2008 09:29'! terms ^ addition / factors! ! !PPCompositeParser class methodsFor: 'accessing' stamp: 'lr 3/16/2013 21:42'! dependencies "Answer a collection of PPCompositeParser classes that this parser directly dependends on. Override this method in subclasses to declare dependent parsers. The default implementation does not depend on other PPCompositeParser." ^ #()! ! !PPCompositeParser class methodsFor: 'accessing' stamp: 'lr 1/29/2010 11:35'! ignoredNames "Answer a collection of instance-variables that should not be automatically initialized with productions, but that are used internal to the composite parser." ^ PPCompositeParser allInstVarNames! ! !PPCompositeParser class methodsFor: 'instance creation' stamp: 'lr 12/7/2009 08:24'! new "Answer a new parser starting at the default start symbol." ^ self newStartingAt: self startSymbol! ! !PPCompositeParser class methodsFor: 'instance creation' stamp: 'lr 3/16/2013 21:21'! newStartingAt: aSymbol "Answer a new parser starting at aSymbol. The code makes sure to resolve all dependent parsers correctly." | parsers remaining | parsers := IdentityDictionary new. remaining := OrderedCollection with: self. [ remaining isEmpty ] whileFalse: [ | dependency | dependency := remaining removeLast. (parsers includesKey: dependency) ifFalse: [ parsers at: dependency put: dependency basicNew. remaining addAll: dependency dependencies ] ]. parsers keysAndValuesDo: [ :class :parser | | dependencies | dependencies := IdentityDictionary new. class dependencies do: [ :dependency | dependencies at: dependency put: (parsers at: dependency) ]. parser initializeStartingAt: (class == self ifTrue: [ aSymbol ] ifFalse: [ class startSymbol ]) dependencies: dependencies ]. parsers keysAndValuesDo: [ :class :parser | parser setParser: (parser perform: parser children first name). parser productionNames keysAndValuesDo: [ :key :value | (parser instVarAt: key) setParser: (parser perform: value) ] ]. ^ parsers at: self! ! !PPCompositeParser class methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:57'! parse: anObject ^ self parse: anObject startingAt: self startSymbol! ! !PPCompositeParser class methodsFor: 'parsing' stamp: 'lr 2/7/2010 21:02'! parse: anObject onError: aBlock ^ self parse: anObject startingAt: self startSymbol onError: aBlock! ! !PPCompositeParser class methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:57'! parse: anObject startingAt: aSymbol ^ (self newStartingAt: aSymbol) parse: anObject! ! !PPCompositeParser class methodsFor: 'parsing' stamp: 'lr 2/7/2010 21:02'! parse: anObject startingAt: aSymbol onError: aBlock ^ (self newStartingAt: aSymbol) parse: anObject onError: aBlock! ! !PPCompositeParser class methodsFor: 'accessing' stamp: 'lr 12/7/2009 08:20'! startSymbol "Answer the method that represents the default start symbol." ^ #start! ! !PPCompositeParser methodsFor: 'querying' stamp: 'lr 3/16/2013 21:41'! dependencyAt: aClass "Answer the dependent parser aClass. Throws an error if this parser class is not declared in the method #dependencies on the class-side of the receiver." ^ dependencies at: aClass ifAbsent: [ self error: 'Undeclared dependency in ' , self class name , ' to ' , aClass name ]! ! !PPCompositeParser methodsFor: 'initialization' stamp: 'lr 3/16/2013 17:15'! initializeStartingAt: aSymbol dependencies: aDictionary self initialize. parser := PPDelegateParser named: aSymbol. self productionNames keysAndValuesDo: [ :key :value | self instVarAt: key put: (PPDelegateParser named: value) ]. dependencies := aDictionary! ! !PPCompositeParser methodsFor: 'querying' stamp: 'lr 12/4/2009 18:39'! productionAt: aSymbol "Answer the production named aSymbol." ^ self productionAt: aSymbol ifAbsent: [ nil ]! ! !PPCompositeParser methodsFor: 'querying' stamp: 'lr 6/4/2010 13:37'! productionAt: aSymbol ifAbsent: aBlock "Answer the production named aSymbol, if there is no such production answer the result of evaluating aBlock." (self class ignoredNames includes: aSymbol asString) ifTrue: [ ^ aBlock value ]. (self class startSymbol = aSymbol) ifTrue: [ ^ parser ]. ^ self instVarAt: (self class allInstVarNames indexOf: aSymbol asString ifAbsent: [ ^ aBlock value ])! ! !PPCompositeParser methodsFor: 'querying' stamp: 'lr 5/8/2011 15:45'! productionNames "Answer a dictionary of slot indexes and production names." | productionNames ignoredNames | productionNames := Dictionary new. ignoredNames := self class ignoredNames collect: [ :each | each asSymbol ]. self class allInstVarNames keysAndValuesDo: [ :key :value | (ignoredNames includes: value asSymbol) ifFalse: [ productionNames at: key put: value asSymbol ] ]. ^ productionNames! ! !PPCompositeParser methodsFor: 'accessing' stamp: 'lr 5/16/2008 17:32'! start "Answer the production to start this parser with." self subclassResponsibility! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! and ^ self parse: '\p.\q.((p q) p)'! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! false ^ self parse: '\x.\y.y'! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! ifthenelse ^ self parse: '\p.p'! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! not ^ self parse: '\p.\a.\b.((p b) a)'! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! or ^ self parse: '\p.\q.((p p) q)'! ! !PPLambdaParser class methodsFor: 'curch-booleans' stamp: 'lr 4/3/2009 08:28'! true ^ self parse: '\x.\y.x'! ! !PPLambdaParser methodsFor: 'productions' stamp: 'lr 2/25/2013 23:43'! abstraction ^ $\ asParser trim , variable , $. asParser trim , expression ==> [ :node | Array with: node second with: node fourth ]! ! !PPLambdaParser methodsFor: 'productions' stamp: 'lr 2/25/2013 23:43'! application ^ $( asParser trim , expression , expression , $) asParser trim ==> [ :node | Array with: node second with: node third ]! ! !PPLambdaParser methodsFor: 'productions' stamp: 'lr 9/15/2008 09:29'! expression ^ variable / abstraction / application! ! !PPLambdaParser methodsFor: 'accessing' stamp: 'lr 5/19/2008 11:35'! start ^ expression end! ! !PPLambdaParser methodsFor: 'productions' stamp: 'lr 2/25/2013 23:44'! variable ^ (#letter asParser , #word asParser star) flatten trim! ! !PPDelegateParser class methodsFor: 'instance creation' stamp: 'lr 4/20/2008 16:22'! on: aParser ^ self new setParser: aParser! ! !PPDelegateParser methodsFor: 'accessing' stamp: 'lr 10/21/2009 16:37'! children ^ Array with: parser! ! !PPDelegateParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:20'! displayDescription ^ nil! ! !PPDelegateParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:27'! exampleOn: aStream parser exampleOn: aStream! ! !PPDelegateParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/18/2009 11:21'! morphicShapeSeen: aSet depth: anInteger ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | self displayDescription isNil ifTrue: [ cc value: parser ] ifFalse: [ self newRowMorph addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph height: 10); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); yourself); addMorphBack: (self newRowMorph color: (self backgroundForDepth: anInteger); addMorphBack: (self newColumnMorph addMorphBack: (cc value: parser); addMorphBack: (self newRowMorph hResizing: #spaceFill; addMorphBack: (self newSpacerMorph width: 20; yourself); addMorphBack: (self newColumnMorph hResizing: #spaceFill; listCentering: #center; addMorphBack: (self newSpacerMorph); addMorphBack: (StringMorph new contents: self displayDescription; yourself); yourself); yourself); yourself); addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph height: 10); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); yourself); yourself); yourself ] ]! ! !PPDelegateParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:47'! parseOn: aStream ^ parser parseOn: aStream! ! !PPDelegateParser methodsFor: '*petitanalyzer-transforming' stamp: 'lr 4/13/2010 09:39'! replace: aParser with: anotherParser super replace: aParser with: anotherParser. parser == aParser ifTrue: [ parser := anotherParser ]! ! !PPDelegateParser methodsFor: 'initialization' stamp: 'lr 4/20/2008 16:23'! setParser: aParser parser := aParser! ! !PPEndOfInputParser commentStamp: 'lr 4/18/2008 13:46' prior: 34291087! A parser that succeeds only at the end of the input stream.! !PPEndOfInputParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:18'! displayDescription ^ 'end of input'! ! !PPEndOfInputParser methodsFor: 'operators' stamp: 'lr 12/7/2009 08:53'! end ^ self! ! !PPEndOfInputParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:10'! parseOn: aStream | position result | position := aStream position. result := parser parseOn: aStream. (result isPetitFailure or: [ aStream atEnd ]) ifTrue: [ ^ result ]. result := PPFailure message: 'end of input expected' at: aStream position. aStream position: position. ^ result! ! !PPExpressionParser commentStamp: '' prior: 34291207! A PPExpressionParser is a parser to conveniently define an expression grammar with prefix, postfix, and left- and right-associative infix operators. The following code initializes a parser for arithmetic expressions. First we instantiate an expression parser, a simple parser for expressions in parenthesis and a simple parser for integer numbers. expression := PPExpressionParser new. parens := $( asParser token trim , expression , $) asParser token trim ==> [ :nodes | nodes second ]. integer := #digit asParser plus token trim ==> [ :token | token value asInteger ]. Then we define on what term the expression grammar is built on: expression term: parens / integer. Finally we define the operator-groups in descending precedence. Note, that the action blocks receive both, the terms and the parsed operator in the order they appear in the parsed input. expression group: [ :g | g prefix: $- asParser token trim do: [ :op :a | a negated ] ]; group: [ :g | g postfix: '++' asParser token trim do: [ :a :op | a + 1 ]. g postfix: '--' asParser token trim do: [ :a :op | a - 1 ] ]; group: [ :g | g right: $^ asParser token trim do: [ :a :op :b | a raisedTo: b ] ]; group: [ :g | g left: $* asParser token trim do: [ :a :op :b | a * b ]. g left: $/ asParser token trim do: [ :a :op :b | a / b ] ]; group: [ :g | g left: $+ asParser token trim do: [ :a :op :b | a + b ]. g left: $- asParser token trim do: [ :a :op :b | a - b ] ]. After evaluating the above code the 'expression' is an efficient parser that evaluates examples like: expression parse: '-8++'. expression parse: '1+2*3'. expression parse: '1*2+3'. expression parse: '(1+2)*3'. expression parse: '8/4/2'. expression parse: '8/(4/2)'. expression parse: '2^2^3'. expression parse: '(2^2)^3'. Instance Variables: operators The operators defined in the current group.! !PPExpressionParser methodsFor: 'private' stamp: 'FirstnameLastname 11/26/2009 20:48'! build: aParser left: aChoiceParser ^ (aParser separatedBy: aChoiceParser) foldLeft: [ :a :op :b | op first value: a value: op second value: b ]! ! !PPExpressionParser methodsFor: 'private' stamp: 'lr 12/4/2009 17:38'! build: aParser postfix: aChoiceParser ^ aParser , aChoiceParser star map: [ :term :ops | ops inject: term into: [ :result :operator | operator first value: result value: operator second ] ]! ! !PPExpressionParser methodsFor: 'private' stamp: 'lr 12/4/2009 17:39'! build: aParser prefix: aChoiceParser ^ aChoiceParser star , aParser map: [ :ops :term | ops reversed inject: term into: [ :result :operator | operator first value: operator second value: result ] ]! ! !PPExpressionParser methodsFor: 'private' stamp: 'FirstnameLastname 11/26/2009 20:48'! build: aParser right: aChoiceParser ^ (aParser separatedBy: aChoiceParser) foldRight: [ :a :op :b | op first value: a value: op second value: b ]! ! !PPExpressionParser methodsFor: 'private' stamp: 'FirstnameLastname 11/26/2009 21:15'! buildOn: aParser ^ self buildSelectors inject: aParser into: [ :term :selector | | list | list := operators at: selector ifAbsent: [ #() ]. list isEmpty ifTrue: [ term ] ifFalse: [ self perform: selector with: term with: (list size = 1 ifTrue: [ list first first ==> [ :operator | Array with: list first second with: operator ] ] ifFalse: [ list inject: PPChoiceParser new into: [ :choice :each | choice / (each first ==> [ :operator | Array with: each second with: operator ]) ] ]) ] ]! ! !PPExpressionParser methodsFor: 'private' stamp: 'FirstnameLastname 11/26/2009 20:48'! buildSelectors ^ #(build:prefix: build:postfix: build:right: build:left:)! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'lr 2/7/2010 23:20'! group: aOneArgumentBlock "Defines a priority group by evaluating aOneArgumentBlock." operators := Dictionary new. parser := [ aOneArgumentBlock value: self. self buildOn: parser ] ensure: [ operators := nil ]! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'FirstnameLastname 11/26/2009 20:49'! left: aParser do: aThreeArgumentBlock "Define an operator aParser that is left-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term." self operator: #build:left: parser: aParser do: aThreeArgumentBlock! ! !PPExpressionParser methodsFor: 'private' stamp: 'lr 2/7/2010 23:23'! operator: aSymbol parser: aParser do: aBlock parser isNil ifTrue: [ ^ self error: 'You did not specify a term when creating the receiver.' ]. operators isNil ifTrue: [ ^ self error: 'Use #group: to define precedence groups in descending order.' ]. (operators at: aSymbol ifAbsentPut: [ OrderedCollection new ]) addLast: (Array with: aParser asParser with: aBlock)! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'FirstnameLastname 11/26/2009 20:49'! postfix: aParser do: aTwoArgumentBlock "Define a postfix operator aParser. Evaluate aTwoArgumentBlock with the term and the operator." self operator: #build:postfix: parser: aParser do: aTwoArgumentBlock! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'FirstnameLastname 11/26/2009 20:49'! prefix: aParser do: aTwoArgumentBlock "Define a prefix operator aParser. Evaluate aTwoArgumentBlock with the operator and the term." self operator: #build:prefix: parser: aParser do: aTwoArgumentBlock! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'FirstnameLastname 11/26/2009 20:49'! right: aParser do: aThreeArgumentBlock "Define an operator aParser that is right-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term." self operator: #build:right: parser: aParser do: aThreeArgumentBlock! ! !PPExpressionParser methodsFor: 'specifying' stamp: 'FirstnameLastname 11/26/2009 21:26'! term: aParser "Defines the initial term aParser of the receiver." parser isNil ifTrue: [ parser := aParser ] ifFalse: [ self error: 'Unable to redefine the term.' ]! ! !PPFlattenParser commentStamp: 'lr 11/22/2009 13:09' prior: 34293178! A parser that answers a flat copy of the range my delegate parses.! !PPFlattenParser methodsFor: 'private' stamp: 'lr 2/25/2013 23:31'! on: aCollection start: aStartInteger stop: aStopInteger value: anObject ^ aCollection copyFrom: aStartInteger to: aStopInteger! ! !PPFlattenParser methodsFor: 'parsing' stamp: 'lr 2/25/2013 23:30'! parseOn: aStream | start element | start := aStream position. element := parser parseOn: aStream. element isPetitFailure ifTrue: [ ^ element ]. ^ self on: aStream collection start: start + 1 stop: aStream position value: element! ! !PPTokenParser commentStamp: 'lr 2/25/2013 23:31' prior: 34293306! A parser that answers a token with the value of my delegate parses. Instance Variables: tokenClass The token sub-class to be used.! !PPTokenParser methodsFor: 'private' stamp: 'lr 4/6/2010 19:18'! defaultTokenClass ^ PPToken! ! !PPTokenParser methodsFor: 'initialization' stamp: 'lr 4/6/2010 19:19'! initialize tokenClass := self defaultTokenClass ! ! !PPTokenParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 6/18/2010 14:09'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self tokenClass = aParser tokenClass ]! ! !PPTokenParser methodsFor: 'private' stamp: 'lr 2/25/2013 23:32'! on: aCollection start: aStartInteger stop: aStopInteger value: anObject ^ self tokenClass on: aCollection start: aStartInteger stop: aStopInteger value: anObject! ! !PPTokenParser methodsFor: 'accessing' stamp: 'lr 4/6/2010 19:23'! tokenClass ^ tokenClass! ! !PPTokenParser methodsFor: 'accessing' stamp: 'lr 4/6/2010 19:24'! tokenClass: aTokenClass tokenClass := aTokenClass! ! !PPMemoizedParser commentStamp: '' prior: 34293513! A memoized parser, for refraining redundant computations. Instance Variables: stream The stream of the associated memento objects. buffer The buffer of memento objects. ! !PPMemoizedParser methodsFor: 'operators' stamp: 'lr 4/2/2009 19:48'! memoized "Ther is no point in memoizing more than once." ^ self! ! !PPMemoizedParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:11'! parseOn: aStream | memento | stream == aStream ifFalse: [ self reset: aStream ]. memento := (buffer at: stream position + 1) ifNil: [ buffer at: stream position + 1 put: PPMemento new ]. memento position isNil ifTrue: [ memento result: (stream size - stream position + 2 < memento count ifTrue: [ PPFailure message: 'overflow' at: stream position ] ifFalse: [ memento increment. parser parseOn: stream ]). memento position: stream position ] ifFalse: [ stream position: memento position ]. ^ memento result! ! !PPMemoizedParser methodsFor: 'private' stamp: 'lr 4/2/2009 19:22'! reset: aStream stream := aStream. buffer := Array new: aStream size + 1! ! !PPNotParser commentStamp: '' prior: 34293782! The not-predicate, a parser that succeeds whenever its delegate does not, but consumes no input [Parr 1994, 1995].! !PPNotParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:17'! displayDescription ^ 'not'! ! !PPNotParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/11/2009 21:09'! exampleOn: aStream! ! !PPNotParser methodsFor: '*petitanalyzer-private' stamp: 'JanKurs 5/31/2013 11:50'! firstSets: aFirstDictionary into: aSet ! ! !PPNotParser methodsFor: '*petitanalyzer-testing' stamp: 'JanKurs 5/31/2013 11:50'! isFirstSetTerminal ^ true! ! !PPNotParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:11'! parseOn: aStream | element position | position := aStream position. element := parser parseOn: aStream. aStream position: position. ^ element isPetitFailure ifFalse: [ PPFailure message: '' at: aStream position ]! ! !PPOptionalParser commentStamp: 'lr 4/3/2011 14:46' prior: 34293960! A parser that optionally parsers its delegate, or answers nil.! !PPOptionalParser methodsFor: '*petitanalyzer-testing' stamp: 'lr 9/1/2010 22:10'! isNullable ^ true! ! !PPOptionalParser methodsFor: 'parsing' stamp: 'lr 8/14/2011 11:47'! parseOn: aStream | element | element := parser parseOn: aStream. ^ element isPetitFailure ifFalse: [ element ]! ! !PPRepeatingParser commentStamp: 'lr 4/3/2011 14:45' prior: 34294087! An abstract parser that repeatedly parses between 'min' and 'max' instances of its delegate. The default configuration parses an infinite number of elements, as 'min' is set to 0 and 'max' to infinity (SmallInteger maxVal). Instance Variables: min The minimum number of repetitions. max The maximum number of repetitions.! !PPLimitedRepeatingParser commentStamp: 'lr 4/3/2011 14:37' prior: 34294503! An abstract parser that repeatedly parses between 'min' and 'max' instances of my delegate and that requires the input to be completed with a specified parser 'limit'. Subclasses provide repeating behavior as typically seen in regular expression implementations (non-blind). Instance Variables: limit The parser to complete the input with.! !PPGreedyRepeatingParser commentStamp: 'lr 4/3/2011 15:08' prior: 34294926! A greedy repeating parser, commonly seen in regular expression implementations. It aggressively consumes as much input as possible and then backtracks to meet the 'limit' condition. This class essentially implements the iterative version of the following recursive parser composition: | parser | parser := PPChoiceParser new. parser setParsers: (Array with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ]) with: (limit and ==> [ :each | OrderedCollection new ])). ^ parser ==> [ :rest | rest asArray ]! !PPGreedyRepeatingParser methodsFor: 'parsing' stamp: 'lr 4/2/2011 15:54'! parseOn: aStream | start element elements positions | start := aStream position. elements := OrderedCollection new. [ elements size < min ] whileTrue: [ (element := parser parseOn: aStream) isPetitFailure ifTrue: [ aStream position: start. ^ element ]. elements addLast: element ]. positions := OrderedCollection with: aStream position. [ elements size < max and: [ (element := parser parseOn: aStream) isPetitFailure not ] ] whileTrue: [ elements addLast: element. positions addLast: aStream position ]. [ positions isEmpty ] whileFalse: [ aStream position: positions last. element := limit parseOn: aStream. element isPetitFailure ifFalse: [ aStream position: positions last. ^ elements asArray ]. elements isEmpty ifTrue: [ aStream position: start. ^ element ]. elements removeLast. positions removeLast ]. aStream position: start. ^ PPFailure message: 'overflow' at: start! ! !PPLazyRepeatingParser commentStamp: 'lr 4/3/2011 15:08' prior: 34295527! A lazy repeating parser, commonly seen in regular expression implementations. It limits its consumption to meet the 'limit' condition as early as possible. This class essentially implements the iterative version of the following recursive parser composition: | parser | parser := PPChoiceParser new. parser setParsers: (Array with: (limit and ==> [ :each | OrderedCollection new ]) with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ])). ^ parser ==> [ :rest | rest asArray ]! !PPLazyRepeatingParser methodsFor: 'parsing' stamp: 'lr 4/2/2011 10:14'! parseOn: aStream | start element elements | start := aStream position. elements := OrderedCollection new. [ elements size < min ] whileTrue: [ (element := parser parseOn: aStream) isPetitFailure ifTrue: [ aStream position: start. ^ element ]. elements addLast: element ]. [ self matchesLimitOn: aStream ] whileFalse: [ elements size < max ifFalse: [ aStream position: start. ^ PPFailure message: 'overflow' at: start ]. element := parser parseOn: aStream. element isPetitFailure ifTrue: [ aStream position: start. ^ element ]. elements addLast: element ]. ^ elements asArray! ! !PPLimitedRepeatingParser class methodsFor: 'instance creation' stamp: 'lr 4/3/2011 14:58'! on: aParser limit: aLimitParser ^ (self on: aParser) setLimit: aLimitParser! ! !PPLimitedRepeatingParser methodsFor: 'accessing' stamp: 'lr 4/4/2011 18:46'! children ^ Array with: parser with: limit! ! !PPLimitedRepeatingParser methodsFor: 'accessing' stamp: 'lr 4/2/2011 10:00'! limit "Answer the parser that limits (or ends) this repetition." ^ limit! ! !PPLimitedRepeatingParser methodsFor: 'private' stamp: 'lr 4/2/2011 10:10'! matchesLimitOn: aStream | element position | position := aStream position. element := limit parseOn: aStream. aStream position: position. ^ element isPetitFailure not! ! !PPLimitedRepeatingParser methodsFor: '*petitanalyzer-transforming' stamp: 'lr 4/4/2011 18:46'! replace: aParser with: anotherParser super replace: aParser with: anotherParser. limit == aParser ifTrue: [ limit := anotherParser ]! ! !PPLimitedRepeatingParser methodsFor: 'initialization' stamp: 'lr 4/2/2011 10:00'! setLimit: aParser limit := aParser! ! !PPPossessiveRepeatingParser commentStamp: 'lr 4/3/2011 14:35' prior: 34296108! The default repeating parser with standard PEG semantics (i.e. possessive, blind, eager).! !PPPossessiveRepeatingParser methodsFor: 'parsing' stamp: 'lr 4/2/2011 09:52'! parseOn: aStream | start element elements | start := aStream position. elements := OrderedCollection new. [ elements size < min ] whileTrue: [ (element := parser parseOn: aStream) isPetitFailure ifTrue: [ aStream position: start. ^ element ]. elements addLast: element ]. [ elements size < max ] whileTrue: [ (element := parser parseOn: aStream) isPetitFailure ifTrue: [ ^ elements asArray ]. elements addLast: element ]. ^ elements asArray! ! !PPRepeatingParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:18'! displayDescription ^ String streamContents: [ :stream | min = 0 ifFalse: [ stream print: min; nextPutAll: '..' ]. max = SmallInteger maxVal ifTrue: [ stream nextPut: $* ] ifFalse: [ stream print: max ] ]! ! !PPRepeatingParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/11/2009 20:57'! exampleOn: aStream "Perform the minimal repeatitions required, and a random amount of more if possible and if not that much output has been produced yet." min timesRepeat: [ super exampleOn: aStream ]. (max - min min: 5) atRandom timesRepeat: [ aStream position > 512 ifTrue: [ ^ self ]. super exampleOn: aStream ]! ! !PPRepeatingParser methodsFor: '*petitanalyzer-private' stamp: 'JanKurs 5/31/2013 11:51'! followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet | firstSet | super followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet. firstSet := aFirstDictionary at: self. self children do: [:p | (aFollowDictionary at: p) addAll: (firstSet reject: [:each | each isNullable]) ]! ! !PPRepeatingParser methodsFor: 'initialization' stamp: 'lr 4/1/2011 21:06'! initialize super initialize. self setMin: 0; setMax: SmallInteger maxVal! ! !PPRepeatingParser methodsFor: '*petitanalyzer-testing' stamp: 'lr 10/21/2009 12:13'! isNullable ^ min = 0! ! !PPRepeatingParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 6/18/2010 14:09'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self min = aParser min and: [ self max = aParser max ] ]! ! !PPRepeatingParser methodsFor: 'accessing' stamp: 'lr 4/30/2010 11:08'! max "Answer the maximum number of repetitions." ^ max! ! !PPRepeatingParser methodsFor: 'accessing' stamp: 'lr 4/30/2010 11:08'! min "Answer the minimum number of repetitions." ^ min! ! !PPRepeatingParser methodsFor: 'printing' stamp: 'lr 6/3/2010 14:00'! printOn: aStream super printOn: aStream. aStream nextPutAll: ' ['; print: min; nextPutAll: ', '; nextPutAll: (max = SmallInteger maxVal ifTrue: [ '*' ] ifFalse: [ max printString ]); nextPut: $]! ! !PPRepeatingParser methodsFor: 'initialization' stamp: 'lr 4/1/2011 21:00'! setMax: anInteger max := anInteger! ! !PPRepeatingParser methodsFor: 'initialization' stamp: 'lr 4/1/2011 21:01'! setMin: anInteger min := anInteger! ! !PPTrimmingParser commentStamp: 'lr 4/6/2010 19:27' prior: 34296261! A parser that silently consumes spaces before and after the delegate parser.! !PPTrimmingParser class methodsFor: 'instance creation' stamp: 'lr 7/31/2010 12:01'! on: aParser trimmer: aTrimParser ^ self new setParser: aParser; setTrimmer: aTrimParser; yourself! ! !PPTrimmingParser methodsFor: '*petitgui-accessing' stamp: 'lr 4/14/2010 20:48'! exampleOn: aStream super exampleOn: aStream. aStream nextPut: Character space! ! !PPTrimmingParser methodsFor: 'parsing' stamp: 'lr 8/1/2010 17:11'! parseOn: aStream | position element | position := aStream position. [ (trimmer parseOn: aStream) isPetitFailure ] whileFalse. element := parser parseOn: aStream. element isPetitFailure ifTrue: [ aStream position: position. ^ element ]. [ (trimmer parseOn: aStream) isPetitFailure ] whileFalse. ^ element! ! !PPTrimmingParser methodsFor: 'initialization' stamp: 'lr 7/31/2010 12:00'! setTrimmer: aParser trimmer := aParser! ! !PPEpsilonParser commentStamp: 'lr 5/15/2008 15:09' prior: 34296401! A parser that consumes nothing and always succeeds.! !PPEpsilonParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/6/2009 18:42'! displayName ^ 'epsilon'! ! !PPEpsilonParser methodsFor: '*petitanalyzer-testing' stamp: 'lr 10/21/2009 12:11'! isNullable ^ true! ! !PPEpsilonParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/18/2009 11:15'! morphicShapeSeen: aSet depth: anInteger ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | self newRowMorph addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph height: 10); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); yourself); yourself ]! ! !PPEpsilonParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:49'! parseOn: aStream ^ nil! ! !PPSentinel class methodsFor: 'instance creation' stamp: 'lr 9/16/2010 17:54'! instance ^ instance ifNil: [ instance := self new ]! ! !PPFailingParser commentStamp: '' prior: 34296510! A parser that consumes nothing and always fails. Instance Variables: message The failure message.! !PPFailingParser class methodsFor: 'instance creation' stamp: 'lr 5/2/2010 19:16'! message: aString ^ self new setMessage: aString! ! !PPFailingParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:16'! displayColor ^ Color red! ! !PPFailingParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/6/2009 18:43'! displayName ^ message! ! !PPFailingParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 4/30/2010 12:01'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self message = aParser message ]! ! !PPFailingParser methodsFor: 'accessing' stamp: 'lr 4/30/2010 11:10'! message "Answer the error message of the receiving parser." ^ message! ! !PPFailingParser methodsFor: 'parsing' stamp: 'lr 5/5/2010 13:57'! parseOn: aStream ^ PPFailure message: message at: aStream position! ! !PPFailingParser methodsFor: 'printing' stamp: 'lr 4/16/2010 21:27'! printNameOn: aStream super printNameOn: aStream. aStream nextPutAll: ', '; print: message! ! !PPFailingParser methodsFor: 'initialization' stamp: 'lr 5/2/2010 19:16'! setMessage: aString message := aString! ! !PPListParser commentStamp: '' prior: 34296673! Abstract parser that parses a list of things in some way (to be specified by the subclasses). Instance Variables: parsers A sequence of other parsers to delegate to.! !PPChoiceParser commentStamp: 'lr 4/18/2008 15:35' prior: 34296941! A parser that uses the first parser that succeeds.! !PPChoiceParser methodsFor: 'operators' stamp: 'lr 9/17/2008 00:16'! / aRule ^ self copyWith: aRule! ! !PPChoiceParser methodsFor: '*petitgui-morphic' stamp: 'lr 5/2/2010 20:15'! exampleOn: aStream "If there is already a lot written, try to pick an empty possiblity." aStream position > 512 ifTrue: [ (parsers anySatisfy: [ :each | each isNullable ]) ifTrue: [ ^ self ] ]. parsers atRandom exampleOn: aStream! ! !PPChoiceParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/18/2009 11:14'! morphicShapeSeen: aSet depth: anInteger ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | | morph | morph := self newColumnMorph cellInset: 5; yourself. self children do: [ :each | morph addMorphBack: (self newRowMorph hResizing: #spaceFill; addMorphBack: (cc value: each); addMorphBack: (self newColumnMorph hResizing: #spaceFill; addMorphBack: (self newSpacerMorph height: 10); addMorphBack: ((LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) hResizing: #spaceFill; minWidth: 20; yourself); yourself); yourself) ]. morph fullBounds. self newRowMorph addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph height: 10); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1); yourself); addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph width: 1; height: 10); addMorphBack: (LineMorph from: 0 @ 0 to: 0 @ (morph height - 23) color: Color black width: 1); yourself); addMorphBack: morph; addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph width: 1; height: 10); addMorphBack: (LineMorph from: 0 @ (morph height - 23) to: 0 @ 0 color: Color black width: 1) makeForwardArrow; width: 1; yourself); yourself ]! ! !PPChoiceParser methodsFor: 'parsing' stamp: 'lr 5/22/2010 11:48'! parseOn: aStream "This is optimized code that avoids unnecessary block activations, do not change. When all choices fail, the last failure is answered." | element | 1 to: parsers size do: [ :index | element := (parsers at: index) parseOn: aStream. element isPetitFailure ifFalse: [ ^ element ] ]. ^ element! ! !PPListParser class methodsFor: 'instance creation' stamp: 'lr 5/3/2010 20:26'! with: aParser ^ self withAll: (Array with: aParser)! ! !PPListParser class methodsFor: 'instance creation' stamp: 'lr 9/23/2008 18:32'! with: aFirstParser with: aSecondParser ^ self withAll: (Array with: aFirstParser with: aSecondParser)! ! !PPListParser class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 10:12'! withAll: aCollection ^ self basicNew setParsers: aCollection! ! !PPListParser methodsFor: 'accessing' stamp: 'lr 10/21/2009 16:37'! children ^ parsers! ! !PPListParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 4/30/2010 08:15'! copyInContext: aDictionary seen: aSeenDictionary | copy copies | aSeenDictionary at: self ifPresent: [ :value | ^ value ]. copy := aSeenDictionary at: self put: self copy. copies := OrderedCollection new. parsers do: [ :each | | result | result := each copyInContext: aDictionary seen: aSeenDictionary. result isCollection ifTrue: [ copies addAll: result ] ifFalse: [ copies add: result ] ]. ^ copy setParsers: copies; yourself! ! !PPListParser methodsFor: 'copying' stamp: 'lr 9/17/2008 22:36'! copyWith: aParser ^ self species withAll: (parsers copyWith: aParser)! ! !PPListParser methodsFor: 'initialization' stamp: 'lr 4/29/2010 10:12'! initialize super initialize. self setParsers: #()! ! !PPListParser methodsFor: 'copying' stamp: 'lr 5/22/2010 10:26'! postCopy super postCopy. parsers := parsers copy! ! !PPListParser methodsFor: '*petitanalyzer-transforming' stamp: 'lr 5/22/2010 10:24'! replace: aParser with: anotherParser super replace: aParser with: anotherParser. parsers keysAndValuesDo: [ :index :parser | parser == aParser ifTrue: [ parsers at: index put: anotherParser ] ]! ! !PPListParser methodsFor: 'initialization' stamp: 'lr 4/29/2010 10:12'! setParsers: aCollection parsers := aCollection asArray! ! !PPSequenceParser commentStamp: 'lr 4/18/2008 15:34' prior: 34297056! A parser that parses a sequence of parsers.! !PPSequenceParser methodsFor: 'operators' stamp: 'lr 9/17/2008 00:17'! , aRule ^ self copyWith: aRule! ! !PPSequenceParser methodsFor: '*petitanalyzer-private' stamp: 'lr 12/9/2010 10:37'! cycleSet: aDictionary | firstSet | 1 to: parsers size do: [ :index | firstSet := aDictionary at: (parsers at: index). (firstSet anySatisfy: [ :each | each isNullable ]) ifFalse: [ ^ parsers copyFrom: 1 to: index ] ]. ^ parsers! ! !PPSequenceParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:24'! exampleOn: aStream parsers do: [ :each | each exampleOn: aStream ]! ! !PPSequenceParser methodsFor: '*petitanalyzer-private' stamp: 'lr 9/16/2010 17:56'! firstSets: aFirstDictionary into: aSet | nullable | parsers do: [ :parser | nullable := false. (aFirstDictionary at: parser) do: [ :each | each isNullable ifTrue: [ nullable := true ] ifFalse: [ aSet add: each ] ]. nullable ifFalse: [ ^ self ] ]. aSet add: PPSentinel instance! ! !PPSequenceParser methodsFor: '*petitanalyzer-private' stamp: 'lr 8/14/2010 13:51'! followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet parsers keysAndValuesDo: [ :index :parser | | followSet firstSet | followSet := aFollowDictionary at: parser. index = parsers size ifTrue: [ followSet addAll: aSet ] ifFalse: [ (self class withAll: (parsers copyFrom: index + 1 to: parsers size)) firstSets: aFirstDictionary into: (firstSet := IdentitySet new). (firstSet anySatisfy: [ :each | each isNullable ]) ifTrue: [ followSet addAll: aSet ]. followSet addAll: (firstSet reject: [ :each | each isNullable ]) ] ]! ! !PPSequenceParser methodsFor: 'operators-mapping' stamp: 'lr 5/6/2011 20:27'! map: aBlock ^ aBlock numArgs = self children size ifTrue: [ self ==> [ :nodes | aBlock valueWithArguments: nodes ] ] ifFalse: [ self error: aBlock numArgs asString , ' arguments expected.' ]! ! !PPSequenceParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/17/2009 21:54'! morphicShapeSeen: aSet depth: anInteger ^ self morphicShapeSeen: aSet depth: anInteger do: [ :cc | self children inject: self newRowMorph into: [ :result :each | result addMorphBack: (cc value: each); yourself ] ]! ! !PPSequenceParser methodsFor: 'parsing' stamp: 'lr 5/6/2010 10:47'! parseOn: aStream "This is optimized code that avoids unnecessary block activations, do not change." | start elements element | start := aStream position. elements := Array new: parsers size. 1 to: parsers size do: [ :index | element := (parsers at: index) parseOn: aStream. element isPetitFailure ifTrue: [ aStream position: start. ^ element ]. elements at: index put: element ]. ^ elements! ! !PPSequenceParser methodsFor: 'operators-mapping' stamp: 'lr 1/8/2010 12:01'! permutation: anArrayOfIntegers "Answer a permutation of the receivers sequence." anArrayOfIntegers do: [ :index | (index isInteger and: [ index between: 1 and: parsers size ]) ifFalse: [ self error: 'Invalid permutation index: ' , index printString ] ]. ^ self ==> [ :nodes | anArrayOfIntegers collect: [ :index | nodes at: index ] ]! ! !PPLiteralParser commentStamp: '' prior: 34297157! Abstract literal parser that parses some kind of literal type (to be specified by subclasses). Instance Variables: literal The literal object to be parsed. message The error message to be generated. ! !PPLiteralObjectParser commentStamp: '' prior: 34297441! A parser that accepts a single literal object, such as a character. This is the same as the predicate parser 'PPPredicateParser expect: literal' but slightly more efficient.! !PPLiteralObjectParser methodsFor: 'operators' stamp: 'lr 8/18/2010 20:16'! caseInsensitive "Answer a parser that can parse the receiver case-insensitive." literal asUppercase = literal asLowercase ifTrue: [ ^ self ]. ^ PPPredicateObjectParser on: [ :value | literal sameAs: value ] message: message! ! !PPLiteralObjectParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:25'! exampleOn: aStream aStream nextPut: literal! ! !PPLiteralObjectParser methodsFor: 'operators' stamp: 'lr 4/28/2011 20:02'! negate ^ (PPPredicateObjectParser expect: literal message: message) negate! ! !PPLiteralObjectParser methodsFor: 'parsing' stamp: 'lr 10/30/2010 11:48'! parseOn: aStream ^ (aStream atEnd not and: [ literal = aStream uncheckedPeek ]) ifFalse: [ PPFailure message: message at: aStream position ] ifTrue: [ aStream next ]! ! !PPLiteralParser class methodsFor: 'instance creation' stamp: 'lr 1/7/2010 15:30'! on: anObject ^ self on: anObject message: anObject printString , ' expected'! ! !PPLiteralParser class methodsFor: 'instance creation' stamp: 'lr 1/7/2010 15:29'! on: anObject message: aString ^ self new initializeOn: anObject message: aString! ! !PPLiteralParser methodsFor: 'operators' stamp: 'lr 6/1/2010 22:24'! caseInsensitive "Answer a parser that can parse the receiver case-insensitive." self subclassResponsibility! ! !PPLiteralParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:19'! displayName ^ literal printString! ! !PPLiteralParser methodsFor: 'initialization' stamp: 'lr 5/2/2010 13:25'! initializeOn: anObject message: aString literal := anObject. message := aString! ! !PPLiteralParser methodsFor: 'accessing' stamp: 'lr 5/2/2010 13:26'! literal "Answer the parsed literal." ^ literal! ! !PPLiteralParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 9/15/2010 12:08'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self literal = aParser literal and: [ self message = aParser message ] ]! ! !PPLiteralParser methodsFor: 'accessing' stamp: 'lr 5/2/2010 13:26'! message "Answer the failure message." ^ message! ! !PPLiteralParser methodsFor: 'printing' stamp: 'lr 4/16/2010 16:38'! printNameOn: aStream super printNameOn: aStream. aStream nextPutAll: ', '; print: literal! ! !PPLiteralSequenceParser commentStamp: 'lr 12/4/2009 18:39' prior: 34297686! A parser accepts a sequence of literal objects, such as a String. This is an optimization to avoid having to compose longer sequences from PPSequenceParser.! !PPLiteralSequenceParser methodsFor: 'operators' stamp: 'lr 8/18/2010 20:16'! caseInsensitive "Answer a parser that can parse the receiver case-insensitive." literal asUppercase = literal asLowercase ifTrue: [ ^ self ]. ^ PPPredicateSequenceParser on: [ :value | literal sameAs: value ] message: message size: size! ! !PPLiteralSequenceParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:25'! exampleOn: aStream aStream nextPutAll: literal! ! !PPLiteralSequenceParser methodsFor: 'initialization' stamp: 'lr 6/1/2010 22:21'! initializeOn: anObject message: aString super initializeOn: anObject message: aString. size := literal size! ! !PPLiteralSequenceParser methodsFor: 'parsing' stamp: 'lr 10/30/2010 11:48'! parseOn: aStream | position result | position := aStream position. result := aStream next: size. literal = result ifTrue: [ ^ result ]. aStream position: position. ^ PPFailure message: message at: aStream position! ! !PPLiteralSequenceParser methodsFor: 'accessing' stamp: 'lr 9/15/2010 11:16'! size "Answer the sequence size of the receiver." ^ size! ! !PPParser class methodsFor: 'instance creation' stamp: 'lr 10/27/2008 11:17'! named: aString ^ self new name: aString! ! !PPParser class methodsFor: 'instance creation' stamp: 'lr 4/18/2008 14:00'! new ^ self basicNew initialize! ! !PPParser methodsFor: 'operators' stamp: 'lr 9/23/2008 18:32'! , aParser "Answer a new parser that parses the receiver followed by aParser." ^ PPSequenceParser with: self with: aParser! ! !PPParser methodsFor: 'operators' stamp: 'lr 4/14/2010 11:46'! / aParser "Answer a new parser that parses the receiver, if the receiver fails try with aParser (ordered-choice)." ^ PPChoiceParser with: self with: aParser! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 5/12/2010 20:32'! ==> aBlock "Answer a new parser that performs aBlock as action handler on success." ^ PPActionParser on: self block: aBlock! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 6/12/2010 10:20'! >=> aBlock "Answer a new parser that wraps the receiving parser with a two argument block. The first argument is the parsed stream, the second argument a continuation block on the delegate parser." ^ PPWrappingParser on: self block: aBlock! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 11/23/2010 10:01'! allNamedParsers "Answer all the named parse nodes of the receiver." | result | result := OrderedCollection new. self allNamedParsersDo: [ :parser | result addLast: parser ]. ^ result! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 11/23/2010 10:12'! allNamedParsersDo: aBlock "Iterate over all the named parse nodes of the receiver." self allParsersDo: [ :each | each name notNil ifTrue: [ aBlock value: each ] ]! ! !PPParser methodsFor: '*petitanalyzer-enumerating' stamp: 'lr 4/13/2010 08:36'! allParsers "Answer all the parse nodes of the receiver." | result | result := OrderedCollection new. self allParsersDo: [ :parser | result addLast: parser ]. ^ result! ! !PPParser methodsFor: '*petitanalyzer-enumerating' stamp: 'lr 4/13/2010 08:36'! allParsersDo: aBlock "Iterate over all the parse nodes of the receiver." self allParsersDo: aBlock seen: IdentitySet new! ! !PPParser methodsFor: '*petitanalyzer-enumerating' stamp: 'lr 4/13/2010 08:35'! allParsersDo: aBlock seen: aSet "Iterate over all the parse nodes of the receiver, do not visit and follow the ones contained in aSet." (aSet includes: self) ifTrue: [ ^ self ]. aSet add: self. aBlock value: self. self children do: [ :each | each allParsersDo: aBlock seen: aSet ]! ! !PPParser methodsFor: 'operators' stamp: 'lr 5/31/2010 15:12'! and "Answer a new parser (logical and-predicate) that succeeds whenever the receiver does, but never consumes input." ^ PPAndParser on: self! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 2/19/2010 07:42'! answer: anObject "Answer a new parser that always returns anObject from a successful parse." ^ self ==> [ :nodes | anObject ]! ! !PPParser methodsFor: 'converting' stamp: 'lr 11/29/2011 20:48'! asParser "Answer the receiving parser." ^ self! ! !PPParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:11'! backgroundForDepth: anInteger ^ Color gray: 1.0 - (anInteger / 20.0)! ! !PPParser methodsFor: 'accessing' stamp: 'lr 10/21/2009 16:38'! children "Answer a set of child parsers that could follow the receiver." ^ #()! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 4/30/2010 07:49'! copyInContext: aDictionary ^ self copyInContext: aDictionary seen: IdentityDictionary new! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 7/17/2011 11:53'! copyInContext: aDictionary seen: aSeenDictionary | copy | aSeenDictionary at: self ifPresent: [ :value | ^ value ]. copy := aSeenDictionary at: self put: self copy. copy children do: [ :each | copy replace: each with: (each copyInContext: aDictionary seen: aSeenDictionary) ]. ^ copy! ! !PPParser methodsFor: '*petitanalyzer-querying' stamp: 'lr 11/19/2009 23:49'! cycleSet "Answer a set of all nodes that are within one or more cycles of left-recursion. This is generally not a problem if at least one of the nodes is memoized, but it might make the grammar very inefficient and should be avoided if possible." | cycles | cycles := IdentitySet new. self cycleSet: OrderedCollection new firstSets: self firstSets into: cycles. ^ cycles! ! !PPParser methodsFor: '*petitanalyzer-private' stamp: 'lr 11/19/2009 23:47'! cycleSet: aDictionary "PRIVATE: Answer the children that could be part of a cycle-set with the receiver, subclasses might restrict the number of children returned. aDictionary is pre-calcualted first-sets." ^ self children! ! !PPParser methodsFor: '*petitanalyzer-private' stamp: 'lr 5/22/2010 10:45'! cycleSet: aStack firstSets: aDictionary into: aSet "PRIVATE: Try to find a cycle, where aStack contains the previously visited parsers. The method returns quickly when the receiver is a terminal, terminals cannot be part of a cycle. If aStack already contains the receiver, then we are in a cycle. In this case we don't process the children further and add the nodes to aSet." | index | self isTerminal ifTrue: [ ^ self ]. (index := aStack indexOf: self) > 0 ifTrue: [ ^ aSet addAll: (aStack copyFrom: index to: aStack size) ]. aStack addLast: self. (self cycleSet: aDictionary) do: [ :each | each cycleSet: aStack firstSets: aDictionary into: aSet ]. aStack removeLast! ! !PPParser methodsFor: 'operators' stamp: 'lr 12/3/2010 11:34'! def: aParser "Redefine the receiver as the argument aParser. This method is useful when defining recursive parsers: instantiate a PPUnresolvedParser and later redefine it with another one." ^ self becomeForward: (aParser name: self name)! ! !PPParser methodsFor: 'operators-convenience' stamp: 'lr 2/19/2010 07:42'! delimitedBy: aParser "Answer a new parser that parses the receiver one or more times, separated and possibly ended by aParser." ^ (self separatedBy: aParser) , (aParser optional) ==> [ :node | node second isNil ifTrue: [ node first ] ifFalse: [ node first copyWith: node second ] ]! ! !PPParser methodsFor: '*petitgui-accessing' stamp: 'lr 9/12/2011 18:34'! displayColor ^ self isTerminal ifTrue: [ Color r: 0.5 g: 0.0 b: 0.5 ] ifFalse: [ Color blue ]! ! !PPParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/6/2009 18:31'! displayName ^ self name isNil ifFalse: [ self name asString ] ifTrue: [ self class name asString ]! ! !PPParser methodsFor: 'operators' stamp: 'lr 4/30/2010 12:13'! end "Answer a new parser that succeeds at the end of the input and return the result of the receiver." ^ PPEndOfInputParser on: self! ! !PPParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:37'! example ^ String streamContents: [ :stream | self exampleOn: stream ] limitedTo: 1024! ! !PPParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/9/2009 14:20'! exampleOn: aStream! ! !PPParser methodsFor: '*petitanalyzer-querying' stamp: 'lr 10/22/2009 19:59'! firstSet "Answer the first-set of the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #firstSets to calculate the first-sets at once." ^ self firstSets at: self! ! !PPParser methodsFor: '*petitanalyzer-querying' stamp: 'JanKurs 5/31/2013 11:49'! firstSets "Answer a dictionary with all the parsers reachable from the receiver as key and their first-set as value. The first-set of a parser is the list of terminal parsers that begin the parser derivable from that parser." | firstSets | firstSets := IdentityDictionary new. self allParsersDo: [ :each | firstSets at: each put: (each isFirstSetTerminal ifTrue: [ IdentitySet with: each ] ifFalse: [ IdentitySet new ]). each isNullable ifTrue: [ (firstSets at: each) add: PPSentinel instance ] ]. [ | changed tally | changed := false. firstSets keysAndValuesDo: [ :parser :first | tally := first size. parser firstSets: firstSets into: first. changed := changed or: [ tally ~= first size ] ]. changed ] whileTrue. ^ firstSets! ! !PPParser methodsFor: '*petitanalyzer-private' stamp: 'lr 11/12/2009 21:25'! firstSets: aFirstDictionary into: aSet "PRIVATE: Try to add additional elements to the first-set aSet of the receiver, use the incomplete aFirstDictionary." self children do: [ :parser | aSet addAll: (aFirstDictionary at: parser) ]! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 5/15/2008 16:08'! flatten "Answer a new parser that flattens the underlying collection." ^ PPFlattenParser on: self! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 4/3/2011 15:00'! foldLeft: aBlock "Answer a new parser that that folds the result of the receiver from left-to-right into aBlock. The argument aBlock must take two or more arguments." | size args | size := aBlock numArgs. args := Array new: size. ^ self ==> [ :nodes | args at: 1 put: nodes first. 2 to: nodes size by: size - 1 do: [ :index | args replaceFrom: 2 to: size with: nodes startingAt: index; at: 1 put: (aBlock valueWithArguments: args) ]. args first ]! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 4/3/2011 14:59'! foldRight: aBlock "Answer a new parser that that folds the result of the receiver from right-to-left into aBlock. The argument aBlock must take two or more arguments." | size args | size := aBlock numArgs. args := Array new: size. ^ self ==> [ :nodes | args at: size put: nodes last. nodes size - size + 1 to: 1 by: 1 - size do: [ :index | args replaceFrom: 1 to: size - 1 with: nodes startingAt: index; at: size put: (aBlock valueWithArguments: args) ]. args at: size ]! ! !PPParser methodsFor: '*petitanalyzer-querying' stamp: 'lr 11/12/2009 21:13'! followSet "Answer the follow-set of the receiver starting at the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #followSets to calculate the follow-sets at once." ^ self followSets at: self! ! !PPParser methodsFor: '*petitanalyzer-querying' stamp: 'lr 9/16/2010 17:55'! followSets "Answer a dictionary with all the parsers reachable from the receiver as key and their follow-set as value. The follow-set of a parser is the list of terminal parsers that can appear immediately to the right of that parser." | current previous continue firstSets followSets | current := previous := 0. firstSets := self firstSets. followSets := IdentityDictionary new. self allParsersDo: [ :each | followSets at: each put: IdentitySet new ]. (followSets at: self) add: PPSentinel instance. [ followSets keysAndValuesDo: [ :parser :follow | parser followSets: followSets firstSets: firstSets into: follow ]. current := followSets inject: 0 into: [ :result :each | result + each size ]. continue := previous < current. previous := current. continue ] whileTrue. ^ followSets! ! !PPParser methodsFor: '*petitanalyzer-private' stamp: 'lr 11/12/2009 21:25'! followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet "PRIVATE: Try to add additional elements to the follow-set aSet of the receiver, use the incomplete aFollowDictionary and the complete aFirstDictionary." self children do: [ :parser | (aFollowDictionary at: parser) addAll: aSet ]! ! !PPParser methodsFor: '*petitgui' stamp: 'TudorGirba 11/25/2012 20:41'! gtInspectorParserInspectorIn: composite composite custom: ( PPParserInspector new title: 'Inspector'; startOn: self)! ! !PPParser methodsFor: '*petitgui' stamp: 'TudorGirba 6/24/2013 23:44'! gtNamedTreeViewIn: composite composite tree title: 'Named Tree'; children: [:n | n namedChildren ]; format: [:n| n name ifNil: [ n asString ] ]; shouldExpandToLevel: 3! ! !PPParser methodsFor: '*petitgui' stamp: 'TudorGirba 6/24/2013 23:44'! gtTreeViewIn: composite composite tree title: 'Tree'; children: [:n | n children ]; format: [:n| n name ifNil: [ n asString ] ifNotNil: [n name] ]; shouldExpandToLevel: 6! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:32'! hasProperty: aKey "Test if the property aKey is present." ^ properties notNil and: [ properties includesKey: aKey ]! ! !PPParser methodsFor: 'initialization' stamp: 'lr 4/24/2008 10:33'! initialize! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 12/3/2010 16:45'! innerChildren "Answer the inner children of the receiver." | result | result := OrderedCollection new. self innerChildrenDo: [ :parser | result addLast: parser ]. ^ result! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 12/3/2010 16:48'! innerChildrenDo: aBlock "Iterate over the inner children of the receiver." self innerChildrenDo: aBlock seen: IdentitySet new! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 12/3/2010 16:51'! innerChildrenDo: aBlock seen: aSet "Iterate over the inner children of the receiver." self children do: [ :each | (aSet includes: each) ifTrue: [ ^ self ]. aSet add: each. each name isNil ifTrue: [ aBlock value: each. each innerChildrenDo: aBlock seen: aSet ] ]! ! !PPParser methodsFor: '*petitanalyzer-testing' stamp: 'JanKurs 5/31/2013 11:49'! isFirstSetTerminal "Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." ^ self children isEmpty! ! !PPParser methodsFor: '*petitanalyzer-testing' stamp: 'lr 11/12/2009 17:25'! isNullable "Answer true if the receiver is a nullable parser, e.g. it can successfully parse nothing." ^ false! ! !PPParser methodsFor: 'testing' stamp: 'lr 8/6/2010 16:44'! isPetitParser ^ true! ! !PPParser methodsFor: '*petitanalyzer-testing' stamp: 'lr 5/22/2010 10:45'! isTerminal "Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser." ^ self children isEmpty! ! !PPParser methodsFor: 'testing' stamp: 'lr 10/27/2008 11:28'! isUnresolved ^ false! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 5/6/2011 20:28'! map: aBlock "Answer a new parser that works on the receiving sequence an passes in each element as a block argument." ^ aBlock numArgs = 1 ifTrue: [ self ==> aBlock ] ifFalse: [ self error: aBlock numArgs asString , ' arguments expected.' ] ! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 4/29/2010 23:14'! match: aParser inContext: aDictionary ^ self match: aParser inContext: aDictionary seen: IdentitySet new! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 6/18/2010 14:09'! match: aParser inContext: aDictionary seen: anIdentitySet "This is the default implementation to match two parsers. This code can properly handle recursion. This is code is supposed to be overridden in subclasses that add new state." (self == aParser or: [ anIdentitySet includes: self ]) ifTrue: [ ^ true ]. anIdentitySet add: self. ^ self class = aParser class and: [ self matchList: self children against: aParser children inContext: aDictionary seen: anIdentitySet ]! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 4/29/2010 23:07'! matchList: matchList against: parserList inContext: aDictionary seen: aSet ^ self matchList: matchList index: 1 against: parserList index: 1 inContext: aDictionary seen: aSet! ! !PPParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 5/31/2010 18:37'! matchList: matchList index: matchIndex against: parserList index: parserIndex inContext: aDictionary seen: aSet | parser currentIndex currentDictionary currentSeen parsers | matchList size < matchIndex ifTrue: [ ^ parserList size < parserIndex ]. parser := matchList at: matchIndex. parser class = PPListPattern ifTrue: [ currentIndex := parserIndex - 1. [ currentDictionary := aDictionary copy. currentSeen := aSet copy. parserList size < currentIndex or: [ parsers := parserList copyFrom: parserIndex to: currentIndex. (currentDictionary at: parser ifAbsentPut: [ parsers ]) = parsers and: [ (self matchList: matchList index: matchIndex + 1 against: parserList index: currentIndex + 1 inContext: currentDictionary seen: currentSeen) ifTrue: [ currentDictionary keysAndValuesDo: [ :key :value | aDictionary at: key put: value ]. ^ true ]. false ] ] ] whileFalse: [ currentIndex := currentIndex + 1 ]. ^ false ]. parserList size < parserIndex ifTrue: [ ^ false ]. (parser match: (parserList at: parserIndex) inContext: aDictionary seen: aSet) ifFalse: [ ^ false ]. ^ self matchList: matchList index: matchIndex + 1 against: parserList index: parserIndex + 1 inContext: aDictionary seen: aSet! ! !PPParser methodsFor: 'parsing' stamp: 'lr 2/8/2010 00:30'! matches: anObject "Answer if anObject can be parsed by the receiver." ^ (self parse: anObject) isPetitFailure not! ! !PPParser methodsFor: 'parsing' stamp: 'lr 6/4/2011 18:12'! matchesIn: anObject "Search anObject repeatedly for the matches of the receiver. Answered an OrderedCollection of the matched parse-trees." | result | result := OrderedCollection new. self matchesIn: anObject do: [ :each | result addLast: each ]. ^ result! ! !PPParser methodsFor: 'parsing' stamp: 'lr 3/1/2010 21:51'! matchesIn: anObject do: aBlock "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Make sure to always consume exactly one character with each step, to not miss any match." ((self and ==> aBlock , #any asParser) / #any asParser) star parse: anObject! ! !PPParser methodsFor: 'parsing' stamp: 'lr 8/16/2011 07:26'! matchesSkipIn: anObject "Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of the matched parse-trees. Skip over matches." | result | result := OrderedCollection new. self matchesSkipIn: anObject do: [ :each | result addLast: each ]. ^ result! ! !PPParser methodsFor: 'parsing' stamp: 'lr 8/16/2011 07:26'! matchesSkipIn: anObject do: aBlock "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Skip over matches." (self ==> aBlock / #any asParser) star parse: anObject! ! !PPParser methodsFor: 'parsing' stamp: 'lr 6/4/2011 18:12'! matchingRangesIn: anObject "Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)." | result | result := OrderedCollection new. self matchingRangesIn: anObject do: [ :value | result addLast: value ]. ^ result! ! !PPParser methodsFor: 'parsing' stamp: 'lr 2/25/2013 23:41'! matchingRangesIn: anObject do: aBlock "Search anObject repeatedly for the matches of the receiver. Evaluate aBlock with the range of each match (index of first character to: index of last character)." self token matchesIn: anObject do: [ :token | aBlock value: (token start to: token stop) ]! ! !PPParser methodsFor: 'parsing' stamp: 'DamienCassou 10/29/2011 19:18'! matchingSkipRangesIn: anObject "Search anObject repeatedly for the matches of the receiver. Skip over matches. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)." | result | result := OrderedCollection new. self matchingSkipRangesIn: anObject do: [ :value | result addLast: value ]. ^ result! ! !PPParser methodsFor: 'parsing' stamp: 'lr 2/25/2013 23:42'! matchingSkipRangesIn: anObject do: aBlock "Search anObject repeatedly for the matches of the receiver. Skip over matches. Evaluate aBlock with the range of each match (index of first character to: index of last character)." self token matchesSkipIn: anObject do: [ :token | aBlock value: (token start to: token stop) ]! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:03'! max: anInteger "Answer a new parser that parses the receiver at most anInteger times." ^ self star setMax: anInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:56'! max: anInteger greedy: aParser "Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." ^ (self starGreedy: aParser) setMax: anInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:57'! max: anInteger lazy: aParser "Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed." ^ (self starLazy: aParser) setMax: anInteger! ! !PPParser methodsFor: 'operators' stamp: 'lr 5/31/2010 16:34'! memoized "Answer a new memoized parser, for refraining redundant computations. This ensures polynomial time O(n^4) for left-recursive grammars and O(n^3) for non left-recursive grammars in the worst case. Not necessary for most grammars that are carefully written and in O(n) anyway." ^ PPMemoizedParser on: self! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:02'! min: anInteger "Answer a new parser that parses the receiver at least anInteger times." ^ self star setMin: anInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:56'! min: anInteger greedy: aParser "Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." ^ (self starGreedy: aParser) setMin: anInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:57'! min: anInteger lazy: aParser "Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed." ^ (self starLazy: aParser) setMin: anInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:03'! min: aMinInteger max: aMaxInteger "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times." ^ self star setMin: aMinInteger; setMax: aMaxInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:56'! min: aMinInteger max: aMaxInteger greedy: aParser "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." ^ (self starGreedy: aParser) setMin: aMinInteger; setMax: aMaxInteger! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/3/2011 14:57'! min: aMinInteger max: aMaxInteger lazy: aParser "Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed." ^ (self starLazy: aParser) setMin: aMinInteger; setMax: aMaxInteger! ! !PPParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/18/2009 10:56'! morphicProduction ^ self newRowMorph layoutInset: 4; addMorphBack: (self newRowMorph layoutInset: 4; addMorphBack: (StringMorph new contents: self displayName; emphasis: TextEmphasis bold emphasisCode; yourself); yourself); addMorphBack: (self morphicShapeSeen: IdentitySet new depth: 0); addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) makeForwardArrow; yourself); yourself! ! !PPParser methodsFor: '*petitgui-morphic' stamp: 'lr 1/30/2013 19:35'! morphicShapeDefault ^ self newRowMorph addMorphBack: (self newColumnMorph addMorphBack: (self newSpacerMorph); addMorphBack: (LineMorph from: 0 @ 0 to: 20 @ 0 color: Color black width: 1) makeForwardArrow; yourself); addMorphBack: (self newRowMorph borderWidth: 1; layoutInset: 3; color: Color white; addMorphBack: (StringMorph new contents: self displayName; color: self displayColor; yourself); yourself); yourself! ! !PPParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/13/2009 13:24'! morphicShapeSeen: aSet depth: anInteger ^ self morphicShapeDefault! ! !PPParser methodsFor: '*petitgui-morphic' stamp: 'lr 11/13/2009 13:43'! morphicShapeSeen: aSet depth: anInteger do: aBlock " avoid recursion " (aSet includes: self) ifTrue: [ ^ self morphicShapeDefault ]. " display nice name when possible " (anInteger > 0 and: [ self name notNil ]) ifTrue: [ ^ self morphicShapeDefault ]. " don't do it too deep " (anInteger > 10) ifTrue: [ ^ self morphicShapeDefault ]. aSet add: self. ^ aBlock value: [ :parser | parser morphicShapeSeen: aSet depth: anInteger + 1 ]! ! !PPParser methodsFor: 'accessing' stamp: 'lr 4/19/2010 10:35'! name "Answer the production name of the receiver." ^ self propertyAt: #name ifAbsent: [ nil ]! ! !PPParser methodsFor: 'accessing' stamp: 'lr 4/19/2010 10:38'! name: aString self propertyAt: #name put: aString! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 11/23/2010 10:55'! namedChildren "Answer the named children of the receiver." | result | result := OrderedCollection new. self namedChildrenDo: [ :parser | result addLast: parser ]. ^ result! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 11/23/2010 10:55'! namedChildrenDo: aBlock "Iterate over the named children of the receiver." self namedChildrenDo: aBlock seen: IdentitySet new! ! !PPParser methodsFor: '*petitanalyzer-named' stamp: 'lr 11/23/2010 10:55'! namedChildrenDo: aBlock seen: aSet "Iterate over the named children of the receiver." self children do: [ :each | (aSet includes: each) ifTrue: [ ^ self ]. aSet add: each. each name isNil ifTrue: [ each namedChildrenDo: aBlock seen: aSet ] ifFalse: [ aBlock value: each ] ]! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'tg 8/25/2010 00:31'! namedParsers | result | result := OrderedCollection new. self namedParsersDo: [ :parser | result addLast: parser ]. ^ result! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'tg 8/25/2010 00:32'! namedParsersDo: aBlock self namedParsersDo: aBlock seen: IdentitySet new! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'TudorGirba 12/14/2011 12:40'! namedParsersDo: aBlock seen: aSet self children do: [ :each | (aSet includes: each) ifFalse: [ aSet add: each. each name isEmptyOrNil ifFalse: [ aBlock value: each ] ifTrue: [ each namedParsersDo: aBlock seen: aSet ] ] ]! ! !PPParser methodsFor: 'operators' stamp: 'lr 2/19/2010 07:36'! negate "Answer a new parser consumes any input token but the receiver." ^ self not , #any asParser ==> #second! ! !PPParser methodsFor: '*petitgui-morphic-creational' stamp: 'lr 11/17/2009 21:58'! newColumnMorph ^ AlignmentMorph newColumn cellPositioning: #topLeft; color: Color transparent; listCentering: #topLeft; vResizing: #shrinkWrap; hResizing: #shrinkWrap; layoutInset: 0; yourself! ! !PPParser methodsFor: '*petitgui-morphic-creational' stamp: 'lr 11/17/2009 21:57'! newRowMorph ^ AlignmentMorph newRow cellPositioning: #topLeft; color: Color transparent; listCentering: #topLeft; vResizing: #shrinkWrap; hResizing: #shrinkWrap; layoutInset: 0; yourself! ! !PPParser methodsFor: '*petitgui-morphic-creational' stamp: 'lr 11/17/2009 22:03'! newSpacerMorph ^ Morph new color: Color transparent; borderWidth: 0; extent: 7 @ 7; yourself! ! !PPParser methodsFor: 'operators' stamp: 'lr 5/31/2010 15:12'! not "Answer a new parser (logical not-predicate) that succeeds whenever the receiver fails, but never consumes input." ^ PPNotParser on: self! ! !PPParser methodsFor: 'operators' stamp: 'lr 9/1/2010 22:03'! optional "Answer a new parser that parses the receiver, if possible." ^ PPOptionalParser on: self! ! !PPParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:53'! parse: anObject "Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure." ^ self parseOn: anObject asPetitStream! ! !PPParser methodsFor: 'parsing' stamp: 'lr 10/29/2010 17:05'! parse: anObject onError: aBlock "Parse anObject with the receiving parser and answer the parse-result or answer the result of evaluating aBlock. Depending on the number of arguments of the block it is simply evaluated, evaluated with the failure object, or evaluated with the error message and position." | result | result := self parse: anObject. result isPetitFailure ifFalse: [ ^ result ]. aBlock numArgs = 0 ifTrue: [ ^ aBlock value ]. aBlock numArgs = 1 ifTrue: [ ^ aBlock value: result ]. ^ aBlock value: result message value: result position! ! !PPParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 22:18'! parseOn: aStream "Parse aStream with the receiving parser and answer the parse-result or an instance of PPFailure. Override this method in subclasses to specify custom parse behavior. Do not call this method from outside, instead use #parse:." self subclassResponsibility! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:03'! plus "Answer a new parser that parses the receiver one or more times." ^ self star setMin: 1! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:04'! plusGreedy: aParser "Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed." ^ (self starGreedy: aParser) setMin: 1! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/1/2011 21:04'! plusLazy: aParser "Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed." ^ (self starLazy: aParser) setMin: 1! ! !PPParser methodsFor: 'copying' stamp: 'lr 4/19/2010 10:33'! postCopy super postCopy. properties := properties copy! ! !PPParser methodsFor: 'printing' stamp: 'lr 4/16/2010 16:36'! printNameOn: aStream self name isNil ifTrue: [ aStream print: self hash ] ifFalse: [ aStream nextPutAll: self name ]! ! !PPParser methodsFor: 'printing' stamp: 'lr 4/16/2010 16:36'! printOn: aStream super printOn: aStream. aStream nextPut: $(. self printNameOn: aStream. aStream nextPut: $)! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:32'! propertyAt: aKey "Answer the property value associated with aKey." ^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ]! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:32'! propertyAt: aKey ifAbsent: aBlock "Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock." ^ properties isNil ifTrue: [ aBlock value ] ifFalse: [ properties at: aKey ifAbsent: aBlock ]! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:32'! propertyAt: aKey ifAbsentPut: aBlock "Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value." ^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:33'! propertyAt: aKey put: anObject "Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject." ^ (properties ifNil: [ properties := Dictionary new: 1 ]) at: aKey put: anObject! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:33'! removeProperty: aKey "Remove the property with aKey. Answer the property or raise an error if aKey isn't found." ^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ]! ! !PPParser methodsFor: 'accessing-properties' stamp: 'lr 4/19/2010 10:33'! removeProperty: aKey ifAbsent: aBlock "Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock." | answer | properties isNil ifTrue: [ ^ aBlock value ]. answer := properties removeKey: aKey ifAbsent: aBlock. properties isEmpty ifTrue: [ properties := nil ]. ^ answer! ! !PPParser methodsFor: '*petitanalyzer-transforming' stamp: 'lr 4/13/2010 09:38'! replace: aParser with: anotherParser "Replace the references of the receiver pointing to aParser with anotherParser."! ! !PPParser methodsFor: 'operators-convenience' stamp: 'lr 2/19/2010 07:56'! separatedBy: aParser "Answer a new parser that parses the receiver one or more times, separated by aParser." ^ (PPSequenceParser with: self with: (PPSequenceParser with: aParser with: self) star) ==> [ :nodes | | result | result := Array new: 2 * nodes second size + 1. result at: 1 put: nodes first. nodes second keysAndValuesDo: [ :index :pair | result replaceFrom: 2 * index to: 2 * index + 1 with: pair startingAt: 1 ]. result ]! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/2/2011 10:02'! star "Answer a new parser that parses the receiver zero or more times. This is a greedy and blind implementation that tries to consume as much input as possible and it does not consider what comes afterwards." ^ PPPossessiveRepeatingParser on: self! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/2/2011 10:01'! starGreedy: aParser "Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed." ^ PPGreedyRepeatingParser on: self limit: aParser! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 4/2/2011 10:01'! starLazy: aParser "Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed." ^ PPLazyRepeatingParser on: self limit: aParser! ! !PPParser methodsFor: 'operators-repeating' stamp: 'lr 9/15/2010 09:34'! times: anInteger "Answer a new parser that parses the receiver exactly anInteger times." ^ self min: anInteger max: anInteger! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 6/29/2010 14:25'! token "Answer a new parser that transforms the input to a token." ^ PPTokenParser on: self! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 4/6/2010 19:26'! token: aTokenClass "Answer a new parser that transforms the input to a token of class aTokenClass." ^ self token tokenClass: aTokenClass! ! !PPParser methodsFor: '*petitanalyzer-transforming' stamp: 'lr 10/30/2010 11:54'! transform: aBlock "Answer a copy of all parsers reachable from the receiver transformed using aBlock." | mapping root | mapping := IdentityDictionary new. self allParsersDo: [ :each | mapping at: each put: (aBlock value: each copy) ]. root := mapping at: self. [ | changed | changed := false. root allParsersDo: [ :each | each children do: [ :old | mapping at: old ifPresent: [ :new | each replace: old with: new. changed := true ] ] ]. changed ] whileTrue. ^ root! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 7/31/2010 12:06'! trim "Answer a new parser that consumes spaces before and after the receiving parser." ^ self trimSpaces! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 7/11/2011 11:03'! trim: aParser "Answer a new parser that consumes and ignores aParser repeatedly before and after the receiving parser." ^ PPTrimmingParser on: self trimmer: aParser! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 7/11/2011 11:03'! trimBlanks "Answer a new parser that consumes blanks before and after the receiving parser." ^ self trim: #blank asParser! ! !PPParser methodsFor: 'operators-mapping' stamp: 'lr 7/11/2011 11:03'! trimSpaces "Answer a new parser that consumes spaces before and after the receiving parser." ^ self trim: #space asParser! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'TudorGirba 6/5/2013 23:01'! viewAllNamedParsers | view | view := ROMondrianViewBuilder new. self viewAllNamedParsersOn: view. ^ view open setLabel: 'All named parsers'! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'JurajKubelka 5/30/2013 13:55'! viewAllNamedParsersOn: view view shape rectangleWithoutBorder; withText: #displayName. view nodes: (self allParsers select: [:each | each name isEmptyOrNil not ]). view edgesToAll: #namedParsers. view horizontalDominanceTreeLayout layered! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'TudorGirba 12/6/2011 07:43'! viewAllNamedParsersWithSelection: aCollectionOfNames on: view self viewAllNamedParsersWithSelection: aCollectionOfNames previewing: [ :each | each name ] on: view! ! !PPParser methodsFor: '*petitgui-mondrian' stamp: 'TudorGirba 10/18/2012 09:38'! viewAllNamedParsersWithSelection: aCollectionOfNames previewing: aBlock on: view view shape label color: [:each | (aCollectionOfNames includes: each name) ifFalse: [Color black] ifTrue: [Color red]]; text: [:each |each displayName]. view interaction popupText: aBlock. view interaction item: 'Explore' action: #explore. view nodes: (self allParsers select: [:each | each name isEmptyOrNil not ]). view edges: (self allParsers select: [:each | each name isEmptyOrNil not ])from: #yourself toAll: #namedParsers. view horizontalDominanceTreeLayout verticalGap: 10; layered! ! !PPParser methodsFor: 'operators-convenience' stamp: 'lr 2/25/2012 16:54'! withoutSeparators "Filters out the separators from a parse result produced by one of the productions #delimitedBy: or #separatedBy:." ^ self ==> [ :items | | result | result := Array new: items size + 1 // 2. 1 to: result size do: [ :index | result at: index put: (items at: 2 * index - 1) ]. result ]! ! !PPParser methodsFor: 'operators' stamp: 'lr 10/23/2008 14:05'! wrapped "Answer a new parser that is simply wrapped." ^ PPDelegateParser on: self! ! !PPParser methodsFor: 'operators' stamp: 'lr 4/14/2010 11:53'! | aParser "Answer a new parser that either parses the receiver or aParser. Fail if both pass or fail (exclusive choice, unordered choice)." ^ (self not , aParser) / (aParser not , self) ==> #second! ! !PPPattern commentStamp: '' prior: 34297894! PPPattern is meta-parser that is solely used to match other types of parsers. It cannot be used for actually parsing something. The constructor method determines what can be matched.! !PPListPattern commentStamp: '' prior: 34298132! PPListPattern that is used to match any number of parsers. As its superclass, it cannot be used for actually parsing something.! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 4/30/2010 08:47'! any "Matches all parsers." ^ self on: [ :parser :context | true ]! ! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 3/16/2013 21:45'! class: aBehavior "Matches parsers that are of the class aBehavior." ^ self on: [ :parser :context | parser class = aBehavior ]! ! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 3/16/2013 21:45'! kind: aBehavior "Matches parsers that are of the class aBehavior or one of its subclasses." ^ self on: [ :parser :context | parser isKindOf: aBehavior ]! ! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 4/30/2010 08:46'! name: aString "Matches parsers with the name aString." ^ self on: [ :parser :context | parser name = aString ]! ! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 10:21'! new self error: 'Use an explicit constructur on ' , self name! ! !PPPattern class methodsFor: 'instance creation' stamp: 'lr 4/30/2010 08:46'! on: aBlock "Matches parsers that satisfy an arbitrary condition in aBlock." ^ self basicNew initializeOn: aBlock! ! !PPPattern methodsFor: 'comparing' stamp: 'lr 4/29/2010 10:33'! = aParser ^ self == aParser or: [ self name notNil and: [ self name = aParser name ] ]! ! !PPPattern methodsFor: 'matching' stamp: 'lr 4/30/2010 07:53'! copyInContext: aDictionary seen: aSeenDictionary ^ aDictionary at: self! ! !PPPattern methodsFor: 'comparing' stamp: 'lr 4/29/2010 10:33'! hash ^ self identityHash! ! !PPPattern methodsFor: 'initialization' stamp: 'lr 4/29/2010 10:20'! initializeOn: aBlock verificationBlock := aBlock! ! !PPPattern methodsFor: 'matching' stamp: 'lr 4/30/2010 12:01'! match: aParser inContext: aDictionary seen: anIdentitySet (verificationBlock value: aParser value: aDictionary) ifFalse: [ ^ false ]. ^ (aDictionary at: self ifAbsentPut: [ aParser ]) match: aParser inContext: aDictionary seen: anIdentitySet! ! !PPPattern methodsFor: 'parsing' stamp: 'lr 4/30/2010 08:48'! parseOn: aStream "This is just a pattern used for matching. It should not be used in actual grammars." self shouldNotImplement! ! !PPPluggableParser commentStamp: '' prior: 34298319! A pluggable parser that passes the parser stream into a block. This enables users to perform manual parsing or to embed other parser frameworks into PetitParser. Instance Variables: block The pluggable one-argument block. ! !PPPluggableParser class methodsFor: 'instance creation' stamp: 'lr 5/2/2010 16:52'! on: aBlock ^ self new initializeOn: aBlock! ! !PPPluggableParser methodsFor: 'accessing' stamp: 'lr 4/30/2010 11:10'! block "Answer the pluggable block." ^ block! ! !PPPluggableParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:41'! displayName ^ String streamContents: [ :stream | block decompile shortPrintOn: stream ]! ! !PPPluggableParser methodsFor: 'initialization' stamp: 'lr 5/2/2010 16:52'! initializeOn: aBlock block := aBlock! ! !PPPluggableParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 6/18/2010 14:09'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]! ! !PPPluggableParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:54'! parseOn: aStream | position result | position := aStream position. result := block value: aStream. result isPetitFailure ifTrue: [ aStream position: position ]. ^ result! ! !PPPredicateParser commentStamp: '' prior: 34298618! An abstract parser that accepts if a given predicate holds. Instance Variables: predicate The block testing for the predicate. predicateMessage The error message of the predicate. negated The block testing for the negation of the predicate. negatedMessage The error message of the negated predicate.! !PPPredicateObjectParser commentStamp: '' prior: 34299036! A parser that accepts if a given predicate on one element of the input sequence holds.! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 6/12/2010 09:10'! any ^ self on: [ :each | true ] message: 'input expected' negated: [ :each | false ] message: 'no input expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 4/1/2011 20:05'! anyExceptAnyOf: aCollection ^ self on: [ :each | (aCollection includes: each) not ] message: 'any except ' , aCollection printString , ' expected' negated: [ :each | aCollection includes: each ] message: aCollection printString , ' not expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 4/1/2011 20:05'! anyOf: aCollection ^ self on: [ :each | aCollection includes: each ] message: 'any of ' , aCollection printString , ' expected' negated: [ :each | (aCollection includes: each) not ] message: 'none of ' , aCollection printString , 'expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 6/12/2010 09:10'! between: min and: max ^ self on: [ :each | each >= min and: [ each <= max ] ] message: min printString , '..' , max printString , ' expected' negated: [ :each | each < min or: [ each > max ] ] message: min printString , '..' , max printString , ' not expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:02'! blank ^ self chars: (String with: Character space with: Character tab) message: 'blank expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:02'! char: aCharacter ^ self expect: aCharacter message: (String with: $" with: aCharacter with: $") , ' expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 10:57'! char: aCharacter message: aString ^ self expect: aCharacter message: aString! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! chars: aCollection message: aString ^ self on: (PPCharSetPredicate on: [ :char | aCollection includes: char ]) message: aString! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:02'! cr ^ self char: Character cr message: 'carriage return expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! digit ^ self on: (PPCharSetPredicate on: [ :char | char isDigit ]) message: 'digit expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 8/25/2010 10:57'! expect: anObject ^ self expect: anObject message: anObject printString , ' expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-objects' stamp: 'lr 8/25/2010 10:57'! expect: anObject message: aString ^ self on: [ :each | each = anObject ] message: aString negated: [ :each | each ~= anObject ] message: 'no ' , aString! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! hex ^ self on: (PPCharSetPredicate on: [ :char | (char between: $0 and: $9) or: [ (char between: $a and: $f) or: [ (char between: $A and: $F) ] ] ]) message: 'hex digit expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:05'! letter ^ self on: (PPCharSetPredicate on: [ :char | char isLetter ]) message: 'letter expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 6/12/2010 09:10'! lf ^ self char: Character lf! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! lowercase ^ self on: (PPCharSetPredicate on: [ :char | char isLowercase ]) message: 'lowercase letter expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:04'! newline ^ self chars: (String with: Character cr with: Character lf) message: 'newline expected'! ! !PPPredicateObjectParser class methodsFor: 'instance creation' stamp: 'lr 6/12/2010 09:10'! on: aBlock message: aString ^ self on: aBlock message: aString negated: [ :each | (aBlock value: each) not ] message: 'no ' , aString! ! !PPPredicateObjectParser class methodsFor: 'instance creation' stamp: 'lr 6/12/2010 09:10'! on: aBlock message: aString negated: aNegatedBlock message: aNegatedString ^ self new initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:04'! punctuation ^ self chars: '.,"''?!!;:#$%&()*+-/<>=@[]\^_{}|~' message: 'punctuation expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! space ^ self on: (PPCharSetPredicate on: [ :char | char isSeparator ]) message: 'separator expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:04'! tab ^ self char: Character tab message: 'tab expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! uppercase ^ self on: (PPCharSetPredicate on: [ :char | char isUppercase ]) message: 'uppercase letter expected'! ! !PPPredicateObjectParser class methodsFor: 'factory-chars' stamp: 'lr 8/25/2010 11:06'! word ^ self on: (PPCharSetPredicate on: [ :char | char isAlphaNumeric ]) message: 'letter or digit expected'! ! !PPPredicateObjectParser methodsFor: 'initialization' stamp: 'lr 6/12/2010 09:12'! initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString predicate := aBlock. predicateMessage := aString. negated := aNegatedBlock. negatedMessage := aNegatedString! ! !PPPredicateObjectParser methodsFor: 'operators' stamp: 'lr 6/12/2010 09:12'! negate "Answer a parser that is the negation of the receiving predicate parser." ^ self class on: negated message: negatedMessage negated: predicate message: predicateMessage! ! !PPPredicateObjectParser methodsFor: 'parsing' stamp: 'lr 9/30/2010 11:05'! parseOn: aStream ^ (aStream atEnd not and: [ predicate value: aStream uncheckedPeek ]) ifFalse: [ PPFailure message: predicateMessage at: aStream position ] ifTrue: [ aStream next ]! ! !PPPredicateParser methodsFor: 'accessing' stamp: 'lr 5/2/2010 13:36'! block "Answer the predicate block of the receiver." ^ predicate! ! !PPPredicateParser methodsFor: '*petitgui-accessing' stamp: 'lr 5/2/2010 19:35'! displayName ^ predicateMessage! ! !PPPredicateParser methodsFor: '*petitgui-accessing' stamp: 'lr 5/1/2010 17:05'! exampleOn: aStream "Produce a random character that is valid. If there are characters in the alpha-numeric range prefer those over all others." | valid normal | valid := Character allCharacters select: [ :char | self matches: (String with: char) ]. normal := valid select: [ :char | char asInteger < 127 and: [ char isAlphaNumeric ] ]. aStream nextPut: (normal isEmpty ifTrue: [ valid atRandom ] ifFalse: [ normal atRandom ])! ! !PPPredicateParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 9/15/2010 11:56'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block and: [ self message = aParser message ] ]! ! !PPPredicateParser methodsFor: 'accessing' stamp: 'lr 5/2/2010 13:36'! message "Answer the failure message." ^ predicateMessage! ! !PPPredicateParser methodsFor: 'printing' stamp: 'lr 5/2/2010 13:37'! printNameOn: aStream super printNameOn: aStream. aStream nextPutAll: ', '; print: predicateMessage! ! !PPPredicateSequenceParser commentStamp: '' prior: 34299190! A parser that accepts if a given predicate on an arbitrary number of elements of the input sequence holds. Instance Variables: size The number of elements to consume.! !PPPredicateSequenceParser class methodsFor: 'instance creation' stamp: 'lr 6/12/2010 09:14'! on: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger ^ self new initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger! ! !PPPredicateSequenceParser class methodsFor: 'instance creation' stamp: 'lr 6/12/2010 09:14'! on: aBlock message: aString size: anInteger ^ self on: aBlock message: aString negated: [ :each | (aBlock value: each) not ] message: 'no ' , aString size: anInteger ! ! !PPPredicateSequenceParser methodsFor: 'initialization' stamp: 'lr 6/12/2010 09:13'! initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString size: anInteger predicate := aBlock. predicateMessage := aString. negated := aNegatedBlock. negatedMessage := aNegatedString. size := anInteger ! ! !PPPredicateSequenceParser methodsFor: '*petitanalyzer-matching' stamp: 'lr 6/18/2010 14:09'! match: aParser inContext: aDictionary seen: anIdentitySet ^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self size = aParser size ]! ! !PPPredicateSequenceParser methodsFor: 'operators' stamp: 'lr 6/12/2010 09:14'! negate "Answer a parser that is the negation of the receiving predicate parser." ^ self class on: negated message: negatedMessage negated: predicate message: predicateMessage size: size! ! !PPPredicateSequenceParser methodsFor: 'parsing' stamp: 'lr 6/12/2010 09:25'! parseOn: aStream | position result | position := aStream position. result := aStream next: size. (result size = size and: [ predicate value: result ]) ifTrue: [ ^ result ]. aStream position: position. ^ PPFailure message: predicateMessage at: aStream position! ! !PPPredicateSequenceParser methodsFor: 'accessing' stamp: 'lr 6/12/2010 08:58'! size "Answer the sequence size of the receiver." ^ size! ! !PPUnresolvedParser commentStamp: 'lr 11/28/2009 18:50' prior: 34299436! This is a temporary placeholder or forward reference to a parser that has not been defined yet. If everything goes well it will eventually be replaced with the real parser instance.! !PPUnresolvedParser methodsFor: '*petitgui-accessing' stamp: 'lr 11/13/2009 14:15'! displayColor ^ Color red! ! !PPUnresolvedParser methodsFor: 'testing' stamp: 'lr 10/27/2008 11:29'! isUnresolved ^ true! ! !PPUnresolvedParser methodsFor: 'parsing' stamp: 'lr 2/7/2010 20:51'! parseOn: aStream self error: self printString , ' need to be resolved before execution.'! ! !PPParserDebuggerResult commentStamp: 'TudorGirba 3/8/2011 10:03' prior: 34299695! This class is meant to be used as a model for running a parser over a given stream. You create it via parse:with: class side method. For example: self parse: '1 + 2' with: PPArithmeticParser new. Instance Variables: parser result children parent ! !PPParserDebuggerResult class methodsFor: 'instance creation' stamp: 'TudorGirba 12/6/2011 20:42'! parse: aStream with: parser | root newParser | root := self new. newParser := parser transform: [:each | each name isNil ifTrue: [ each ] ifFalse: [ each >=> [:stream :continuation | | result child | child := PPParserDebuggerResult new parser: each; parent: root. root := root children add: child. child start: stream position + 1. result := continuation value. child end: stream position. root result: result. root := root parent. result ]]]. newParser parse: aStream. ^ root children first! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! children ^ children! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! children: anObject children := anObject! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 12/6/2011 20:40'! end ^ end! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 12/6/2011 20:40'! end: anObject end := anObject! ! !PPParserDebuggerResult methodsFor: 'printing' stamp: 'TudorGirba 3/8/2011 10:54'! formattedText ^ self result isPetitFailure ifTrue: [ Text string: self printString attribute: TextColor gray ] ifFalse: [ self printString]! ! !PPParserDebuggerResult methodsFor: 'initialization' stamp: 'TudorGirba 3/8/2011 07:32'! initialize children := OrderedCollection new! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/8/2011 07:29'! parent ^ parent! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/8/2011 07:29'! parent: anObject parent := anObject! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! parser ^ parser! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! parser: anObject parser := anObject! ! !PPParserDebuggerResult methodsFor: 'printing' stamp: 'TudorGirba 3/8/2011 10:55'! printOn: aStream aStream nextPutAll: self parser name; nextPutAll: ' - '; nextPutAll: self result printString! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! result ^ result! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 3/7/2011 23:08'! result: anObject result := anObject! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 12/6/2011 20:40'! start ^ start! ! !PPParserDebuggerResult methodsFor: 'accessing' stamp: 'TudorGirba 12/6/2011 20:40'! start: anObject start := anObject! ! !PPProcessor commentStamp: '' prior: 34300091! PPProcessor is an abstract superclass to PPRewriter and PPSearcher. It implements common functionality to search and transform grammars. The implementation of these matching algorithms is inspired from the refactoring engine by Don Roberts and John Brant. Contrary to the original implementation that worked on syntax trees, this implementation was generalized and works on possibly cyclic search patterns and grammar graphs. Instance Variables: searches The rules to be processed. context The current search context.! !PPProcessor class methodsFor: 'instance creation' stamp: 'lr 4/30/2010 08:34'! new ^ self basicNew initialize! ! !PPProcessor methodsFor: 'rules' stamp: 'lr 4/29/2010 09:34'! addRule: aGrammarRule searches add: (aGrammarRule setOwner: self)! ! !PPProcessor methodsFor: 'private' stamp: 'lr 4/29/2010 09:34'! context ^ context! ! !PPProcessor methodsFor: 'initialization' stamp: 'lr 4/29/2010 09:38'! initialize super initialize. searches := OrderedCollection new. context := Dictionary new! ! !PPProcessor methodsFor: 'private' stamp: 'lr 9/1/2010 20:53'! performRule: aRule on: aParser context := Dictionary new. ^ aRule performOn: aParser! ! !PPProcessor methodsFor: 'private' stamp: 'lr 9/1/2010 20:56'! performRulesOn: aParser | result | searches do: [ :rule | result := self performRule: rule on: aParser. result notNil ifTrue: [ ^ result ] ]. ^ nil! ! !PPRewriter commentStamp: '' prior: 34300702! PPRewriter walks over a grammar graph and transforms its parsers. If the grammar is modified, #hasChanged returns true. Instance Variables: changed Indicates if the last operation has changed anything.! !PPRewriter methodsFor: 'public' stamp: 'lr 9/1/2010 20:58'! execute: aParser "Perform the replace rules of the receiver on aParser, answer the resulting parser." | previous result | previous := context. changed := false. context := Dictionary new. result := aParser transform: [ :each | | transformed | transformed := self performRulesOn: each. transformed isNil ifTrue: [ each ] ifFalse: [ changed := true. transformed ] ]. context := previous. ^ result! ! !PPRewriter methodsFor: 'testing' stamp: 'lr 4/29/2010 21:28'! hasChanged "Answer if the last operation has changed anything." ^ changed! ! !PPRewriter methodsFor: 'initialization' stamp: 'lr 4/29/2010 21:28'! initialize super initialize. changed := false! ! !PPRewriter methodsFor: 'accessing' stamp: 'lr 4/29/2010 10:16'! replace: aSearchParser with: aReplaceParser self replace: aSearchParser with: aReplaceParser when: [ :node | true ]! ! !PPRewriter methodsFor: 'accessing' stamp: 'lr 4/29/2010 08:25'! replace: aSearchParser with: aReplaceParser when: aValidationBlock self addRule: (PPParserReplaceRule searchFor: aSearchParser replaceWith: aReplaceParser when: aValidationBlock)! ! !PPRewriter methodsFor: 'accessing' stamp: 'lr 4/29/2010 10:16'! replace: aSearchParser withValueFrom: aReplaceBlock self replace: aSearchParser withValueFrom: aReplaceBlock when: [ :node | true ]! ! !PPRewriter methodsFor: 'accessing' stamp: 'lr 4/29/2010 08:25'! replace: aSearchParser withValueFrom: aReplaceBlock when: aValidationBlock self addRule: (PPBlockReplaceRule searchFor: aSearchParser replaceWith: aReplaceBlock when: aValidationBlock)! ! !PPSearcher commentStamp: '' prior: 34300968! PPSearcher walks over a grammar specification and matches its parsers against the patterns using #match:inContext:. Instance Variables: answer The answer propagated between matches.! !PPSearcher methodsFor: 'private' stamp: 'lr 4/29/2010 09:46'! answer ^ answer! ! !PPSearcher methodsFor: 'public' stamp: 'lr 4/29/2010 09:45'! execute: aParser "Perform the search rules of the receiver on aParser. Answer the result of the search." ^ self execute: aParser initialAnswer: nil! ! !PPSearcher methodsFor: 'public' stamp: 'lr 9/1/2010 20:56'! execute: aParser initialAnswer: anObject "Perform the search rules of the receiver on aParser. Inject anObject into the matches and answer the result." | previous | previous := context. answer := anObject. context := Dictionary new. aParser allParsersDo: [ :each | self performRulesOn: each ]. context := previous. ^ answer! ! !PPSearcher methodsFor: 'rules' stamp: 'lr 4/29/2010 09:48'! matches: aParser do: anAnswerBlock "Add a search expression aParser, evaluate anAnswerBlock with the matched node and the previous answer." self addRule: (PPSearchRule searchFor: aParser thenDo: anAnswerBlock)! ! !PPSearcher methodsFor: 'rules' stamp: 'lr 4/29/2010 09:56'! matchesAnyOf: aCollectionOfParsers do: anAnswerBlock "Add a collection of search expressions aCollectionOfParsers, evaluate anAnswerBlock with the matched node and the previous answer." aCollectionOfParsers do: [ :each | self matches: each do: anAnswerBlock ]! ! !PPSearcher methodsFor: 'initialization' stamp: 'lr 4/29/2010 09:37'! setAnswer: anObject answer := anObject! ! !PPRefactoringUtils methodsFor: 'private refactoring' stamp: 'TudorGirba 11/28/2012 22:58'! handleError: anException anException actionBlock isNil ifTrue: [ UIManager default inform: anException messageText ] ifFalse: [ (UIManager default confirm: anException messageText) ifTrue: [ anException actionBlock value ] ]. anException return! ! !PPRefactoringUtils methodsFor: 'private refactoring' stamp: 'TudorGirba 11/28/2012 22:58'! handleWarning: anException | message | message := (anException messageText endsWith: '?') ifTrue: [ anException messageText ] ifFalse: [ anException messageText , String cr , 'Do you want to proceed?' ]. (UIManager default confirm: message) ifTrue: [ anException resume ] ifFalse: [ anException return ]! ! !PPRefactoringUtils methodsFor: 'private refactoring' stamp: 'TudorGirba 11/28/2012 22:58'! performRefactoring: aRefactoring [ [ aRefactoring execute ] on: RBRefactoringWarning do: [ :exception | self handleWarning: exception ] ] on: RBRefactoringError do: [ :exception | self handleError: exception ]! ! !PPRefactoringUtils methodsFor: 'private refactoring' stamp: 'TudorGirba 11/28/2012 22:58'! performRenameProduction: oldName from: class | refactoring newName | newName := UIManager default request: 'Production name:' initialAnswer: oldName. refactoring := PPRenameProdcutionRefactoring onClass: class rename: oldName to: newName. self performRefactoring: refactoring. ^ refactoring! ! !PPRule commentStamp: '' prior: 34301209! PPRule is the abstract superclass of all of the grammar search rules. A rule is the first class representation of a particular pattern to search for. The owner of the rule is the algorithms that actually executes the search. This arrangement allows multiple searches to be conducted by a single processor. Instance Variables: owner The processor that is actually performing the search. search The parse pattern to be searched. ! !PPReplaceRule commentStamp: '' prior: 34301720! PPReplaceRule is the abstract superclass of all of the transforming rules. The rules change the grammar by replacing the node that matches the rule. Subclasses implement different strategies for this replacement. Instance Variables: verificationBlock Is evaluated with the matching parser and allows for further verification of a match.! !PPBlockReplaceRule commentStamp: '' prior: 34302134! PPBlockReplaceRule replaces the matching node by the result of evaluating replaceBlock. This allows arbitrary computation to come up with a replacement. Instance Variables: replaceBlock The block that returns the parer to replace to matching parser with. ! !PPBlockReplaceRule class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 08:28'! searchFor: aSearchParser replaceWith: aReplaceBlock when: aVerificationBlock ^ (self searchFor: aSearchParser) setReplaceBlock: aReplaceBlock; setVerificationBlock: aVerificationBlock; yourself! ! !PPBlockReplaceRule methodsFor: 'matching' stamp: 'lr 6/5/2011 16:51'! foundMatchFor: aParser ^ replaceBlock cull: aParser! ! !PPBlockReplaceRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:29'! setReplaceBlock: aBlock replaceBlock := aBlock! ! !PPParserReplaceRule commentStamp: '' prior: 34302468! PPParserReplaceRule replaces a matched grammar with another grammar, which may include patterns from the matching grammar. Instance Variables: replaceParser The parser to replace the matched parser with.! !PPParserReplaceRule class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 08:28'! searchFor: aSearchParser replaceWith: aReplaceParser when: aVerificationBlock ^ (self searchFor: aSearchParser) setReplaceParser: aReplaceParser; setVerificationBlock: aVerificationBlock; yourself! ! !PPParserReplaceRule methodsFor: 'matching' stamp: 'lr 4/29/2010 08:16'! foundMatchFor: aParser ^ replaceParser copyInContext: owner context! ! !PPParserReplaceRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:29'! setReplaceParser: aParser replaceParser := aParser! ! !PPReplaceRule methodsFor: 'matching' stamp: 'lr 6/5/2011 16:52'! canMatch: aParser ^ verificationBlock cull: aParser! ! !PPReplaceRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:13'! initialize super initialize. verificationBlock := [ :parser | true ]! ! !PPReplaceRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:26'! setVerificationBlock: aBlock verificationBlock := aBlock! ! !PPRule class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 09:51'! new ^ self basicNew initialize! ! !PPRule class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 09:51'! searchFor: aParser ^ self new setSearch: aParser! ! !PPRule methodsFor: 'matching' stamp: 'lr 4/28/2010 21:10'! canMatch: aParser ^ true! ! !PPRule methodsFor: 'matching' stamp: 'lr 4/29/2010 08:14'! foundMatchFor: aParser self subclassResponsibility! ! !PPRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:51'! initialize! ! !PPRule methodsFor: 'matching' stamp: 'lr 4/29/2010 08:53'! performOn: aParser (search match: aParser inContext: owner context) ifFalse: [ ^ nil ]. (self canMatch: aParser) ifFalse: [ ^ nil ]. ^ self foundMatchFor: aParser! ! !PPRule methodsFor: 'initialization' stamp: 'lr 4/28/2010 20:45'! setOwner: aGrammarSearcher owner := aGrammarSearcher! ! !PPRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 08:23'! setSearch: aParser search := aParser! ! !PPSearchRule commentStamp: '' prior: 34302739! PPSearchRule is a rule that simply searches for matches to the rule. Every time a match is found, answerBlock is evaluated with the parser that matches and the current answer. This two-argument approach allows a collection to be formed from all of the matches, like with #inject:into:. Instance Variables: answerBlock Block to evaluate with the matching node and the current answer. ! !PPSearchRule class methodsFor: 'instance creation' stamp: 'lr 4/29/2010 08:21'! searchFor: aParser thenDo: aBlock ^ (self searchFor: aParser) setAnswerBlock: aBlock! ! !PPSearchRule methodsFor: 'matching' stamp: 'lr 6/5/2011 16:51'! canMatch: aParser owner setAnswer: (answerBlock cull: aParser cull: owner answer). ^ super canMatch: aParser! ! !PPSearchRule methodsFor: 'matching' stamp: 'lr 4/29/2010 08:15'! foundMatchFor: aParser ^ aParser! ! !PPSearchRule methodsFor: 'initialization' stamp: 'lr 4/29/2010 09:51'! setAnswerBlock: aBlock answerBlock := aBlock! ! !PPTextHighlighter commentStamp: '' prior: 34303199! This is a utility class for creating a highlighted text. For this we need: - a parser: PPParser - an attributeMapper Here is a template to use it: PPTextHighlighter new parser: YourParser new; color: 'tokenName1' with: Color blue; color: 'tokenName2' with: Color gray; highlight: string.! !PPTextHighlighter methodsFor: 'public' stamp: 'tg 7/27/2010 23:41'! addAttribute: aTextAttribute for: anElementString | attributes | attributes := self attributeMapper at: anElementString ifAbsentPut: [OrderedCollection new]. attributes add: aTextAttribute! ! !PPTextHighlighter methodsFor: 'accessing' stamp: 'tg 7/27/2010 23:09'! attributeMapper "returns a dictionary with keys corresponding to parser names and values corresponding to a collection of TextAttributes" ^ attributeMapper! ! !PPTextHighlighter methodsFor: 'accessing' stamp: 'tg 7/27/2010 23:07'! attributeMapper: aDictionary attributeMapper := aDictionary! ! !PPTextHighlighter methodsFor: 'public' stamp: 'tg 7/27/2010 23:42'! bold: anElementString self addAttribute: TextEmphasis bold for: anElementString! ! !PPTextHighlighter methodsFor: 'public' stamp: 'tg 7/28/2010 08:06'! color: anElementString with: aColor self addAttribute: (TextColor new color: aColor) for: anElementString! ! !PPTextHighlighter methodsFor: 'public' stamp: 'TudorGirba 4/30/2011 21:26'! highlight: aString | text highlighter | text := aString asText. highlighter := parser transform: [ :p | attributeMapper at: p name ifPresent: [ :attributes | p token ==> [ :token | attributes do: [:each | text addAttribute: each from: token start to: token stop ] ] ] ifAbsent: [ p ] ]. highlighter parse: text. ^ text! ! !PPTextHighlighter methodsFor: 'initialization' stamp: 'tg 7/27/2010 23:09'! initialize parser := #any asParser. attributeMapper := Dictionary new! ! !PPTextHighlighter methodsFor: 'accessing' stamp: 'tg 7/27/2010 23:06'! parser ^ parser! ! !PPTextHighlighter methodsFor: 'accessing' stamp: 'tg 7/27/2010 23:21'! parser: aParser parser := aParser! ! !PPToken commentStamp: 'lr 2/25/2013 23:34' prior: 34303548! PPToken represents a parsed part of the input stream. Contrary to a simple String it remembers where it came from, the original collection, its start and stop position and its parse value. Instance Variables: collection The collection this token comes from. start The start position in the collection. stop The stop position in the collection. value The parse result.! !PPToken class methodsFor: 'initialization' stamp: 'lr 11/29/2011 20:42'! initialize "Platform independent newline sequence. LF: Unix, CR+LF: Windows, and CR: Apple." NewLineParser := (Character lf asParser) / (Character cr asParser , Character lf asParser optional)! ! !PPToken class methodsFor: 'instance creation' stamp: 'lr 4/6/2010 20:58'! new self error: 'Token can only be created using a dedicated constructor.'! ! !PPToken class methodsFor: 'instance creation' stamp: 'lr 2/25/2013 23:36'! on: aSequenceableCollection ^ self on: aSequenceableCollection start: 1 stop: aSequenceableCollection size value: nil! ! !PPToken class methodsFor: 'instance creation' stamp: 'lr 2/25/2013 23:39'! on: aSequenceableCollection start: aStartInteger stop: aStopInteger value: anObject ^ self basicNew initializeOn: aSequenceableCollection start: aStartInteger stop: aStopInteger value: anObject! ! !PPToken methodsFor: 'comparing' stamp: 'lr 2/26/2013 00:34'! = anObject ^ self class = anObject class and: [ self parsedValue = anObject parsedValue ]! ! !PPToken methodsFor: 'accessing' stamp: 'lr 6/15/2010 23:34'! collection "Answer the underlying collection of this token." ^ collection! ! !PPToken methodsFor: 'querying' stamp: 'lr 9/7/2011 20:40'! column "Answer the column number of this token in the underlying collection." | position | position := 0. (NewLineParser , [ :stream | start <= stream position ifTrue: [ ^ start - position ]. position := stream position ] asParser / #any asParser) star parse: collection. ^ start - position! ! !PPToken methodsFor: 'copying' stamp: 'lr 2/26/2013 00:34'! copyFrom: aStartInteger to: aStopInteger ^ self class on: collection start: start + aStartInteger - 1 stop: stop + aStopInteger - 3 value: value! ! !PPToken methodsFor: 'comparing' stamp: 'lr 2/26/2013 00:34'! hash ^ self parsedValue hash! ! !PPToken methodsFor: 'initialization' stamp: 'lr 2/25/2013 23:36'! initializeOn: aSequenceableCollection start: aStartInteger stop: aStopInteger value: anObject collection := aSequenceableCollection. start := aStartInteger. stop := aStopInteger. value := anObject! ! !PPToken methodsFor: 'accessing-values' stamp: 'lr 2/26/2013 00:32'! inputValue "Answer the consumed input of this token." ^ collection copyFrom: start to: stop! ! !PPToken methodsFor: 'querying' stamp: 'lr 9/7/2011 20:41'! line "Answer the line number of this token in the underlying collection." | line | line := 1. (NewLineParser , [ :stream | start <= stream position ifTrue: [ ^ line ]. line := line + 1 ] asParser / #any asParser) star parse: collection. ^ line! ! !PPToken methodsFor: 'accessing-values' stamp: 'lr 2/26/2013 00:32'! parsedValue "Answer the parsed value of this token." ^ value! ! !PPToken methodsFor: 'printing' stamp: 'lr 2/26/2013 00:37'! printOn: aStream super printOn: aStream. aStream nextPut: $[; print: self start; nextPut: $,; print: self stop; nextPut: $]. aStream nextPut: $(; print: self parsedValue; nextPut: $)! ! !PPToken methodsFor: 'accessing' stamp: 'lr 2/25/2013 23:56'! size "Answer the size of this token in the underlying collection." ^ stop - start + 1! ! !PPToken methodsFor: 'accessing' stamp: 'lr 6/15/2010 23:33'! start "Answer the start position of this token in the underlying collection." ^ start! ! !PPToken methodsFor: 'accessing' stamp: 'lr 6/15/2010 23:33'! stop "Answer the stop position of this token in the underlying collection." ^ stop! ! !PPToken methodsFor: 'accessing-values' stamp: 'lr 2/26/2013 00:34'! value self notify: 'Token>>#value is no longer supported. Instead use Token>>#inputValue or the more pragmatic #parsedValue.'. ^ self inputValue! ! !ROAbstractAdjustSize class methodsFor: 'public' stamp: 'AlexandreBergel 9/15/2012 10:42'! getNewRectangleFor: element self subclassResponsibility ! ! !ROAbstractAdjustSize class methodsFor: 'public' stamp: 'AlexandreBergel 9/15/2012 10:57'! on: element | rec topLeft border | self assert: [ element isKindOf: ROElement ]. topLeft := element bounds topLeft. rec := self getNewRectangleFor: element. element extent: rec extent. element translateTo: (rec topLeft). "Check if I was extended on the topLeft corner" element elementsNotEdge do: [ :el | el translateWithoutUpdatingContainedElementsBy: topLeft - rec topLeft ]! ! !ROAdjustSizeOfNesting class methodsFor: 'public' stamp: 'AlexandreBergel 9/15/2012 10:31'! getNewRectangleFor: element ^ element encompassingRectangle! ! !ROShrikingSize class methodsFor: 'public' stamp: 'AlexandreBergel 9/15/2012 10:33'! getNewRectangleFor: element ^ element encompassingNestedRectangle! ! !ROAction class methodsFor: 'public'! on: element self subclassResponsibility! ! !ROBlink class methodsFor: 'configuration' stamp: 'AlexandreBergel 5/22/2013 17:46'! defaultColor ^ Color red! ! !ROBlink class methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 18:00'! highlight: element self highlight: element color: self defaultColor! ! !ROBlink class methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 17:59'! highlight: element color: aColor self set: element color: aColor! ! !ROBlink class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 17:50'! highlightElements: elements ^ elements do: [ :el | self highlight: el ] ! ! !ROBlink class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 17:53'! highlightElements: elements color: aColor ^ elements do: [ :el | self highlight: el color: aColor ] ! ! !ROBlink class methodsFor: 'testing' stamp: 'AlexandreBergel 5/22/2013 17:47'! isBlinking: element ^ element attributes includesKey: #oldColor! ! !ROBlink class methodsFor: 'testing' stamp: 'AlexandreBergel 5/22/2013 18:04'! isHighlighted: element ^ element attributes includesKey: #oldColor! ! !ROBlink class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 17:27'! on: element ^ self new on: element! ! !ROBlink class methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 17:57'! set: element color: aColor element forShape: ROShape do: [ :d | (element attributes includesKey: #oldColor) ifFalse: [ element attributes at: #oldColor put: d color. d color: aColor. element signalUpdate ]]. ! ! !ROBlink class methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 18:04'! unhighlight: element (self isHighlighted: element) ifFalse: [ ^ self ]. element forShape: ROShape do: [ :d | d color: (element attributes at: #oldColor). element attributes removeKey: #oldColor ]. element signalUpdate! ! !ROBlink class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 17:50'! unhighlightElements: elements ^ elements do: [ :el | self unhighlight: el ] ! ! !ROBlink methodsFor: 'configuration' stamp: 'AlexandreBergel 5/22/2013 17:46'! defaultColor ^ self class defaultColor! ! !ROBlink methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 18:00'! highlight: element ^ self class highlight: element! ! !ROBlink methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 17:59'! highlight: element color: aColor ^ self class highlight: element color: aColor! ! !ROBlink methodsFor: 'testing' stamp: 'AlexandreBergel 5/22/2013 18:04'! isHighlighted: element ^ self class isHighlighted: element! ! !ROBlink methodsFor: 'configuration' stamp: 'AlexandreBergel 5/22/2013 17:43'! nbOfCyclesLightOn ^ 20! ! !ROBlink methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 17:48'! on: element self highlight: element. RONopAnimation new nbCycles: self nbOfCyclesLightOn; after: [ self unhighlight: element ]; on: element view " RONopAnimation new nbCycles: 20; after: [ ROUnhighlightElement on: element ]; on: element view. RONopAnimation new nbCycles: 40; after: [ ROHighlightElement on: element ]; on: element view. RONopAnimation new nbCycles: 60; after: [ ROUnhighlightElement on: element ]; on: element view. "! ! !ROBlink methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 17:57'! set: element color: aColor ^ self class set: element color: aColor! ! !ROBlink methodsFor: 'util' stamp: 'AlexandreBergel 5/22/2013 17:58'! unhighlight: element ^ self class unhighlight: element! ! !ROFocusView class methodsFor: 'public - focus on element' stamp: 'AlexandreBergel 11/19/2012 14:53'! bottomLeftOn: element ^ self new bottomLeftOn: element! ! !ROFocusView class methodsFor: 'public - focus on element' stamp: 'AlexandreBergel 11/19/2012 14:53'! bottomRightOn: element ^ self new bottomRightOn: element! ! !ROFocusView class methodsFor: 'public - center view' stamp: 'AlexandreBergel 5/14/2013 15:58'! centerView: aView self new view: aView toPosition: aView encompassingRectangle center! ! !ROFocusView class methodsFor: 'public - center view' stamp: 'AlexandreBergel 10/21/2013 15:08'! moveElementsTopLeft: aView "Move all the elements in the top left corner. No elements have a negative coordinate" self new view: aView toPosition: aView encompassingRectangle topLeft! ! !ROFocusView class methodsFor: 'public - focus on element' stamp: 'AlexandreBergel 9/29/2012 14:50'! on: element ^ self new on: element! ! !ROFocusView methodsFor: 'public' stamp: 'AlexandreBergel 11/21/2012 14:14'! bottomLeftOn: element "Public method" self on: element offset: (0 @ (element view camera windowSize y - element height))! ! !ROFocusView methodsFor: 'public' stamp: 'AlexandreBergel 11/21/2012 14:14'! bottomRightOn: element "Public method" self on: element offset: (((element view camera windowSize x - element width)) @ (element view camera windowSize y - element height))! ! !ROFocusView methodsFor: 'private' stamp: 'AlexandreBergel 5/22/2013 18:13'! highlightElement: element ROBlink on: element! ! !ROFocusView methodsFor: 'public' stamp: 'AlexandreBergel 11/21/2012 14:14'! on: element "Public method" self on: element offset: (element view camera windowSize / 2).! ! !ROFocusView methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 18:10'! on: element offset: offset " Without the translation" " element view camera translateTo: (element absolutePosition - offset)." "We have the smooth translate until the point we are pointing to" ROLinearMove new for: element view by: (element view camera position - element absolutePosition + offset); after: [ self highlightElement: element ]. element view doAnimationCycle ; doAnimationCycle. element signalUpdate.! ! !ROFocusView methodsFor: 'public deprecated' stamp: 'AlexandreBergel 9/29/2012 14:55'! on: element view: aView "Public method" "There is some duplication with ROLinearMove. Need to check!!!!!!" "Deprecated method" self on: element! ! !ROFocusView methodsFor: 'public' stamp: 'AlexandreBergel 10/21/2013 14:51'! view: view toPosition: pointToFocusOn view camera translateTo: (pointToFocusOn - (view camera windowSize / 2)) "ROLinearMove new for: view by: (view camera position - pointToFocusOn + (view camera windowSize / 2))"! ! !ROGrow class methodsFor: 'public'! on: element by: integer element setBounds: (element bounds extendBy: ((integer * 2) @ (integer * 2))). element translateBy: integer @ integer! ! !RORemoveEdge class methodsFor: 'public' stamp: 'AlexandreBergel 11/20/2012 18:50'! edgesFrom: anElement anElement view elementsDo: [ :el | el isEdge ifTrue: [ (el from == anElement) ifTrue: [ el remove ] ] ]. anElement view signalUpdate ! ! !RORemoveEdge class methodsFor: 'public' stamp: 'AlexandreBergel 11/20/2012 18:50'! edgesTo: anElement anElement view elementsDo: [ :el | el isEdge ifTrue: [ (el to == anElement) ifTrue: [ el remove ] ] ]. anElement view signalUpdate ! ! !RORemoveNode class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 6/18/2012 15:49'! suchThat: aBlock in: view view elementsDo: [ :el | el isEdge ifTrue: [ ((aBlock value: el from) or: [ (aBlock value: el to) ]) ifTrue: [ el remove ] ] ifFalse: [ (aBlock value: el) ifTrue: [ el remove ] ] ]. view signalUpdate ! ! !ROResize commentStamp: '' prior: 34304025! A ROResize is a general utility class to perform various operations regarding resizing! !ROResize class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 16:11'! stretchHorizontally: elements | maxWidth | maxWidth := elements inject: 0 into: [ :max :el | max max: el extent x ]. elements do: [ :el | el extent: (maxWidth @ el extent y) ].! ! !ROResize class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 16:11'! stretchVertically: elements | maxHeight | maxHeight := elements inject: 0 into: [ :max :el | max max: el extent y ]. elements do: [ :el | el extent: (el extent x @ maxHeight) ].! ! !ROExample commentStamp: '' prior: 34304163! A ROExample contains a list of example of Roassal. It does not contains examples on the builder. ! !ROExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:48'! postScript ^ ' "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view noLayout. view open'! ! !ROExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:43'! preamble ^ 'rawView := ROView new. view := ROMondrianViewBuilder view: rawView.'! ! !ROExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:43'! preambleVariables ^ #('view' 'rawView')! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 6/21/2013 09:52'! addingInnerOnClickOn: rawView | bundle label body elements | label := ROLabel elementOn: 'Click here!!'. body := ROBox element. bundle := ROElement new. bundle add: label; add: body. ROVerticalLineLayout on: (Array with: label with: body). rawView add: bundle. ROBlink on: label. label on: ROMouseClick do: [ :event | elements := (1 to: 5) collect: [ :i | ROBox green elementOn: i ]. body addAll: elements. ROGridLayout on: body elements. rawView signalUpdate. ].! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 8/11/2013 22:25'! addingOnClickOn: rawView | addButton element | addButton := (ROBorder + ROLabel) elementOn: '+ 1'. addButton @ ROLightlyHighlightable. rawView add: addButton. addButton translateBy: 15 @ 15. element := ROBorder element. element @ RODraggable. element translateBy: 50 @ 50. element callback: (ROContainerCallbackLayout for: ROGridLayout new). rawView add: element. "callback" addButton on: ROMouseClick do: [ :event | element add: ROBox gray element. element signalUpdate ]. ! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 9/1/2013 09:02'! animationOn: rawView | elements b helpLabel | "Define 10 blue rectangles, align them, and move them away from the corner" elements := ROElement forCollection: (1 to: 10). elements do: [ :el | el + ROBox blue; extent: 40 @ 80 ]. rawView addAll: elements. ROHorizontalLineLayout new horizontalGap: 0; on: elements. elements do: [ :el | el translateBy: 40 @ 40 ]. "We define the animation in a block to be repeatable" b := [ elements do: [ :el | el model odd ifTrue: [ ROLinearMove new nbCycles: 30; for: el by: 0 @ 40; after: [ ROLinearMove new nbCycles: 30; for: el by: 0 @ -40 ] ] ] ]. "We first do the animation" b value. "Help message" RONopAnimation new nbCycles: 70; after: [ helpLabel := (ROElement on: 'Click here!!') + ROLabel. rawView add: helpLabel. helpLabel translateTo: 20 @ 150.]; on: rawView. RONopAnimation new nbCycles: 120; after: [ helpLabel remove ]; on: rawView. rawView on: ROMouseClick do: [ :event | b value ].! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/13/2013 23:15'! arrayOfObjects | view | view := ROView new. self arrayOfObjectsOn: view. view open! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 9/15/2013 00:44'! arrayOfObjectsOn: rawView | module unit b | "Inspired from Processing code, ArrayObjects" unit := 40. 1 to: (500 / unit) asInteger do: [ :x | 1 to: (500 / unit) asInteger do: [ :y | module := ROElement new + (ROEllipse size: 8). module translateTo: (x * unit + ( unit / 2)) @ (y * unit + ( unit / 2)). module attributeAt: #speed put: (200 atRandom / 100) asFloat. module attributeAt: #direction put: (1 @ 1). module attributeAt: #originalPosition put: ((x * unit) @ (y * unit)). rawView add: module. ] ]. b := [ rawView elementsDo: [ :element | | px dx | px := (element attributeAt: #originalPosition) x. dx := (module attributeAt: #direction) x. element translateBy: ((element attributeAt: #speed) *dx) @ 0. (((element position x - px) >= unit) or: [ (element position x - px) <= 0 ]) ifTrue: [ module attributeAt: #direction put: (dx negated @ 0 ) ]. ] ]. ROPluggableAnimation new nbCycles: 20000; block: b; on: rawView. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 7/14/2012 15:05'! arrowedLine " self new arrowedLine " | view n1 n2| view := ROView new. self arrowedLineOn: view. view open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 7/14/2012 18:12'! arrowedLineOn: rawView | n1 n2 | n1 := ROElement sprite. n2 := ROElement sprite. n2 translateBy: 20@60. rawView add: n1; add: n2; add: (ROEdge arrowedLineFrom: n1 to: n2). ! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 10/3/2012 08:48'! bouncingBall " self new bouncingBall " | rawView | rawView := ROView new. self bouncingBallOn: rawView. rawView open.! ! !ROExample methodsFor: 'animation' stamp: 'VanessaPena 3/12/2013 15:30'! bouncingBallOn: rawView | x y dy ball b | x := 0. y := 50. dy := 0. ball := ROElement new + ROEllipse. ball extent: 30 @ 30. rawView add: ball. b := [ x := x + 4. y := y + dy. ( y > 185) ifTrue: [ dy := dy negated. ball extent: 30 @ 25. ball translateTo: x @ 190 ] ifFalse: [ dy := dy * 0.98 + 3. ball extent: 30 @ 30. ball translateTo: x @ y ]. ]. ROPluggableAnimation new nbCycles: 100; block: b; on: rawView. ! ! !ROExample methodsFor: 'colors' stamp: 'AlexandreBergel 9/11/2012 17:19'! brightness " Brightness by Rusty Robison. from Processing self new brightness " | view barWidth elements windowExtent cantBars layout | view := ROView new. windowExtent := 500. self brightnessOn: view. view openInWindowSized: windowExtent @windowExtent . ! ! !ROExample methodsFor: 'colors' stamp: 'AlexandreBergel 12/4/2012 10:06'! brightnessOn: rawView | barWidth elements windowExtent cantBars layout | windowExtent := 250. barWidth := 5. cantBars := windowExtent / barWidth . elements := ROElement forCollection: (1 to: cantBars). elements do: [:e | e extent: barWidth@windowExtent. e + (ROBox new color: Color black). e on: ROMouseMove do:[:event | (e getShape: ROBox) color: (Color h: e position x s: 100 v: (event position y / 250) ). e signalUpdate. ]. ]. layout := ROHorizontalLineLayout withGap: 0. layout applyOn: elements. rawView addAll: elements. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 9/1/2013 13:48'! buildingEdge " self new buildingEdge. " | view | view := ROView new. view addAll: (ROBox elementsOn: Collection withAllSubclasses). view addAll: (ROLine buildEdgesFromElements: view elements from: #superclass to: #yourself). ROTreeLayout on: view elements. view open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 9/1/2013 09:35'! buildingEdgesOn: rawView | assocs | assocs := OrderedCollection new. assocs add: 1 -> 3; add: 3 -> 5; add: 1 -> 4; add: 4 -> 5. rawView addAll: (ROBox elementsOn: (1 to: 5) ). rawView addAll: (ROLine buildEdgesFromAssociations: assocs inView: rawView). ROHorizontalTreeLayout on: rawView elements. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 11/23/2012 08:33'! centeredLabel " self new centeredLabel " | rawView | rawView := ROView new. self centeredLabelOn: rawView. rawView open . ! ! !ROExample methodsFor: 'basic' stamp: 'VanessaPena 3/12/2013 15:30'! centeredLabelOn: rawView | el | el := (ROElement spriteOn: 'x x x x x x x x x x x x x x x x x x x x x x x x x x x x' ) width: 200; height:200. el + ROCenteredLabel + (ROEllipse color: Color green). rawView add: el.! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 11/23/2012 08:34'! choice " self new choice " | view circle grid options choice container elementsToLayout | view := ROView new. circle := ROButtonElement named: 'circle' do: [:e | ROCircleLayout on: elementsToLayout. view signalUpdate ]. grid := ROButtonElement named: 'grid' do: [:e | ROGridLayout on: elementsToLayout. view signalUpdate ]. options := Array with: circle with: grid. choice := ROElement new. choice addAll: (ROHorizontalLineLayout on: options). container := ROElement new. elementsToLayout := ROElement labelsOn: (1 to: 20). elementsToLayout do: [ :v | v + ROBorder red @RODraggable. v extent: 50@50 ]. container addAll: (ROCircleLayout on: elementsToLayout). elementsToLayout do: [:l | l addShape: ROLabel]. view addAll: (ROVerticalLineLayout on: (Array with: choice with: container)). view open. ! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 7/14/2012 18:40'! choiceOn: rawView | circle grid options choice container elementsToLayout | circle := ROButtonElement named: 'circle' do: [:e | ROCircleLayout on: elementsToLayout. rawView signalUpdate ]. grid := ROButtonElement named: 'grid' do: [:e | ROGridLayout on: elementsToLayout. rawView signalUpdate ]. options := Array with: circle with: grid. choice := ROElement new. choice addAll: (ROHorizontalLineLayout on: options). container := ROElement new. elementsToLayout := ROElement labelsOn: (1 to: 20). elementsToLayout do: [ :v | v + ROBorder red @RODraggable. v extent: 50@50 ]. container addAll: (ROCircleLayout on: elementsToLayout). elementsToLayout do: [:l | l addShape: ROLabel]. rawView addAll: (ROVerticalLineLayout on: (Array with: choice with: container)). ! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 1/23/2013 16:29'! circle | view | view := ROView new. self circleOn: view. view open! ! !ROExample methodsFor: 'animation' stamp: 'VanessaPena 3/12/2013 15:30'! circleOn: rawView | outterElements innerElements b angle | outterElements := ROElement forCollection: (1 to: 20). outterElements do: [ :el | el + (ROEllipse blue extent: 20 @ 20) @ RODraggable ]. innerElements := ROElement forCollection: (21 to: 41). innerElements do: [ :el | el + (ROEllipse green extent: 20 @ 20) @ RODraggable ]. rawView addAll: outterElements. rawView addAll: innerElements. angle := 0. b := [ ROCircleLayout new initialAngleInDegree: angle; initialRadius: 130; initialIncrementalAngleInDegree: 10; on: innerElements. ROCircleLayout new initialAngleInDegree: angle; initialRadius: 250; initialIncrementalAngleInDegree: 10; on: outterElements. angle := angle + 1. angle >= 360 ifTrue: [ angle := 0 ]. ]. ROPluggableAnimation new nbCycles: 5000; nbIterationsBeforeRefresh: 2; block: b; on: rawView. ! ! !ROExample methodsFor: 'software' stamp: 'AlexandreBergel 8/8/2013 15:54'! classHierarchyOn: rawView "We insert the classes" ROShape withAllSubclasses do: [ :c | | el | el := ROElement on: c. el @ RODraggable. el + ROBorder + ROLabel. rawView add: el ]. ROShape withAllSubclasses do: [ :c | | subclass superclass | subclass := rawView elementFromModel: c. superclass := rawView elementFromModel: c superclass. (subclass notNil and: [ superclass notNil ]) ifTrue: [ | edge | edge := ROEdge from: superclass to: subclass. edge + (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 1 ); attachPoint: ROVerticalAttachPoint instance). rawView add: edge ] ]. ROTreeLayout on: (rawView elementsNotEdge) edges: (rawView elements select: #isEdge).! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 15:19'! clickAndMove " self new clickAndMove Click to make the element go to where you have clicked " | rawView | rawView := ROView new. self clickAndMoveOn: rawView. rawView open. ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 9/11/2013 23:15'! clickAndMoveOn: rawView | el | " Click to make the element go to where you have clicked " el := ROElement sprite. rawView add: el. rawView on: ROMouseLeftClick do: [ :event | ROLinearMove new nbCycles: 20; for: el to: event position. ]. ! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 12:42'! clock " self new clock " | view | view := ROView new. self clockOn: view. view open! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 13:32'! clockOn: rawView | radius secondsRadius minutesRadius hoursRadius clockDiameter cx cy now s m h center secondElement minuteElement hourElement b | radius := 250. secondsRadius := radius * 0.72. minutesRadius := radius * 0.60. hoursRadius := radius * 0.50. clockDiameter := radius * 1.8. cx := 250. cy := 250. center := ROElement new. center translateTo: (cx @ cy). secondElement := ROElement new zIndex: 2. rawView add: ((ROLine gray width: 2) elementFrom: center to: secondElement). minuteElement := ROElement new zIndex: 2. rawView add: ((ROLine gray width: 3) elementFrom: center to: minuteElement). hourElement := ROElement new zIndex: 2. rawView add: ((ROLine gray width: 5) elementFrom: center to: hourElement). "Points" 1 to: 360 by: (360 / 12) do: [ :a | | ra el | ra := (a * 3.1415 / 180) asFloat. el := ROBox red element translateTo: (cx + (ra cos * secondsRadius)) @ (cy + (ra sin * secondsRadius)). rawView add: el. ]. b := [ now := Time now. s := now second / 60 * (3.1415 * 2) - (3.1415 / 2). m := (now minute + (now second / 60)) / 60 * (3.1415 * 2) - (3.1415 / 2). h := (now hour + (now minute / 60)) / 60 * (3.1415 * 2) - (3.1415 / 2). minuteElement translateTo: (cx + (m cos * minutesRadius)) @ (cy + (m sin * minutesRadius)). secondElement translateTo: (cx + (s cos * secondsRadius)) @ (cy + (s sin * secondsRadius)). hourElement translateTo: (cx + (h cos * hoursRadius)) @ (cy + (h sin * hoursRadius)). rawView signalUpdate ]. b value. ROPluggableAnimation new nbCycles: 2000; block: b; on: rawView.! ! !ROExample methodsFor: 'colors' stamp: 'VanessaPena 12/20/2012 17:50'! colors " self new colors " | view els | view := ROView new. view @RODraggable . self colorsOn: view. view open. view inspect ! ! !ROExample methodsFor: 'colors' stamp: 'VanessaPena 3/12/2013 15:30'! colorsOn: rawView | els | els := ROElement forCollection: (1 to: 20). els with: (Color red mix: Color green shades: 20) do: [:el :c | (el size: 20) + (ROEllipse color: c )]. "We make the circle draggable" els do: [ :e | e @ RODraggable ]. rawView addAll: els. ROCircleLayout new scaleBy: 4; on: els. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/22/2013 11:13'! composingOn: rawView | outer inner innerLabel | outer := ROElement new + ROBorder white. outer @ RODraggable. inner := ROElement sprite. innerLabel := ROLabel elementOn: 'My sprite'. outer add: inner; add: innerLabel. "We make the inner and innerLabel forwarder of events" inner forward. innerLabel forward. "We layout the things" ROVerticalLineLayout on: outer elements. rawView add: outer. ! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 13:37'! constraint " self new constraint " | view | view := ROView new. self constraintOn: view. view open ! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 6/12/2013 17:29'! constraintOn: rawView | outter inner | outter := ROBox element extent: 100 @ 80. inner := (ROEllipse color: Color gray) element size: 20. outter add: inner. outter resizeStrategy: (ROFixedSizedParent new). ROConstraint constraintInItsParent: inner. rawView add: outter. rawView add: inner. outter translateTo: 80 @ 20. inner @ RODraggable.! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/22/2013 11:13'! constraintsOn: rawView | outer inner innerLabel | outer := ROElement sprite. outer @ ROLightlyHighlightable . inner := ROElement sprite . innerLabel := ROLabel elementOn: 'My sprite'. outer add: inner; add: innerLabel. inner add: ROElement sprite. rawView add: outer. ROConstraint stick: innerLabel onTheRightOf: inner. "ROConstraint stick: innerLabel below: inner." "ROConstraint stick: innerLabel above: inner." "ROConstraint stick: innerLabel onTheLeftOf: inner." "ROConstraint stick: innerLabel onTheCenterOf: inner."! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 8/22/2012 21:38'! continuousLinearMove " From Processing self new continuousLinearMove " |view line1 line2| view := ROView new. line1 := (ROElement new model: 'line1') extent:1@100; yourself. line1 + (ROBorder new color: Color red). line2 := (ROElement new model: 'line1') extent:1@100; yourself. line2 + (ROBorder new color: Color green). line2 translateBy: 0@100. view add: line1. view add: line2. ROMotionMove new for: line1 initialSpeed: 60@0. ROMotionMove new for: line2 initialSpeed: 30@0. view openInWindowSized: 200@200. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/21/2013 14:33'! draggingAllConnected " self new draggingAllConnected " | view | view := ROView new. self draggingAllConnectedOn: view. view open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/21/2013 14:32'! draggingAllConnectedOn: rawView | elements | 0 to: 50 by: 10 do: [ :i | elements := (ROBox green size: 10) elementsOn: (i to: i + 9). elements do: [ :e | e @ RODraggable @ ROPopup ]. rawView addAll: elements. ROLine buildEdgesFromElement: elements first from: #yourself toAll: [ :v | (v + 1 to: v + 9) ]. ROTreeLayout on: elements. (rawView elementFromModel: i) - ROBox + ROBox red. (rawView elementFromModel: i) @ ROAllConnectedNodeDraggable ; translateBy: i * 15 @ 10. ]. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/21/2013 21:39'! draggingAllRecursivelyConnected " self new draggingAllRecursivelyConnected " | view | view := ROView new. self draggingAllRecursivelyConnectedOn: view. view open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/21/2013 21:43'! draggingAllRecursivelyConnectedOn: rawView | toElement fromElement | 1 to: 7 do: [ :n | toElement := ((ROLabel elementOn: n) extent: 50@50 ) + ROBorder @ RODraggable. rawView add: toElement. ((fromElement := rawView elementFromModel: n // 2) ) ifNotNil: [ rawView add: (ROEdge from: fromElement to: toElement ) + ROLine ] ]. ROHorizontalTreeLayout new on: rawView elements. rawView elements first @ ROAllRecursivelyConnectedNodeDraggable. rawView elements first - ROBorder + ROBorder red. ! ! !ROExample methodsFor: 'free style' stamp: 'VanessaPena 3/12/2013 15:30'! drawCircle: view x: x radius: radius level: level | tt | tt := 126 * level / 4. view add: ((ROElement new center: x asInteger @100 radius: radius asInteger ) addShape: (ROEllipse new color: (Color gray256: tt) )). (level > 1) ifTrue: [ self drawCircle: view x: (x - (radius / 2)) radius: radius / 2 level: level - 1. self drawCircle: view x: (x + (radius / 2)) radius: radius / 2 level: level - 1. ] ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 4/6/2013 23:59'! drawing | rawView p newEl | rawView := ROView new. rawView add: (ROLabel elementOn: 'Drawing!!'). rawView on: ROMouseRightClick do: [ :event | rawView removeAllElements ]. rawView on: ROMouseDragging do: [ :event | p ifNil: [ p := ROBox element size: 1 . p translateTo: event position. rawView add: p ]. newEl := (ROBox element size: 1) translateTo: event position. rawView add: newEl. rawView add: ((ROEdge from: p to: newEl) + ROLine). p := newEl. rawView signalUpdate ]. rawView on: ROMouseDragged do: [ :event | p := nil ]. rawView open ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/17/2013 18:23'! dynamicEdgeOn: rawView | el1 el2 el3 | rawView add: (el1 := ROBox element size: 20). rawView add: (el2 := ROBox element size: 20). rawView add: (el3 := ROBox element size: 20). ROCircleLayout on: (Array with: el1 with: el2 with: el3). el1 @ RODraggable. el2 @ RODraggable. el3 @ RODraggable. el1 @ (RODynamicEdge toAll: (Array with: el2 with: el3) using: (ROLine arrowed color: Color red)).! ! !ROExample methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/22/2013 10:05'! dynamicEdgeSimpleOn: rawView | element1 element2 | element1 := ROBox blue element. element1 extent: 50 @ 50. element1 @ RODraggable. element2 := ROBox green element. element2 extent: 50 @ 50. element2 @ RODraggable. element1 on: ROMouseEnter do: [ :event | element1 @ (RODynamicEdge to: element2). ROWiggle on: element2 ]. rawView add: element1; add: element2. ROHorizontalLineLayout on: (Array with: element1 with: element2).! ! !ROExample methodsFor: 'free style' stamp: 'AlexandreBergel 9/11/2012 15:48'! embeddedIteration " From Processing self new embeddedIteration " | view boxSize elements tmpEltos windowExtent cantBoxes layout height gap originalBoxSize | originalBoxSize := 10. boxSize := 10. windowExtent := 200. view := ROView new. elements := OrderedCollection new. cantBoxes := windowExtent / boxSize . height := 0. [ boxSize > 0 ] whileTrue: [ gap := (originalBoxSize - boxSize) / 2. tmpEltos := ROElement forCollection: (1 to: cantBoxes). tmpEltos do: [ :e | e + ROBox . e size: boxSize ]. layout := ROHorizontalLineLayout withGap: gap. layout applyOn: tmpEltos. tmpEltos do: [ :e | e translateBy: 0 @ height ]. elements addAll: tmpEltos . height := height + boxSize + 1. boxSize := boxSize - 0.5. ]. view addAll: elements . view openInWindowSized: windowExtent @ windowExtent .! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 00:03'! enteringCharacter " self new enteringCharacter " | rawView | rawView := ROView new. self enteringCharacterOn: rawView. rawView open! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 12:11'! enteringCharacterOn: rawView | label labelElement | label := 'Press keys :'. labelElement := ROLabel elementOn: label. labelElement @RODraggable . rawView add: labelElement. rawView on: ROKeyDown do: [ :event | label := label, event character asString. labelElement model: label. rawView signalUpdate ].! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:28'! expandableNodes " ROExample new expandableNodes " | view initialNodes | view := ROView new. self expandableNodesOn: view. view @RODraggable @ RODraggableWithVelocity. view open! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:28'! expandableNodesOn: rawView | initialNodes | initialNodes := (ROElement labelsOn: (Array with: Integer)) asOrderedCollection. initialNodes do: [:n | n + ROLabel + ROBorder red. n @ (RORecursiveExpandOnClick childrenForModel: [ :model | model subclasses])]. rawView addAll: initialNodes. ROTreeLayout new translator: (ROSmoothLayoutTranslator new); applyOn: initialNodes. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 6/12/2013 17:30'! fontSize: rawView | label | (1 to: 30) do: [ :h| label := ROLabel new. label fontSize: h. rawView add: ((label elementOn: 'Hello World') @ RODraggable) ]. ROVerticalLineLayout on: rawView elements.! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 11/23/2012 08:35'! grid " self new grid " | view elements | view := ROView new. view addAll: ((elements := ROElement spritesOn: (1 to: 20)) do: [:n | n addShape: ROLabel]). ROGridLayout on: elements. view open ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 11/23/2012 08:34'! growOnClick " self new growOnClick " | view greenNode blueNode | view := ROView new. self growOnClickOn: view. view open ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:31'! growOnClickOn: rawView | greenNode blueNode | greenNode := ROElement on: 'green node'. greenNode addShape: (ROBox new color: Color green). greenNode setBounds: (5 @ 10 corner: (180 @ 170)). greenNode @ RODraggable. greenNode @ ROGrowable. blueNode := ROElement on: 'blue node'. blueNode addShape: (ROBox new color: Color blue). blueNode setBounds: (5 @ 10 corner: (180 @ 170)). blueNode translateBy: 50@30. blueNode @ RODraggable. blueNode @ ROGrowable. rawView add: greenNode; add: blueNode. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/22/2013 01:23'! imageOn: rawView rawView add: (ROImage new form: ROEaselMorphic new roassalIcon ) element @ RODraggable. rawView add: (ROImage new form: ROEaselMorphic new objectprofileIcon ) element @ RODraggable. ROHorizontalLineLayout on: rawView elements. ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 6/9/2013 18:04'! innerNodeAndZoom " self new innerNodeAndZoom " | view els | view := ROView new. els := ROElement forCollection: (1 to: 200). els do: [:spr | | innerNodes | spr extent: 50@50. spr + ROBorder red. spr @ ROZoomOnClick @ RODraggable. innerNodes := ROElement forCollection: (1 to: 10). innerNodes do: [:s | s + ROBox green @ RODraggable ]. spr addAll: (ROGridLayout on: innerNodes). ]. view addAll: els. ROGridLayout on: els. view @ RODraggable. view open. ! ! !ROExample methodsFor: 'keypressing' stamp: 'VanessaPena 8/27/2012 10:06'! keyPressing " self new keyPressing " |view elto elements| view := ROView new. view on: ROKeyDown do: [:evt | |keyValue| keyValue := evt keyValue. keyValue = 30 "up arrow" ifTrue: [view translateBy: 0@1]. keyValue = 31 "down arrow" ifTrue: [view translateBy: 0@(-1)]. keyValue = 29 "right arrow" ifTrue: [view translateBy: (-1)@0]. keyValue = 28 "left arrow" ifTrue: [view translateBy: 1@0] ]. elements := ROElement spritesOn: (1 to: 100). ROGridLayout new applyOn: elements. view addAll: elements . view open.! ! !ROExample methodsFor: 'keypressing' stamp: 'AlexandreBergel 4/14/2013 00:03'! keyPressing2 " self new keyPressing2 " |view elto element| view := ROView new. element := ROElement spriteOn: 'me'. view on: ROKeyDown do: [:evt | | keyValue | keyValue := evt keyValue. keyValue = 30 "up arrow" ifTrue: [element translateBy: 0@(-2)]. keyValue = 31 "down arrow" ifTrue: [element translateBy: 0@(2)]. keyValue = 29 "right arrow" ifTrue: [element translateBy: (2)@0]. keyValue = 28 "left arrow" ifTrue: [element translateBy: (-2)@0]. element signalUpdate. ]. view add: element. view open.! ! !ROExample methodsFor: 'basic' stamp: 'VanessaPena 12/23/2012 20:53'! label " self new label " | rawView | rawView := ROView new. self labelOn: rawView. rawView open. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 7/14/2012 18:13'! labelOn: rawView rawView add: (ROLabel elementOn: 'hello world'). ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 6/11/2013 11:31'! labelOnEdgeOn: rawView | el1 el2 label | rawView add: (el1 := ROBox red element size: 50). rawView add: (el2 := ROBox green element size: 50). el1 @ RODraggable. el2 @ RODraggable. el1 translateTo: 50 @ 50. el2 translateTo: 200 @ 54. rawView add: (ROLine elementFrom: el1 to: el2). label := ROLabel elementOn: 'Hello World'. ROConstraint stick: label between: el1 and: el2. rawView add: label. "view shape rectangle size: 50. nodes := view nodes: #(1 2). view edgeFromAssociation: 1 -> 2. view shape label. labelNode := view node: 'Hello'. ROConstraint stick: labelNode between: nodes first and: nodes second."! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 11/23/2012 08:35'! labelWithCRCharacter " self new labelWithCRCharacter " | view | view := ROView new. view add: (ROLabel elementOn: 'hello world'). view open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 7/14/2012 18:21'! labelWithCRCharacterOn: rawView rawView add: (ROLabel elementOn: 'hello world'). ! ! !ROExample methodsFor: 'software' stamp: 'AlexandreBergel 5/7/2013 13:54'! latentSemanticIndexing " self new latentSemanticIndexing " | documentsToProcess matrix words v elements view tIndexing elementsGraphical nativeUtil stack | documentsToProcess := OrderedCollection new. nativeUtil := RONativeExampleUtility current. ROElement withAllSubclasses do: [ :cls | documentsToProcess addAll: ((nativeUtil getMethodsForClass: cls) collect: #sourceCode) ]. "Matrix is a dictionary of dictionaries. The outter key is a word of the documents. The value is a dictionary is a method source code. In this dictionary of method source code, the value is the number of occurence of the word in the source code. | w1 | w2 | w3 | w4| s0| s1| s2| (w1, s0) occurence of the word w1 in the source code s0. ... " matrix := Dictionary new. documentsToProcess do: [ :source | words := nativeUtil substringsFor: source . words do: [ :w | matrix at: w ifAbsentPut: [ Dictionary new ]. v := (matrix at: w) at: source ifAbsentPut: [ 0 ]. (matrix at: w) at: source put: (v + 1) ] ]. elements := OrderedCollection new. matrix associationsDo: [ :assoc| | wordToConsider sourceAndOccurrences | wordToConsider := assoc key. sourceAndOccurrences := assoc value. sourceAndOccurrences associationsDo: [ :assoc2| | sourceCodeForWord wordOccurrence| sourceCodeForWord := assoc2 key. wordOccurrence := assoc2 value. elements add: (Array with: wordToConsider with: (documentsToProcess indexOf: sourceCodeForWord) with: wordOccurrence with: sourceCodeForWord) ] ]. tIndexing := (elements collect: #first) asSet asSortedCollection. elements := elements collect: [ :tupple | Array with: (tIndexing indexOf: tupple first) with: tupple second with: tupple third with: tupple fourth with: tupple first ]. "We build the view" stack := ROViewStack new. view := ROView new backgroundColor: Color black. elementsGraphical := ROElement forCollection: elements. elementsGraphical do: [:el | el addShape: (ROEllipse green); addInteraction: (ROPopup new text: [:e | 'Word: ', e fifth, Character cr, 'Occurrence: ', e third printString, Character cr, 'Source Code: ', Character cr, e fourth printString] ; receivingView: stack); size: (el model third) ]. view addAll: elementsGraphical. ROScatterplotLayout new x: #first ; y: #second; applyOn: elementsGraphical. view on: ROMouseLeftClick do: [ :event | ROZoomInMove new on: view ]. view on: ROMouseRightClick do: [ :event | ROZoomOutMove new on: view ]. view @ RODraggable @ RODraggableWithVelocity. stack addView: view. stack open.! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 11/23/2012 08:35'! leftAndRightClick " self new leftAndRightClick " | view | view := ROView new. self leftAndRightClickOn: view. view open ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/29/2012 09:40'! leftAndRightClickOn: rawView | counter add sub els | els := OrderedCollection new. add := ROElement sprite addShape: (ROLabel new text: '+ / --'); addShape: (ROBorder yellow). add on: ROMouseLeftClick do: [ :ev | | el | el := ROElement sprite translateTo: (200 atRandom @ 200 atRandom ). els add: el. rawView add: el. rawView signalUpdate ]. add on: ROMouseRightClick do: [ :ev | | el | els ifNotEmpty: [ rawView remove: els removeLast. rawView signalUpdate ] ]. rawView add: add. ! ! !ROExample methodsFor: 'basic' stamp: 'VanessaPena 12/23/2012 20:52'! lines " self new lines " | view node1 node2 edge | view := ROView new. self linesOn: view. view open. view camera inspect.! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 10/3/2012 09:02'! linesOn: rawView | node1 node2 edge | node1 := ROLabel elementOn: 'node1'. node2 := ROLabel elementOn: 'node2'. node1 @ RODraggable. node2 @ RODraggable. edge := ROEdge from: node1 to: node2. edge + (ROLine red). rawView add: edge; add: node1; add: node2. ROHorizontalLineLayout on: (Array with: node1 with: node2). ! ! !ROExample methodsFor: 'software'! memoryProfiling " self new memoryProfiling " "| spaceItems builder | spaceItems := SpaceTally new spaceTally: (Array with: ByteString with: Process with: RPackage with: Bitmap). builder := ROMondrianViewBuilder new. builder shape rectangle logWidth: #instanceCount; logHeight: #spaceForInstances. builder nodes: (spaceItems asSorted: #spaceForInstances). builder open . "! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 3/11/2013 10:37'! miniMap " self new miniMap " | view eltos | view := ROView new. view @ RODraggable. view on: ROMouseRightClick do: [ :event | ROZoomInMove new on: view ]. view on: ROMouseLeftClick do: [ :event | ROZoomOutMove new on: view ]. eltos := ROElement spritesOn: (1 to: 400). eltos do: [:el | el + ROLabel ]. view addAll: eltos. ROGridLayout new on: eltos. "Mini map opens by pressing m" view @ ROMiniMap. view open. ! ! !ROExample methodsFor: 'util' stamp: 'AlexandreBergel 12/13/2012 17:20'! monsterFrom: string color: aColor "Check spaceInvaderOn: for example of usage" ^ self monsterFrom: string color: aColor size: 10! ! !ROExample methodsFor: 'util' stamp: 'AlexandreBergel 1/30/2013 12:04'! monsterFrom: string color: aColor size: sizeAsInteger "Check spaceInvaderOn: for example of usage" | monster x y cr | cr := ' ' first. monster := ROElement new. monster @ RODraggable. x := 0. y := 0. string do: [ :char | char = 'X' first ifTrue: [ | el | el := ROElement new + (ROBox new color: aColor). el extent: sizeAsInteger @ sizeAsInteger. el translateBy: (x * sizeAsInteger) @ (y * sizeAsInteger). monster add: el. el forward. ]. char = cr ifTrue: [ y := y + 1. x := -1. ]. x := x + 1 ]. ^ monster! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 14:19'! moose1D " self new moose1D " | rawView | rawView := ROView new. self moose1DOn: rawView. rawView open! ! !ROExample methodsFor: 'Processing' stamp: 'AlexandreBergel 4/14/2013 20:33'! moose1DOn: rawView | el1 el2 | el1 := ROBox element. el2 := ROBox element. el1 forward. el2 forward. rawView add: el1; add: el2. rawView on: ROMouseMove do: [ :event | el1 translateTo: ( 250 + (event position x / 2)) @ (event position x / 2). el2 translateTo: ( 250 - (500 - (event position x))) @ (event position x / 2). el1 extent: (event position x @ event position x). el2 extent: ((500 @ 500) - (event position x @ event position x)). rawView signalUpdate ].! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:34'! motion " self new motion " |view sprs | view := ROView new. self motionOn: view. view open. ! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 3/12/2013 15:30'! motionOn: rawView | sprs | sprs := (ROElement forCollection: (1 to: 20)). sprs do: [:s | s extent: 20@20. s + ROEllipse blue. s @ RODraggable. s @ RODraggableWithVelocity ]. rawView addAll: sprs. sprs do: [ :spr | ROMotionMove new for: spr initialSpeed: 60 atRandom @ 60 atRandom ]. sprs last @ (ROPopup text: 'Press me!!' ). (sprs last getShape: ROEllipse) color: Color red. sprs last on: ROMouseClick do: [ sprs do: [ :spr | ROMotionMove new for: spr initialSpeed: (60 atRandom - 30) @ (60 atRandom - 30 ) ] ].! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 8/28/2012 09:52'! mouse1D " From Processing self new mouse1D " |view lElto rElto w h| w := 200. h := 200. view := ROView new. lElto := ROElement new model: 'left element'. lElto width: 100; height: 200. lElto + (ROBox new color: Color green). rElto := ROElement new model: 'right element'. rElto width: 100; height: 200. rElto + (ROBox new color: Color blue). rElto translateBy: 100@0. view add: lElto ; add: rElto . view openInWindowSized: w@h.! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 10/3/2012 08:48'! moveLikeCircle " self new moveLikeCircle " | rawView | rawView := ROView new. self moveLikeCircleOn: rawView. rawView open.! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 10/16/2013 11:20'! moveLikeCircleOn: rawView | elto mov | elto := ROElement new. elto size: 10. elto + (ROEllipse color: Color green). rawView add: elto. elto translateBy: 250@250. ROFunctionMove new nbCycles: 360; blockX: [ :elapseCycle | (elapseCycle * 3.14 / 180) cos * 40 + 100 ]; blockY: [ :elapseCycle | (elapseCycle * 3.14 / 180) sin * 40 + 100 ]; on: elto. " mov := ROTranslation new nbCycles: 200. mov for: elto functionX: [:t | 10* (t cos)] Y: [:t | 10* (t sin)] intervalIni: 0 IntervalEnd: 2 * Float pi. "! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 10/3/2012 08:47'! moveLikeCurve " self new moveLikeCurve " | rawView | rawView := ROView new. self moveLikeCurveOn: rawView. rawView open.! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 10/16/2013 11:20'! moveLikeCurveOn: rawView | elto mov | elto := ROElement new. elto size: 10. elto + (ROEllipse color: Color green). rawView add: elto. elto translateBy: 30@20. ROFunctionMove new nbCycles: 360; blockY: [ :x | (x * 3.1415 / 180) sin * 80 + 50 ]; on: elto. " mov := ROTranslation new nbCycles: 100. mov for: elto function: [:x | x ] intervalIni: 0 IntervalEnd: 100. "! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 6/13/2012 00:25'! multipleArrow | view el1 el2 edge line | view := ROView new. el1 := ROElement new. el1 @RODraggable. el1 extent: 50@50. el1 + ROBox blue. el2 := ROElement new. el2 @RODraggable. el2 extent: 50@50. el2 + ROBox green. el1 translateTo: 0 @ 100. edge := ROEdge from: el1 to: el2. line := ROLine new. line add: ROArrow new offset: 0.1. line add: ROArrow new offset: 0.5. edge + line. view add: el1; add: el2; add: edge. view open ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 7/14/2012 18:23'! multipleArrowOn: rawView | el1 el2 edge line | "A line shape can have several arrows on it." el1 := ROElement new. el1 @RODraggable. el1 extent: 50@50. el1 + ROBox blue. el2 := ROElement new. el2 @RODraggable. el2 extent: 50@50. el2 + ROBox green. el1 translateTo: 0 @ 100. edge := ROEdge from: el1 to: el2. line := ROLine new. line add: ROArrow new offset: 0.1. line add: ROArrow new offset: 0.5. edge + line. rawView add: el1; add: el2; add: edge. ! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 10/7/2012 13:46'! nestedLayoutOn: rawView | elements edges outterNode | outterNode := ROElement new + ROBorder blue. elements := ROElement spritesOn: (1 to: 5). outterNode addAll: elements. rawView add: outterNode. rawView addAll: (edges := ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third )). ROTreeLayout on: elements. ! ! !ROExample methodsFor: 'nesting' stamp: 'AlexandreBergel 11/23/2012 08:35'! nesting " self new nesting " | view innerNode outterNode | view := ROView new. innerNode := ROElement new extent: 40@30; + (ROBox new color: Color green); @ RODraggable. outterNode := ROElement new addInteraction: RODraggable; extent: 190@190; translateBy: 20@20; + (ROBorder new color: Color red). view add: outterNode. outterNode add: innerNode. view open. ! ! !ROExample methodsFor: 'nesting' stamp: 'AlexandreBergel 11/23/2012 08:34'! nesting2 " self new nesting2 " | view nodes | view := ROView new. view add: (ROElement sprite addAll: (nodes := ROElement spritesOn: (1 to: 20))). nodes do: [:n | n addShape: ROLabel]. ROCircleLayout on: nodes. view open. ! ! !ROExample methodsFor: 'nesting' stamp: 'AlexandreBergel 6/9/2012 18:42'! nesting3 " self new nesting3 " | view elements edges outterElement | view := ROView new. elements := ROElement spritesOn: (1 to: 5). outterElement := ROElement new. outterElement addAll: elements. outterElement addAll: (edges := ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third )). ROTreeLayout on: elements edges: edges. view add: outterElement. view open.! ! !ROExample methodsFor: 'nesting' stamp: 'AlexandreBergel 9/1/2013 11:43'! nestingOn: rawView | innerNode outterNode | innerNode := ROElement new extent: 40@30; + (ROBox new color: Color green); @ RODraggable. outterNode := ROElement new addInteraction: RODraggable; extent: 190@190; translateBy: 20@20; + (ROBorder new color: Color red). rawView add: outterNode. outterNode add: innerNode. ! ! !ROExample methodsFor: 'colors' stamp: 'AlexandreBergel 7/29/2012 10:14'! normalizer " self new normalizer " | view el | view := ROView new. self normalizerOn: view. view open! ! !ROExample methodsFor: 'colors' stamp: 'AlexandreBergel 7/29/2012 10:14'! normalizerOn: rawView | el normalizer nodes| normalizer := RONIdentityNormalizer beginingAtBlue. nodes := (1 to: 30) collect: [ :i | el := ROElement on: i. el @ RODraggable. el @ ROPopup. el extent: 60 @ 30. el + (ROBox new color: normalizer) + ROBorder. el ]. rawView addAll: nodes. ROGridLayout on: nodes. "-------------" ! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 12/1/2012 17:48'! omgParticules " self new omgParticules " | rawView | rawView := ROView new. self omgParticulesOn: rawView. rawView open.! ! !ROExample methodsFor: 'animation' stamp: 'VanessaPena 3/12/2013 15:30'! omgParticulesOn: rawView | particules | "Inspired from http://bl.ocks.org/1062544" particules := OrderedCollection new. rawView on: ROMouseMove do: [ :event | | newElem | newElem := ROElement new + ROEllipse. newElem extent: 10 @ 10. newElem translateTo: (rawView camera realToVirtualPoint: event position). particules addFirst: newElem. rawView add: newElem. rawView signalUpdate. (particules size = 70) ifTrue: [ particules last remove. particules removeLast ]. ]. ROPluggableAnimation new nbCycles: 300; block: [ particules do: [ :el | (el extent: (el extent + (3 @ 3))) ] ]; on: rawView. ! ! !ROExample methodsFor: 'free style' stamp: 'VanessaPena 8/23/2012 16:11'! pointillism " Idea from Pointillism by Daniel Shiffman at Prossesing self new pointillism " |view elto| view := ROView new. self pointillismOn: view. view open.! ! !ROExample methodsFor: 'free style' stamp: 'VanessaPena 3/12/2013 15:30'! pointillismOn: rawView | elto | rawView on: ROMouseMove do: [ :event | 5 timesRepeat: [ elto := ROElement new. elto size: (event position x / 10). elto + (ROEllipse color: (Color r: (155 atRandom / 255) g: (155 atRandom / 255) b: (155 atRandom / 255) alpha: 0.5)). elto translateTo: (500 atRandom @ 500 atRandom). rawView add: elto. rawView signalUpdate. ] ].! ! !ROExample methodsFor: 'interaction'! popup " self new popup " | view | view := ROView new. view add: ((ROElement spriteOn: 'world') + (ROLabel text: 'hello') @ (ROPopup)). view open.! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:37'! popupOn: rawView rawView add: ((ROElement spriteOn: 'world') + (ROLabel text: 'hello') @ (ROPopup)). ! ! !ROExample methodsFor: 'interaction'! popupView " self new popupView " | element view popupView | popupView := ROView new. popupView add: ((ROElement new extent: 50@60)+ (ROBox new color: Color blue)). view := ROView new. element := ROElement sprite. element @ (ROPopupView new view: popupView). view add: element. view open! ! !ROExample methodsFor: 'popup' stamp: 'AlexandreBergel 8/28/2013 16:09'! popupViewOn: rawView | popupView | popupView := ROView new. popupView add: (ROBox new extent: 40 @ 40) element. popupView add: (ROBox new extent: 40 @ 40) element. ROHorizontalLineLayout on: popupView elements. rawView add: ((ROElement spriteOn: 'world') + (ROLabel text: 'hello') @ (ROPopupView new view: popupView)).! ! !ROExample methodsFor: 'software' stamp: 'AlexandreBergel 7/14/2012 15:21'! punchChart "inspired from http://raphaeljs.com/github/dots.html self new punchChart " | rawView | rawView := ROView new. self punchChartOn: rawView. rawView @ RODraggable. rawView open! ! !ROExample methodsFor: 'software' stamp: 'AlexandreBergel 5/22/2013 11:14'! punchChartOn: rawView | classes metrics maxMetrics rx ry elements initialX initialY spaceX spaceY spaceYFromAxis spaceXFromAxis | "inspired from http://raphaeljs.com/github/dots.html" "Gathering the data" classes := OrderedCollection new. classes add: Object; add: Behavior; add: Metaclass; add: Collection; add: OrderedCollection. metrics := #(#numberOfMethods #numberOfVariables #numberOfSubclasses). "Visualzing the data" maxMetrics := metrics collect: [ :m | classes inject: 0 into: [:max :el | max max: (m roValue: el) ] ]. initialX := 30. initialY := 60. spaceX := 100. spaceY := 30. spaceYFromAxis := 20. spaceXFromAxis := 20. rx := initialX. ry := initialY. elements := OrderedCollection new. classes do: [:cls | ry := initialY. rx := rx + spaceX. metrics with: maxMetrics do: [ :m :mMax | | v | ry := ry + spaceX. v := m roValue: cls. elements add: ((ROElement on: cls) translateTo: rx @ ry; + (ROEllipse color: ((Color green mix: Color red shades: 30) at: (v max: mMax in: (1 to: 30)))); @ (ROPopup text: v printString); radius: ((m roValue: cls) max: mMax in: (5 to: 10))) ]. ry := ry + spaceYFromAxis. elements add: ((ROLabel elementOn: cls name) center: rx @ ry). ]. ry := initialY. rx := rx + spaceX. rx := rx + spaceXFromAxis. metrics do: [ :m | ry := ry + spaceX. elements add: ((ROLabel elementOn: m) center: rx @ ry) ]. rawView addAll: elements. ! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 10/21/2013 15:14'! radialTreeLayoutOn: rawView | nodes edges | nodes := (ROEllipse gray size: 10) elementsOn: Collection withAllSubclasses. nodes do: [ :n | n @ RODraggable ]. rawView addAll: nodes. edges := ROLine buildEdgesFromElements: nodes from: #superclass to: #yourself. rawView addAll: edges. RORadialTreeLayout new translator: (ROSmoothLayoutTranslator new nbCycles: 10); applyOn: nodes. ! ! !ROExample methodsFor: 'free style' stamp: 'VanessaPena 3/12/2013 15:30'! recursionProcessing " self new recursionProcessing " | view b | view := ROView new. b := [:x :radius :level | | tt | tt := 126 * level / 4.0. view add: ((ROElement new center: x@100 radius: radius) addShape: (ROEllipse new color: (Color gray256: tt) )). (level > 1) ifTrue: [ b value: (x - (radius / 2)) value: radius / 2 value: (level - 1). b value: (x + (radius / 2)) value: radius / 2 value: (level - 1). ] ]. b value: 126 value: 170 value: 6. view open ! ! !ROExample methodsFor: 'free style' stamp: 'AlexandreBergel 4/17/2012 17:14'! recursionProcessing2 " self new recursionProcessing2 " | view b | view := ROView new. self drawCircle: view x: 126 radius: 170 level: 6. view open ! ! !ROExample methodsFor: 'free style' stamp: 'VanessaPena 3/12/2013 15:30'! recursionProcessingOn: rawView | b | b := [ :x :radius :level | | tt | tt := 126 * level / 4.0. rawView add: ((ROElement new center: x@100 radius: radius) addShape: (ROEllipse new color: (Color gray256: tt) )). (level > 1) ifTrue: [ b value: (x - (radius / 2)) value: radius / 2 value: (level - 1). b value: (x + (radius / 2)) value: radius / 2 value: (level - 1). ] ]. b value: 126 value: 170 value: 6. ! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 3/12/2013 15:30'! resizableCircle " self new resizableCircle " | view circles colors | view := ROView new. colors := Color wheel: 6 alpha: 0.7. circles := (1 to: 6) with: colors collect: [:i :c | ROElement new @ RODraggable; + (ROEllipse color: c); translateTo: (i * 60) @ (i \\ 3 * 50 + 50); extent: 50@50. ]. view on: ROMouseMove do: [:event | circles do: [:c | | t | t := ((c bounds center - event position ) r / 2) max: 40. c size: t ]. view signalUpdate ]. view addAll: circles. view open. ! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 3/12/2013 15:30'! resizableCircleOn: rawView | circles colors | colors := Color wheel: 6 alpha: 0.7. circles := (1 to: 6) with: colors collect: [:i :c | ROElement new @ RODraggable; + (ROEllipse color: c); translateTo: (i * 60) @ (i \\ 3 * 50 + 50); extent: 50@50. ]. rawView on: ROMouseMove do: [:event | circles do: [:c | | t | t := ((c bounds center - event position ) r / 2) max: 40. c size: t ]. rawView signalUpdate ]. rawView addAll: circles. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/8/2013 15:31'! resizeParentStrategyOn: rawView | el el2 el3 | el := ROBox element. el @ RODraggable. el extent: 100 @ 80. "The parent cannot be resized" el resizeStrategy: ROFixedSizedParent instance. "The parent shrinks when inner nodes are drag and dropped" "el resizeStrategy: ROShrinkingParent instance." "Inner nodes can be dragged and dropped outside its parent" "el resizeStrategy: ROPermissiveParent instance." el2 := ROBox green element. el3 := ROBox red element. el2 extent: 20 @ 20. el3 extent: 20 @ 20. el2 @ RODraggable. el3 @ RODraggable. el add: el2; add: el3. rawView add: el. ! ! !ROExample methodsFor: 'interaction' stamp: 'BenComan 10/14/2012 23:20'! rubberBand " self new rubberBand " | view | view := ROView new. self rubberBandOn: view. view open! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/22/2013 18:02'! rubberBandOn: rawView | rubberband | "Drag edges from '1x' to '2x' then from '2x' to '3x' etc..." rubberband := RORubberBand new targeting: ( ROSelection new for: [ :source :target | source model first asInteger + 1 = target model first asInteger ]; onInclusion: [ :element | ROBlink highlight: element color: Color blue ]; onExclusion: [ :element | ROBlink unhighlight: element ] ); onDrop: [ :fromElement :toElement | RORemoveEdge edgesTo: toElement. fromElement view add: (ROEdge lineFrom: fromElement to: toElement). ROTreeLayout on: fromElement view elements. ]. 1 to: 4 do: [ :num | "$a asInteger = 97 en Pharo" "$d asInteger = 100 en Pharo" 97 asInteger to: 100 do: [ :charInt | | element | element := (ROElement on: num asString , charInt asCharacter asString) + ROBorder red + ROLabel. element extent: 40 @ 40. element @ rubberband. rawView add: element. ] ]. ROTreeLayout on: rawView elements.! ! !ROExample methodsFor: 'layouts' stamp: 'VanessaPena 3/12/2013 15:30'! scatterPlot " self new scatterPlot " | view elements | view := ROView new. elements := ROElement forCollection: #(#(1 2) #(100 50) #(60 20)). elements do: [:el | el addShape: ROEllipse; size: 30 ]. view addAll: elements. ROScatterplotLayout new x: #first ; y: #second; applyOn: elements. view open.! ! !ROExample methodsFor: 'layouts' stamp: 'VanessaPena 3/12/2013 15:30'! scatterPlotOn: rawView | elements | elements := ROElement forCollection: #(#(1 2) #(100 50) #(60 20)). elements do: [:el | el addShape: ROEllipse; size: 30 ]. rawView addAll: elements. ROScatterplotLayout new x: #first ; y: #second; applyOn: elements. ! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 6/9/2012 18:42'! scrollbar | view els stack | view := ROView new. view add: ROElement sprite. els := ROElement spritesOn: (1 to: 500). els do: [ :el | el + ROLabel @ ROPopup ]. view addAll: (ROGridLayout on: els). view @ RODraggable . stack := ROViewStack new. stack addView: view. stack @ ROScrollbable. stack open.! ! !ROExample methodsFor: 'animation' stamp: 'AlexandreBergel 12/13/2012 17:46'! spaceInvaderOn: rawView | ascii1 ascii2 ascii3 monsterAscii color size monster b | ascii1 := ' XX XX XX XX XXXXXXXXXXXX XXX XXXX XXX XXXXXXXXXXXXXXXX X XXXXXXXXXX X X X X X XXX XXX '. ascii2 := ' XXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXX XXX XXX XXX XXXXXXXXXXXXXXX XXX XXX XX XXX XX XX XX '. ascii3 := ' XXXXXXX XXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXX XXX XXXX XXXXXXXXXXXXXXX XX XX XX XXX XX XX XX XX XX'. b := [ monsterAscii := (Array with: ascii1 with: ascii2 with: ascii3) at: 3 atRandom. color := (Array with: Color blue with: Color black with: Color yellow with: Color red) at: 4 atRandom. size := 20 atRandom + 10. monster := ROExample new monsterFrom: monsterAscii color: color size: size. monster translateTo: 600 atRandom @ (monster position y negated). rawView add: monster. ROLinearMove new nbCycles: 200 atRandom; for: monster to: 600 atRandom @ 600; after: [ monster remove. b value ] ]. b value; value; value.! ! !ROExample methodsFor: 'nesting' stamp: 'AlexandreBergel 6/10/2012 15:59'! stack " self new stack " | view1 label1 stack view2 label2 view3 label3 | view1 := ROView new. label1 := (ROElement on: 'view 2') + ROLabel @ ROLightlyHighlightable. label1 on: ROMouseClick do: [ :event | stack replaceFirstBy: view2 ]. view1 add: label1. view1 addAll: (ROGridLayout on: (ROElement spritesOn: (1 to: 20))). view2 := ROView new. label2 := (ROElement on: 'view 3') +ROLabel @ ROLightlyHighlightable. label2 on: ROMouseClick do: [ :event | stack replaceFirstBy: view3 ]. view2 add: label2. view2 addAll: (ROCircleLayout on: (ROElement spritesOn: (1 to: 20))). view3 := ROView new. label3 := (ROElement on: 'view 1') +ROLabel @ ROLightlyHighlightable. label3 on: ROMouseClick do: [ :event | stack replaceFirstBy: view1 ]. view3 add: label3. view3 addAll: (ROHorizontalLineLayout on: (ROElement spritesOn: (1 to: 20))). stack := ROViewStack new addFirst: view1. stack open! ! !ROExample methodsFor: 'resizing' stamp: 'AlexandreBergel 8/28/2013 16:11'! stretchHorizontalyOn: rawView | container1 container2 | container1 := ROBorder elementOn: 'container1'. container2 := ROBorder elementOn: 'container2'. rawView add: container1. rawView add: container2. container1 extent: 20 @ 20. ROVerticalLineLayout new gapSize: 0; on: rawView elements. ROResize stretchHorizontally: rawView elements.! ! !ROExample methodsFor: 'resizing' stamp: 'AlexandreBergel 8/28/2013 16:11'! stretchVerticalyOn: rawView | container1 container2 | container1 := ROBorder elementOn: 'container1'. container2 := ROBorder elementOn: 'container2'. rawView add: container1. rawView add: container2. container1 extent: 20 @ 20. ROHorizontalLineLayout new gapSize: 0; on: rawView elements. ROResize stretchVertically: rawView elements.! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 6/9/2012 18:42'! treeLayout " self new treeLayout " | view elements edges | view := ROView new. elements := ROElement spritesOn: (1 to: 5). view addAll: elements. view addAll: (edges := ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third )). ROTreeLayout on: elements. view open.! ! !ROExample methodsFor: 'layouts' stamp: 'AlexandreBergel 7/14/2012 18:42'! treeLayoutOn: rawView | elements edges | elements := ROElement spritesOn: (1 to: 5). rawView addAll: elements. rawView addAll: (edges := ROEdge linesFor: (Array with: elements first -> elements second with: elements second -> elements fifth with: elements second -> elements third )). ROTreeLayout on: elements. ! ! !ROExample methodsFor: 'colors' stamp: 'AlexandreBergel 9/24/2013 09:56'! varyingHueOn: rawView | el1 el2 | el1 := (ROBox new extent: 100 @ 100) element. el2 := (ROBox new extent: 100 @ 100) element. rawView add: el1; add: el2. rawView on: ROMouseMove do: [ :event | (el1 getShape: ROBox) color: (Color h: event position y \\ 360 s: 100 v: 100). (el2 getShape: ROBox) color: (Color h: (360 - (event position y \\ 360)) s: 100 v: 100). rawView signalUpdate. ]. ROConstraint move: el2 onTheRightOf: el1.! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 9/1/2013 11:45'! verticalLabel " ROExample new verticalLabel " | rawView| rawView := ROView new. self verticalLabelOn: rawView. rawView open! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 9/1/2013 11:44'! verticalLabelOn: rawView -15 to: 10 do: [ :i | rawView add: ((ROLabel verticalText interlineSpace: i) elementOn: 'hello world'). ]. ROHorizontalLineLayout on: rawView elements. ! ! !ROExample methodsFor: 'basic' stamp: 'AlexandreBergel 1/25/2013 08:51'! zIndexOn: rawView | normalizerSize elements | elements := ROElement forCollection: (1 to: 20). elements do: [ :el | el + (ROBorder new size: 30). el + (ROBox new color: (el model odd ifTrue: [ Color blue ] ifFalse: [ Color green ])). el @ RODraggable ]. rawView addAll: elements. ROHorizontalLineLayout on: (elements select: [ :el | el model odd ]). ROHorizontalLineLayout on: (elements select: [ :el | el model even ]). (elements select: [ :el | el model even ]) do: [ :el | el translateBy: 5 @ 5 ]. "Elements are displayed from low zIndex to high zIndex" rawView zOrdering: (ROZOrdering new setZIndex: 5 if: [ :el | el model odd ]; "Will be displayed first" setZIndex: 10 if: [ :el | el model even ]). ! ! !ROExample methodsFor: 'interaction' stamp: 'VanessaPena 1/3/2013 18:10'! zooming " self new zooming " | view els classes stack | view := ROView new. view @ ROMiniMap . self zoomingOn: view. view open.! ! !ROExample methodsFor: 'interaction' stamp: 'AlexandreBergel 7/14/2012 18:39'! zoomingOn: rawView | els classes stack | "We gather what we want to visualize" classes := Smalltalk globals allClasses select: [ :c | c name beginsWith: 'RO' ]. "We build the visualization" els := ROElement forCollection: classes. els do: [:spr | spr extent: 50@50. spr + ROBorder red. spr @ ROZoomOnClick @ RODraggable ]. rawView addAll: els. ROGridLayout on: els. ! ! !ROMondrianExample commentStamp: '' prior: 34304320! Example for the Mondrian builder! !ROMondrianExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:48'! postScript ^ ' "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view open'! ! !ROMondrianExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:34'! preamble ^ 'rawView := ROView new. view := ROMondrianViewBuilder view: rawView.'! ! !ROMondrianExample class methodsFor: 'easel' stamp: 'AlexandreBergel 7/14/2012 15:34'! preambleVariables ^ #('view' 'rawView')! ! !ROMondrianExample methodsFor: 'interations' stamp: 'VanessaPena 4/12/2013 13:28'! addAndRemoveInteractivelyOn: view |closed| closed := true. view shape rectangle withText size: 40. view interaction item: 'open/close' action: [ closed ifTrue: [ view shape rectangle withText size: 40. view nodes: (2 to: 4). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->4); yourself) from: #key to: #value. view treeLayout. view applyLayout. closed := false.] ifFalse: [ view removeNodesAndEdgesOf: (2 to: 4). view treeLayout. view applyLayout. closed := true. ] ]. view node: 1. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/19/2013 13:52'! addingColoredNameOn: view "Hovering the mouse on a class give a name to its superclass" view shape rectangle size: 10. view interaction on: ROMouseEnter do: [ :event | | elSuperclass | elSuperclass := view elementFromModel: event model superclass. elSuperclass notNil ifTrue: [ ROAddName new color: Color red; toElement: elSuperclass ] ]. view interaction on: ROMouseLeave do: [ :event | | elSuperclass | elSuperclass := view elementFromModel: event model superclass. elSuperclass notNil ifTrue: [ ROAddName removeFrom: elSuperclass ] ]. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 3/6/2013 15:50'! addingNameOn: view "Hovering the mouse on a class give a name to its superclass" view shape rectangle size: 10. view interaction on: ROMouseEnter do: [ :event | | elSuperclass | elSuperclass := view elementFromModel: event model superclass. elSuperclass notNil ifTrue: [ ROAddName toElement: elSuperclass ] ]. view interaction on: ROMouseLeave do: [ :event | | elSuperclass | elSuperclass := view elementFromModel: event model superclass. elSuperclass notNil ifTrue: [ ROAddName removeFrom: elSuperclass ] ]. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'alpha blending' stamp: 'AlexandreBergel 5/17/2013 18:14'! alpha2On: view | random nodes | random := Random new. view shape circle size: 80; fillColor: Color black. view interaction on: ROMouseEnter do: [ :event | ROColorAlphaFading new for: event element nbCycles: 60 ]. nodes := view nodes: (1 to: 50). nodes do: [:el | el translateTo: (random next * 400) @ (random next * 400) ]. view noLayout. ROPluggableAnimation new nbCycles: 20000; block: [ ROColorAlphaFading new for: nodes atRandom nbCycles: 60 ]; on: view raw.! ! !ROMondrianExample methodsFor: 'alpha blending' stamp: 'AlexandreBergel 5/17/2013 18:09'! alphaOn: view view shape circle size: 80; fillColor: Color black. view interaction on: ROMouseEnter do: [ :event | ROColorAlphaFading new for: event element nbCycles: 60 ]. view nodes: (1 to: 50). view gridLayout.! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 7/28/2012 21:42'! attachPoint " self new attachPoint " | view | view := ROMondrianViewBuilder new. self attachPointOn: view. view open! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 7/28/2012 21:41'! attachPointOn: view view nodes: (ROAttachPoint subclasses) forEach: [ :cls | view shape rectangle size: 20. view nodes: #(1 2 3). view shape line attachPoint: cls new. view edgesFromAssociations: (Array with: 1-> 2 with: 2 -> 3 with: 1 -> 3). view circleLayout ].! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 5/17/2013 10:18'! bezierCurveOn: view view shape circle size: 10. view nodes: (Collection withAllSubclasses). view shape bezierLine. view edgesFrom: #superclass. view radialTreeLayout. view center. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/18/2012 09:01'! bottomFlowLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. view bottomFlowLayout. ! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 3/6/2013 15:23'! centeredText " self new centeredText " | view | view := ROMondrianViewBuilder new. self centeredTextOn: view. view open! ! !ROMondrianExample methodsFor: 'basic' stamp: 'VanessaPena 3/6/2013 16:34'! centeredTextOn: view view shape rectangle; withCenteredText; width: 180. view node: 'centered text'. view shape rectangle; withText; width: 180. view node: 'left text'. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 10/21/2013 15:05'! chooseLayoutOn: view (ROGridLayout on: ( ((OrderedCollection new) add: ROTreeLayout; add: ROGridLayout; add: ROForceBasedLayout; add: ROCircleLayout; add: ROHorizontalTreeLayout; add: ROVerticalLineLayout; add: ROHorizontalLineLayout; add: ROSugiyamaLayout; add: ROBottomFlowLayout; add: ROFlowLayout; add: RONarrowRadialTreeLayout; add: ROScatterplotLayout; yourself) collect: [ :layoutClass | | button | button := ((ROElement on: layoutClass name) + ROLabel @ ROLightlyHighlightable + ROBorder). button on: ROMouseLeftClick do: [ :event | layoutClass new translator: (ROSmoothLayoutTranslator new nbCycles: 10); applyOn: (view raw elementsFromModels: (1 to: 5)) ]. view stack firstView add: button. button ])) do: [ :button | button translateBy: 0 @ 380 ]. "We start with a very simple graph" view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edgesFromAssociations: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself). "We use circle layout as default layout" view circleLayout executeOnElements: (view raw elementsFromModels: (1 to: 5)). ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/18/2012 09:02'! circleLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. view circleLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:28'! clickToFocus " self new clickToFocus " | builder | builder := ROMondrianViewBuilder titled: 'Finding nodes'. self clickToFocusOn: builder. builder open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 9/29/2012 14:50'! clickToFocusOn: view view interaction on: ROMouseClick do: [ :event | ROFocusView on: event element ]. view shape rectangle size: 30. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 6/12/2013 06:10'! coloredEdgesOn: view view shape circle size: 10. view nodes: (1 to: 20). view shape line color: [ :edge | (#( 2 3 4) includes: edge from model) ifTrue: [ Color red. ] ifFalse: [ Color lightGray ] ]. view edgesToAll: [ :v | Array with: v + 3 with: v + 5 with: v *2 ]. view circleLayout. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 9/26/2012 19:44'! coloredSystemComplexity " self new systemComplexity " | view elements edge | view := ROMondrianViewBuilder new. self coloredSystemComplexityOn: view. view open. ^ view! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 9/26/2012 19:44'! coloredSystemComplexityOn: view view shape rectangle width: [ :cls | cls numberOfVariables * 7 ]; height: #numberOfMethods; fillColor: (RONColorLinearNormalizer inContext: (Collection withAllSubclasses) withCommand: #numberOfLinesOfCode lowColor: Color green highColor: Color red). view interaction popupText: [ :cls | cls name, (String with: Character cr), cls methods size printString, ' methods', (String with: Character cr), cls instVarNames size printString, ' variables', (String with: Character cr), cls numberOfLinesOfCode printString, ' LOC' ]. view interaction action: #browse. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout.! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/7/2012 11:49'! command " self new command An example that shows the commands that can be defined on the builder. Useful to add menus. " | view | view := ROMondrianViewBuilder new. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. view addMenu: 'Inspect stack' callBack: [ :stack | stack inspect. ]. view addMenu: '+Node Background' callBack: [ :stack | stack firstView add: (ROElement sprite translateTo: 200 atRandom @ 200 atRandom). stack signalUpdate ]. view addMenu: '+Node Foreground' callBack: [ :stack | | el | el := ROElement sprite translateTo: 200 atRandom @ 200 atRandom. (el getShape: ROBorder) color: Color blue. stack add: el. stack signalUpdate ]. view addMenu: 'Zoom in' callBack: [ :stack | ROZoomInMove new on: stack firstView ]. view addMenu: 'Zoom out' callBack: [ :stack | ROZoomOutMove new on: stack firstView ]. view open.! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/8/2013 16:05'! dynamicEdgeOn: view view interaction dynamicEdgeToAll: [ :model | (Array with: 10 with: 20 with: 30) copyWithout: model ] using: (ROLine arrowed color: Color red). view shape rectangle size: 20. view nodes: (Array with: 10 with: 20 with: 30). view circleLayout.! ! !ROMondrianExample methodsFor: 'alpha blending' stamp: 'AlexandreBergel 5/17/2013 18:31'! dynamicFadingEdgesOn: view view interaction dynamicEdgeToAll: [ :model | (1 to: model) collect: [ :v | v // 2 ] ] usingFading: (ROLine red width: 5; attachPoint: ROCenteredAttachPoint instance). view shape rectangle size: 20. view nodes: (1 to: 20). view circleLayout.! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/22/2013 17:51'! dynamicForceBasedLayoutOn: view | layout | "rawView resizeStrategy:(ROPermissiveParent instance)." view interaction on: ROMouseEnter do: [ :n | | nodes | nodes := view raw elementsFromModels: n element model allSubclasses. ROBlink highlightElements: nodes ]. view interaction on: ROMouseLeave do: [ :n | | nodes | nodes := view raw elementsFromModels: n element model allSubclasses. ROBlink unhighlightElements: nodes ]. view interaction on: ROMouseClick do: [ :event | layout := ROForceBasedLayout new. layout fix: event element at: event element position. layout iterationsToSendEvent: 10. layout on: ROLayoutStep do: [ :ev | view raw signalUpdate. World doOneCycle ]. view layout: layout. view applyLayout ]. view shape rectangle size: 10. view nodes: (Collection withAllSubclasses). view edgesFrom: #superclass. layout := ROForceBasedLayout new. layout fix: (view nodes last) at: 450@450; gravityAt: 437@38 . view layout: layout.! ! !ROMondrianExample methodsFor: 'dynamic lines' stamp: 'AlexandreBergel 5/8/2013 16:11'! dynamicLines2On: view | dep | dep := Dictionary new. dep at: #Layer1 put: #(Layer2 Layer3 Layer5). dep at: #Layer2 put: #(Layer1 Layer3 Layer4 Layer5). dep at: #Layer3 put: #(Layer1 Layer2 Layer4 Layer5). view interaction dynamicEdgeToAll: [ :model | dep at: model ifAbsent: #() ] using: (ROLine red). view shape rectangle withText. view nodes: #(Layer1 Layer2 Layer3 Layer4 Layer5). view circleLayout.! ! !ROMondrianExample methodsFor: 'dynamic lines' stamp: 'AlexandreBergel 5/19/2013 15:41'! dynamicLines3On: view | dep | dep := Dictionary new. dep at: #Layer1 put: #(Layer2 Layer3 Layer5). dep at: #Layer2 put: #(Layer1 Layer3 Layer4 Layer5). dep at: #Layer3 put: #(Layer1 Layer2 Layer4 Layer5). view interaction dynamicEdgeFromAll: [ :model | dep at: model ifAbsent: #() ] using: (ROLine red add: ROArrow new). view shape rectangle withText. view nodes: #(Layer1 Layer2 Layer3 Layer4 Layer5). view circleLayout.! ! !ROMondrianExample methodsFor: 'dynamic lines' stamp: 'AlexandreBergel 5/8/2013 16:10'! dynamicLinesOn: view view interaction dynamicEdgeToAll: [ :model | (1 to: model) collect: [ :v | v // 2 ] ] using: (ROLine red attachPoint: ROCenteredAttachPoint instance). view shape rectangle size: 20. view nodes: (1 to: 20). view circleLayout. ! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 7/25/2012 17:01'! edgesDefinedOutsideOn: view "The edges is defined outside the inner nodes. The layout takes those edges into account" view nodes: #(1 2) forEach: [ :each | view shape label. view nodes: (Array with: each * 10 with: (each * 100)). view treeLayout. ]. view edgesFromAssociations: (Array with: 10 -> 100 with: 20 -> 200).! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 1/30/2013 12:11'! explicitIdentityNormalizer2On: view view shape rectangle size: 30; fillColor: (RONExplicitIdentityNormalizer withCommand: #yourself withColors: (Array with: Color blue with: Color white with: Color red) withDefaultColor: Color pink). view nodes: #(#foo #bar #zork #foo #bar #zork).! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 7/2/2012 23:53'! explicitIdentityNormalizerOn: view view shape rectangle size: 30; fillColor: ( RONExplicitIdentityNormalizer withCommand: #yourself withColors: (Array with: Color blue with: Color white with: Color red) withDefaultColor: Color pink). view nodes: (5 to: 10).! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 4/29/2013 16:51'! fixedSizeNodeOn: view view node: 1 forIt: [ view shape rectangle size: 20. view nodes: (1 to: 9). view gridLayout ]. view horizontalLineLayout on: ROLayoutEnd do: [ :event | view raw elementsDo: [ :el | el resizeStrategy: (ROFixedSizedParent instance) ] ].! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/18/2012 09:01'! flowLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. view flowLayout. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/17/2012 20:36'! forceBasedLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. view forceBasedLayout. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/18/2012 08:49'! gridLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view gridLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:13'! highlight " self new highlight " | view | view := ROMondrianViewBuilder new. self highlightOn: view. view open. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:29'! highlightInnerNodes " self new highlightInnerNodes " | view | view := ROMondrianViewBuilder new. self highlightInnerNodesOn: view. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/3/2012 09:38'! highlightInnerNodesOn: view view nodes: (1 to: 5) forEach: [:each | view interaction highlightNodesWhenOver: [ :node | Array with: node ]. view shape rectangle withText; size: 20. view nodes: (1 to: each). view gridLayout ]. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 6/11/2013 06:46'! highlightOn: view view interaction highlightWhenOver: [ :cls | cls allSubclasses ]. view shape rectangle size: 10. view nodes: (Collection withAllSubclasses). view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 4/18/2012 16:35'! highlightSeveralNodes " self new highlightSeveralNodes " | view nodes | view := ROMondrianViewBuilder new. view interaction highlightWhenOver: [:v | ((Array new: 4) at: 1 put: v - 1; at: 2 put: v + 1; at: 3 put: v + 4; at: 4 put: v - 4; yourself) ]. view shape rectangle width: 40; height: 30; borderColor: Color black; borderWidth: 2. nodes := view nodes: (1 to: 16). view gridLayout gapSize: 2. view open. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/22/2013 17:52'! highlightUsingBezierOn: view view interaction on: ROMouseEnter do: [ :n | | nodes | nodes := view raw elementsFromModels: n element model allSubclasses. ROBlink highlightElements: nodes ]. view interaction on: ROMouseLeave do: [ :n | | nodes | nodes := view raw elementsFromModels: n element model allSubclasses. ROBlink unhighlightElements: nodes ]. view shape rectangle size: 10. view nodes: (Collection withAllSubclasses). view shape bezierLine. view edgesFrom: #superclass. view radialTreeLayout. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 10/1/2012 09:42'! horizontalTreeLayoutLayeredOn: view view shape rectangle width: #yourself. view nodes: (1 to: 100). view edgesFrom: [:x | x // 2 ]. view horizontalTreeLayout layered. ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 10/1/2012 09:42'! horizontalTreeLayoutNoLayeredOn: view view shape rectangle width: #yourself. view nodes: (1 to: 100). view edgesFrom: [:x | x // 2 ]. view horizontalTreeLayout. ! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 1/30/2013 12:10'! identityNormalizer2On: view view shape rectangle size: 30; fillColor: RONIdentityNormalizer beginingAtRed. view nodes: #(#foo #bar #zork). ! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 7/2/2012 16:23'! identityNormalizerOn: view view shape rectangle size: 30; fillColor: RONIdentityNormalizer new. view nodes: (1 to: 30) , (30 to: 1). ! ! !ROMondrianExample methodsFor: 'basic' stamp: 'ChrisCunningham 2/15/2013 15:52'! labeledCircle " self new labeledCircle " | view | view := ROMondrianViewBuilder new. self labeledCircleOn: view. view open! ! !ROMondrianExample methodsFor: 'basic' stamp: 'ChrisCunningham 2/15/2013 15:53'! labeledCircleOn: view view shape circle withText. view node: 'With rectangle'. view shape label. view node: 'Without rectangle'. view shape circle. view node: 'Without text'. ! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/2/2012 18:30'! labeledRectangle " self new labeledRectangle " | view | view := ROMondrianViewBuilder new. self labeledRectangleOn: view. view open! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/3/2012 09:38'! labeledRectangleOn: view view shape rectangle withText. view node: 'With rectangle'. view shape label. view node: 'Without rectangle'. ! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 9/25/2012 15:27'! lineWidthOn: view view shape rectangle size: 50. view nodes: #( 1 2 ). view shape line width: 4. view interaction popupText: 'edge!!'. view edgeFromAssociation: 1 -> 2. ! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 7/2/2012 23:54'! linearNumberOn: view view shape rectangle size: ((RONumberLinearNormalizer inContext: #(1 2 3 4 3 2 1)) scale: 50). view nodes: #(1 2 3 4 3 2 1). "The script above has the same effect than: | maxPixel maxValue | maxPixel := 50. maxValue := 4. view shape rectangle size: [:v | (v * maxPixel / maxValue) asInteger ]. view nodes: {1 . 2 . 3 . 4 . 3 . 2 . 1} "! ! !ROMondrianExample methodsFor: 'edges' stamp: 'VanessaPena 12/23/2012 20:52'! lines " self new lines " | view | view := ROMondrianViewBuilder new. self linesOn: view. view open.! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 5/3/2012 09:38'! linesOn: view view shape label. view nodes: #(1 2 3 4 5 6 7 8 9 10). view edges: #(1 2 3 4 5 6 7 8 9 10) from: #yourself toAll: (#(1 2 3 4 5 6 7 8 9 10) select: #odd). view circleLayout.! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 7/2/2012 16:24'! lowerBoundNormalizerOn: view "Color normalizer use white as the lower bound. But it could be any color" view shape rectangle size: 30; fillColor: (RONColorLinearNormalizer inContext: (1 to: 10) lowColor: Color gray highColor: Color black). view nodes: (1 to: 10).! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 7/28/2012 22:44'! makingInvisibleEdgesOn: view "The mondrian builder adds a shape per default. But this can be easily bypassed by using the low level facilities of Roassal" view nodes: Collection withAllSubclasses. (view edgesFrom: #superclass) do: [ :edge | edge - ROEdge ]. view treeLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:31'! menuOnNodes " self new menuOnNodes Right click on a node gives a menu " | view | view := ROMondrianViewBuilder new. self menuOnNodesOn: view. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 10/2/2012 20:31'! menuOnNodesOn: view view shape rectangle size: 15. view interaction item: 'inspect element' action: #inspect; item: 'inspect model' action: [ :el | el model inspect ]; item: 'browse element class' action: [ :el | el model browse ]. view nodes: (1 to: 5). ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 5/3/2012 19:21'! methodComplexity " self new methodComplexity " | view d connectedMethods disconnectedMethods methodShape | view := ROMondrianViewBuilder titled: 'Method Complexity'. self methodComplexityOn: view. view open! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 5/7/2013 13:55'! methodComplexityFor: classes on: view | d connectedMethods disconnectedMethods | view nodes: classes forEach: [ :cls | d := IdentityDictionary new. cls methods do: [ :cm | d at: cm selector put: cm messages ]. d copy keysAndValuesDo: [ :key :messages | d at: key put: (messages intersection: d keys) ]. connectedMethods := d keys select: [ :k | (d at: k) notEmpty ]. disconnectedMethods := d keys select: [ :k | (d at: k) isEmpty ]. "Connected methods" view shape rectangle withoutBorder. view node: cls forIt: [ view shape rectangle size: [ :sym | (cls >> sym) sourceCode lines size ]. view interaction popupText: [ :sym | (cls >> sym) sourceCode ]. view nodes: connectedMethods. view edges: connectedMethods from: #yourself toAll: [ :cm | d at: cm ]. view sugiyamaLayout. ]. "Disconnected methods" view shape rectangle withoutBorder. view node: cls forIt: [ view shape rectangle size: [ :sym | (cls >> sym) sourceCode lines size ]. view interaction popupText: [ :sym | (cls >> sym) sourceCode ]. view nodes: disconnectedMethods. view gridLayout. ]. ]. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 5/7/2013 13:56'! methodComplexityOn: view | classesToAnalyze | "We analyze only the classes of Roassal" classesToAnalyze := (Object allSubclasses select: [ :cls | cls name beginsWith: 'RO' ]). view nodes: classesToAnalyze forEach: [ :cls | | d connectedMethods disconnectedMethods nativeUtil | d := IdentityDictionary new. nativeUtil := RONativeExampleUtility current . (nativeUtil getMethodsForClass: cls) do: [ :cm | d at: cm selector put: cm messages ]. d copy keysAndValuesDo: [ :key :messages | d at: key put: (messages intersection: d keys) ]. connectedMethods := d keys select: [ :k | (d at: k) notEmpty ]. disconnectedMethods := d keys select: [ :k | (d at: k) isEmpty ]. "Connected methods" view shape rectangle withoutBorder. view node: cls forIt: [ view shape rectangle size: [ :sym | (cls >> sym) sourceCode lines size ]. view interaction popupText: [ :sym | (cls >> sym) sourceCode ]. view nodes: connectedMethods. view edges: connectedMethods from: #yourself toAll: [ :cm | d at: cm ]. view sugiyamaLayout. ]. "Disconnected methods" view shape rectangle withoutBorder. view node: cls forIt: [ view shape rectangle size: [ :sym | (cls >> sym) sourceCode lines size ]. view interaction popupText: [ :sym | (cls >> sym) sourceCode ]. view nodes: disconnectedMethods. view gridLayout. ]. ]. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 7/30/2012 00:01'! middleArrowOnEdgesOn: view view shape label. view nodes: #(1 2 3 ). view shape arrowedLineWithOffset: 0.5. view edgesFromAssociations: (Array with: 1 -> 2 with: 2 -> 3 with: 3 -> 1). view circleLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'VanessaPena 1/2/2013 15:46'! miniMap " self new miniMap " |view| view := ROMondrianViewBuilder new. self miniMapOn: view. view open.! ! !ROMondrianExample methodsFor: 'interations' stamp: 'VanessaPena 1/3/2013 18:10'! miniMapOn: view view raw @ (ROMiniMap new targetView: view stack). "press m to open the view minimap " view shape rectangle width: [ :cls | cls numberOfVariables * 5 ]; height: #numberOfMethods; linearFillColor: #numberOfLinesOfCode within: Collection withAllSubclasses. view interaction popupText: [ :cls | cls name, (String with: Character cr), cls methods size printString, ' methods', (String with: Character cr), cls instVarNames size printString, ' variables', (String with: Character cr), cls numberOfLinesOfCode printString, ' LOC' ]. view interaction action: #browse. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout.! ! !ROMondrianExample methodsFor: 'interations' stamp: 'VanessaPena 1/3/2013 16:36'! mouseMoveOn: view |node| view shape rectangle size: 50. node := view node: 'Hola'. view raw on: ROMouseMove do: [:event | |position x y| position := event position - node position. (position x = 0) ifTrue: [ x := 0 ] ifFalse: [ x := (position x / (position x abs)) ]. (position y = 0) ifTrue: [ y := 0 ] ifFalse: [ y := (position y / (position y abs)) ]. node translateByRealPoint: x@y. view raw signalUpdate .].! ! !ROMondrianExample methodsFor: 'key pressing' stamp: 'VanessaPena 1/2/2013 15:41'! moveViewWithKeys " self new keyPressingMondrian " |view | view := ROMondrianViewBuilder new. self moveViewWithKeysOn: view. view open.! ! !ROMondrianExample methodsFor: 'key pressing' stamp: 'VanessaPena 1/2/2013 15:41'! moveViewWithKeysOn: view view stack on: ROKeyDown do: [:evt | |keyValue| keyValue := evt keyValue. keyValue = 30 "up arrow" ifTrue: [view raw translateBy: 0@1]. keyValue = 31 "down arrow" ifTrue: [view raw translateBy: 0@(-1)]. keyValue = 29 "right arrow" ifTrue: [view raw translateBy: (-1)@0]. keyValue = 28 "left arrow" ifTrue: [view raw translateBy: 1@0] ]. view shape rectangle size: 50; color: Color green. view nodes: (1 to: 400). view gridLayout.! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:34'! multilineLabel " self new multilineLabel " | view | view := ROMondrianViewBuilder new. self multilineLabelOn: view. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 1/30/2013 12:03'! multilineLabelOn: view view shape label text: [:m | 'line1 line2 line3 ']; color: Color blue. view node: 'a'.! ! !ROMondrianExample methodsFor: 'normalizers' stamp: 'AlexandreBergel 7/4/2012 00:04'! multipleColorLinearOn: view view shape rectangle size: 60; fillColor: (ROMultipleColorLinearNormalizer valueRange: #(5 10 15) colorRange: (Array with: Color blue with: Color white with: Color red)). view nodes: (5 to: 15). ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:35'! nodraggable " self new nodraggable " | view | view := ROMondrianViewBuilder new. self nodraggableOn: view. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/2/2012 18:35'! nodraggableOn: view view interaction nodraggable. view shape label. view node: 'Cannot be dragged'. view shape label. view node: 'Can be dragged'.! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 8/22/2012 18:58'! orthoHorizontalWithArrowLineOn: view view nodes: ( Array with: [ROHorizontalArrow new offset: 0] with: [ROReversedHorizontalArrow new offset: 0] with: [ROHorizontalArrow new offset: 1] with: [ROReversedHorizontalArrow new offset: 1] ) forEach: [ :exampleBlock | view shape rectangle size: 20. view nodes: (1 to: 16). view shape: (ROOrthoHorizontalLineShape new add: exampleBlock value ). view edgesFrom: [ :i | (i / 4) ceiling ]. view horizontalTreeLayout verticalGap: 10. ]. view horizontalLineLayout. ! ! !ROMondrianExample methodsFor: 'edges' stamp: 'AlexandreBergel 7/30/2012 00:02'! orthoVerticalLineOn: view view shape rectangle size: 20. view nodes: (1 to: 20). view shape: (ROOrthoVerticalLineShape new). view edgesFrom: [ :i | i \\ 3 ]. view treeLayout. ! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 8/22/2012 18:59'! orthoVerticalWithArrowLineOn: view view nodes: (Array with: [ROVerticalArrow new offset: 0] with: [ROReversedVerticalArrow new offset: 0] with: [ROVerticalArrow new offset: 1] with: [ROReversedVerticalArrow new offset: 1] ) forEach: [ :exampleBlock | view shape rectangle size: 20. view nodes: (1 to: 16). view shape: (ROOrthoVerticalLineShape new add: exampleBlock value ). view edgesFrom: [ :i | (i / 4) ceiling ]. view treeLayout horizontalGap: 10. ]. view verticalLineLayout. ! ! !ROMondrianExample methodsFor: 'software visualization'! polymetricViewWithMethods " self new polymetricViewWithMethods " | view classes elements edge nodes | "Gathering the data" classes := ROTest withAllSubclasses. "Visualzing the data" view := ROMondrianViewBuilder new. view shape rectangle width: #numberOfVariables; height: #numberOfMethods; linearFillColor: #numberOfLinesOfCode within: classes. nodes := view nodes: classes. nodes do: [:n | n @ ROZoomOnClick ]. view edgesFrom: #superclass. view treeLayout. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 4/30/2012 17:29'! popupAndNoPopup " self new popupAndNoPopup " | view | view := ROMondrianViewBuilder titled: 'Popup and No popup'. view interaction noPopup. view shape label. view node: 'I have _no_ popup'. view shape label. view node: 'I have a popup'. view interaction noPopup. view shape label. view node: 'I have _no_ popup'. view open! ! !ROMondrianExample methodsFor: 'interations'! popupView " self new popupView " | view | view := ROMondrianViewBuilder new. view shape label. view interaction popupView: [ :entity :myView | myView nodes: entity withAllSuperclasses. myView nodes: entity allSubclasses. myView edgesFrom: #superclass. myView treeLayout. ]. (view nodes: (Array with: ROEvent with: Collection)). view open ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/3/2012 09:43'! popupViewOn: view view shape label. view interaction popupView: [ :entity :myView | myView nodes: entity withAllSuperclasses. myView nodes: entity allSubclasses. myView edgesFrom: #superclass. myView treeLayout. ]. (view nodes: (Array with: ROEvent with: Collection)). ! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 1/30/2013 12:11'! scatterLayoutOn: view view node: 'scatter layout' forIt: [ view nodes: #(#(10 5) #(20 50) #(2 4) #(60 20)). view layout: (ROScatterplotLayout new upSideDown; scaleFactor: 2; x: #first; y: #second) ].! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 5/22/2013 18:07'! selectionOn: view | statusBar activeSelection | activeSelection := ROSelection new onInclusion: [ :element | ROBlink highlight: element color: Color red ]; onExclusion: [ :element | ROBlink unhighlight: element ]. statusBar := (ROElement on: activeSelection) + (ROLabel text: [ :el | el model asString ]) + ROBox white. view stack add: statusBar. statusBar translateTo: 0 @ 480. view shape label. view interaction on: ROMouseLeftClick do: [ :ann | ann shiftKeyPressed ifFalse: [ activeSelection clear ]. activeSelection add: ann element. ]. view nodes: #(1 2 3 4 5). view gridLayout. "TODO: Clicking on background should clear selection" ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'VanessaPena 1/8/2013 14:55'! semanticZoomOn: view |zoom| zoom := ROZoomIntoElementOnClick new. zoom stack: view stack; view: [:el | |v| v := ROView new. v addAll: (ROElement spritesOn: (el model subclasses )). v elementsDo: [:el2 | el2 +ROLabel ]. ROGridLayout new on: v elements. v translateBy: 0@30. v ]; recursive: true. view raw add: (ROElement sprite model: ROInteraction; + ROLabel; @zoom; yourself).! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 10/18/2012 16:56'! shrikingSizeOn: view | outterNode | outterNode := view node: 'hello' forIt: [ view shape rectangle withText. view interaction on: ROMouseClick do: [ :event | outterNode remove: event element. ROHorizontalLineLayout on: outterNode elements. ROShrikingSize on: outterNode. event element signalUpdate ]. view nodes: (1 to: 20). ]. "Make the outter node shrink when it can" outterNode resizeStrategy: ROShrinkingParent new.! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/7/2012 11:16'! simpleHierarchy " self new simpleHierarchy " | view | view := ROMondrianViewBuilder new. self simpleHierarchyOn: view. view open! ! !ROMondrianExample methodsFor: 'basic' stamp: 'AlexandreBergel 5/7/2012 11:15'! simpleHierarchyOn: view view shape rectangle size: 20. view nodes: (1 to: 20). view shape line. view edgesFrom: [ :i | i \\ 3 ]. view treeLayout. ! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 7/4/2013 17:09'! statusBarOn: view | statusBar | statusBar := ROElement new + ROLabel + ROBox white. view stack add: statusBar. ROConstraint stickAtTheBottomOfTheWindow: statusBar. view interaction on: ROMouseEnter do: [ :event | statusBar model: event element model. ]. view shape rectangle size: 10. view nodes: (Collection withAllSubclasses). view edgesFrom: #superclass. view treeLayout.! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/4/2012 09:27'! step1CreatingNodesOn: view "A mondrian view is composed of nodes and egdes. In this first step, we will have the simplest visualization possible. A list of nodes representing each subclass of the class Collection." view nodes: Collection withAllSubclasses. "Since no shape is defined, each node is represented as a small white square, with a black border. The size of the square is 5 pixels wide. No layout is specified, therefore the horizontal line layout is used per default. All the nodes are lined up horizontally. Wave the mouse over a node, a popup will tell you which node you are pointing to. You can individually drag and drop each node. The whole view may be move around by dragging and dropping where there is no node, in the background."! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/4/2012 10:23'! step2AddingEdgesOn: view "We will now add edges to represent the superclass hierarchy of the collection classes." view nodes: Collection withAllSubclasses. "The message #edgesFrom: tells Roassal to draw edges between each node. The message #superclass is sent to each nodes (i.e., each subclass of Collection). A line is draw for each couple (subclassOfCollection -> subclassOfCollection superclass)." view edgesFrom: #superclass. "We need to provide a layout to structure the visualization. A tree layout is appropriate in Smalltalk since a class has only one superclass." view treeLayout. "The tree layout places a superclass aboves its subclasses. The Easel offers a number of actions. Zoom in, zoom out and find objects. Really handy and you have many nodes and you are looking for a specific node. "! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/12/2012 21:56'! step3DefiningShapeOn: view "Up to now, all the boxes have the same graphical aspect (i.e., a 5 pixels white square). Each node may particularize its shape depending on the object that is rendered." "We will now define a new shape in which the height represents the amount of mehtods the class has, Its width is the amount of variables the class defines." view shape rectangle width: [ :cls | cls instVarNames size ]; height: [ :cls | cls methods size ]. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/13/2012 10:01'! step4ColoringShapeOn: view "Shapes may be colored in many different ways. " "Let's paint with a blue border the classes for which the word Array appear in their name. Classes with Hash in their name will have a green border." "Classes are painted in veryLightGray. Classes with more than 20 methods are in gray. The one with more than 30 methods are in back" view shape rectangle width: [ :cls | cls instVarNames size * 5 ]; height: [ :cls | cls methods size ]; if: [ :cls | '*Array*' match: cls name ] borderColor: Color blue; if: [ :cls | '*Hash*' match: cls name ] borderColor: Color green; fillColor: Color veryLightGray; if: [ :cls | cls methods size > 20 ] fillColor: Color gray; if: [ :cls | cls methods size > 30 ] fillColor: Color black. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/13/2012 10:38'! step5LinearFillColorOn: view "In the previous step, we have related the amount of methods a class may have with the darkness of its color: many methods is associated to black and few methods with light gray. In chromatography, the lightness (or darkness) of a color is called its 'value'. Relating a metric (e.g., the number of methods) with the color value is a common behavior that deserves its own facilities. " "In this example, we relate the number of lines of code a class has with its color value." view shape rectangle width: [ :cls | cls instVarNames size * 5 ]; height: [ :cls | cls methods size ]; linearFillColor: #linesOfCode within: Collection withAllSubclasses. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout. "linearFillColor: aBlock within: aCollection computes for each node a numerical value using aBlock and associates a gray value. The visualization we have obtained is well know in the field of software visualization. It is called 'System Complexity'. More description of this fantastic visualization may be found in the publication 'Polymetric Views -- A Lightweight Visual Approach to Reverse Engineering', TSE 29(9), 2003." ! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 5/13/2012 10:43'! step6NestingNodesOn: view "Until now, the only relation between nodes that we have expressed is linking them with an edge. Another way to relate nodes is to nest them. A node acts as a view in which nodes and edges may be added." "Methods may be added within a class using nodes:forEach:" view nodes: Collection withAllSubclasses forEach: [ :aClass | view nodes: aClass methods. ]. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'AlexandreBergel 7/14/2012 19:00'! step7GridLayoutOn: view "Having a long horizontal list of methods is not that exciting. They can be ordered a little bit by using a grid layout" view nodes: Collection withAllSubclasses forEach: [ :aClass | view nodes: aClass methods. "The amount of space between each nodes may be specified using gapSize:. " view gridLayout gapSize: 2. ]. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'tutorial' stamp: 'DR 1/15/2013 21:11'! step8PaintingMethodsOn: view "We will now paint the methods according to their amount of lines of code " view nodes: Collection withAllSubclasses forEach: [ :aClass | "The color of an element may be conditionally picked. " view shape rectangle if: [ :cm | cm numberOfLinesOfCode > 5 ] fillColor: Color green; if: [ :cm | cm numberOfLinesOfCode > 10 ] fillColor: Color red. view nodes: (aClass methods asSortedCollection: [ :m1 :m2 | m1 numberOfLinesOfCode > m2 numberOfLinesOfCode]). view gridLayout gapSize: 2. ]. view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'VanessaPena 11/21/2012 00:04'! systemComplexity " self new systemComplexity " | view elements edge | view := ROMondrianViewBuilder new. self systemComplexityOn: view. view open. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 1/18/2013 15:22'! systemComplexityFor: classes " self new systemComplexityFor: Morph withAllSubclasses " | view elements edge | view := ROMondrianViewBuilder new. view shape rectangle width: #numberOfVariables; height: #numberOfMethods; linearFillColor: #numberOfLinesOfCode within: classes. view interaction popupText: [ :cls | cls name, String cr, cls methods size printString, ' methods', Character cr asString, cls instVarNames size printString, ' variables', Character cr asString, cls numberOfLinesOfCode printString, ' LOC' ]. view interaction action: #browse. view nodes: classes. view edgesFrom: #superclass. view treeLayout. view open. ^ view! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 7/14/2012 14:15'! systemComplexityOn: view view shape rectangle width: [ :cls | cls numberOfVariables * 5 ]; height: #numberOfMethods; linearFillColor: #numberOfLinesOfCode within: Collection withAllSubclasses. view interaction popupText: [ :cls | cls name, (String with: Character cr), cls methods size printString, ' methods', (String with: Character cr), cls instVarNames size printString, ' variables', (String with: Character cr), cls numberOfLinesOfCode printString, ' LOC' ]. view interaction action: #browse. view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. view treeLayout.! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 3/6/2013 16:10'! temporaryEdges " self new temporaryEdges " | view | view := ROMondrianViewBuilder new. self temporaryEdgesOn: view. view open! ! !ROMondrianExample methodsFor: 'interations' stamp: 'AlexandreBergel 3/6/2013 16:10'! temporaryEdgesOn: view | addedEdges wrongDependencies classes inheritanceLinks | "My classes" classes := #('Object' 'Model' 'Database' 'Car'). "My inheritance links" inheritanceLinks := Array with: 'Object' -> 'Model' with: 'Object' -> 'Database' with: 'Model' -> 'Car'. "My wrong dependencies" wrongDependencies := Array with: 'Object' -> 'Database' with: 'Car' -> 'Database'. "Showing some (fake) dependencies" addedEdges := nil. view interaction on: ROMouseEnter do: [ :event | view shape arrowedLineWithOffset: 0.5; color: Color red. addedEdges := view edgesFromAssociations: wrongDependencies. view raw signalUpdate. ]. view interaction on: ROMouseLeave do: [ :event | addedEdges ifNotNil: [ addedEdges do: #remove. addedEdges := nil. view raw signalUpdate. ]. ]. "My system is made of 4 classes" view shape rectangle withText. view nodes: classes. "Showing UML like diagram" view shape arrowedLineReversed. view edgesFromAssociations: inheritanceLinks. view treeLayout.! ! !ROMondrianExample methodsFor: 'layouts' stamp: 'AlexandreBergel 5/17/2012 19:59'! treeLayoutOn: view view shape rectangle size: 40. view nodes: (1 to: 5). view shape arrowedLine. view edges: ((OrderedCollection new) add: (1->2); add: (1->3); add: (1->5); add: (2->4); add: (4->1); yourself) from: #key to: #value. view treeLayout. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 9/25/2013 09:13'! uml " ROMondrianExample new uml " | view | view := ROMondrianViewBuilder new. self umlOn: view. ROEaselMorphic new populateMenuOn: view. view open ! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 8/9/2013 19:03'! umlAggregateOn: view view shape rectangle withText. view nodes: #( 'container' 'element' ). view shape: (ROLine new add: (RODiamondDecoration new offset: 1 )). view edgesFromAssociations: (Array with: 'container' -> 'element' ). view treeLayout verticalGap: 40. ! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 7/30/2012 00:04'! umlLikeOn: view view shape rectangle withText. view nodes: (ROShape withAllSubclasses). view shape: (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 1 )). view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'software visualization' stamp: 'AlexandreBergel 9/25/2013 09:04'! umlOn: view | classes categoriesToAnalyze | "To visualize your own packages, modify the following line" categoriesToAnalyze := #('Roassal-*' 'RoassalMorphic' 'RoassalExtras'). "classes contains all the classes that will be visualized" classes := Object withAllSubclasses select: [ :cls | cls isMeta not and: [ categoriesToAnalyze anySatisfy: [ :cat | cat match: cls category ] ] ]. view shape rectangle withoutBorder. view nodes: classes forEach: [ :cls | | title ivs methods | view shape label. view interaction forward: ROMouseDragging. title := view node: cls name asString. view shape rectangle borderColor: Color lightGray. view interaction forward: ROMouseDragging. ivs := view node: 'IVs' forIt: [ view shape label text: #asString. view interaction noPopup. view interaction forward: ROMouseDragging. view nodes: cls instVarNames asSortedCollection. view verticalLineLayout gapSize: -3 ]. view shape rectangle borderColor: Color lightGray. view interaction forward: ROMouseDragging. methods := view node: 'methods' forIt: [ view shape label text: #asString. view interaction popupText: [ :k | (cls >> k) getSource ]. view interaction forward: ROMouseDragging. view nodes: cls selectors asSortedCollection. view shape label color: Color lightGray; text: #asString. view interaction popupText: [ :k | (cls class >> k) getSource ]. view interaction forward: ROMouseDragging. view nodes: cls class selectors asSortedCollection. view verticalLineLayout gapSize: -3 ]. ROResize stretchHorizontally: (Array with: ivs with: methods with: title). view verticalLineLayout gapSize: -2. ]. view shape: (ROOrthoVerticalLineShape new add: (ROReversedVerticalArrow new offset: 1 )). view edgesFrom: #superclass. view treeLayout.! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 7/30/2012 00:05'! umlReallyUpSideDownLikeOn: view view shape rectangle withText. view nodes: (ROShape withAllSubclasses). view shape: (ROOrthoVerticalLineShape new add: (ROVerticalArrow new offset: 1 )). view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'arrowed edges' stamp: 'AlexandreBergel 7/30/2012 00:05'! umlUpSideDownLikeOn: view view shape rectangle withText. view nodes: (ROShape withAllSubclasses). view shape: (ROOrthoVerticalLineShape new add: (ROVerticalArrow new offset: 0 )). view edgesFrom: #superclass. view treeLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'DennisSchenk 9/19/2012 12:10'! viewCollectionSubclassesTreeMapsOn: view view interaction item: 'Explore Class' action: #explore; item: 'Browse Class' action: #browse; popupText: [ :node | node ]. "Set size of all treemaps to 100 by 100." view shape size: 100. view nodes: Collection subclasses forEach: [ :each | | subClasses | subClasses := each allSubclasses. subClasses notEmpty ifTrue: [ view nodes: subClasses. view edgesFrom: #superclass. view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model numberOfLinesOfCode ]). ]. ]. view gridLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'DennisSchenk 9/19/2012 12:34'! viewCollectionSubclassesTreesOn: view view interaction item: 'Explore Class' action: #explore; item: 'Browse Class' action: #browse; popupText: [ :node | node ]. view shape size: 100. view nodes: Collection subclasses forEach: [ :each | | subClasses | subClasses := each allSubclasses. subClasses notEmpty ifTrue: [ view nodes: subClasses. view edgesFrom: #superclass. view treeLayout. ]. ]. view gridLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'AlexandreBergel 8/21/2012 10:34'! viewCollectionTreeMapOn: view "Adding basic interaction capabilities to nodes: - Add a menu item which lets one explore the model of the node. - Another menu item which lets one browse the class represented by the node. - Show the node name on hover." view interaction item: 'Explore Class' action: #explore; item: 'Browse Class' action: #browse; popupText: [ :node | node ]. "The treemap should have a dimension of 400 by 400." view shape width: 400; height: 400. "Our nodes are all subclasses of Collection." view nodes: Collection withAllSubclasses. view edgesFrom: #superclass. "The weights we use to draw the treemap are the classes lines of code (LOC)." view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model numberOfLinesOfCode ]). ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'DennisSchenk 9/19/2012 11:16'! viewMultipleTreeMapsOn: view "Make every treemap have a size of 100x100." view shape rectangle size: 100. view nodes: (1 to: 4) forEach: [ :each | | innerNodes innerEdges | innerNodes := view nodes: (each*10 to: each*40 by: each*5) asOrderedCollection. innerEdges := view edgesFromAssociations: (Array with: (each*10) -> (each*10+each*5*1) with: (each*10) -> (each*10+each*5*2) with: (each*10) -> (each*10+each*5*3) with: (each*10) -> (each*10+each*5*4) with: (each*10) -> (each*10+each*5*5) with: (each*10) -> (each*10+each*5*6) ). view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ]. view edgesFromAssociations: (Array with: 1 -> 2 with: 1 -> 3 with: 1 -> 4). view treeLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'DennisSchenk 9/19/2012 11:15'! viewMultipleTreesOn: view "Displays the same tree as displayed in viewMultipleTreeMapsOn but as normal tree." view nodes: (1 to: 4) forEach: [ :each | | innerNodes innerEdges | innerNodes := view nodes: (each*10 to: each*40 by: each*5) asOrderedCollection. innerEdges := view edgesFromAssociations: (Array with: (each*10) -> (each*10+each*5*1) with: (each*10) -> (each*10+each*5*2) with: (each*10) -> (each*10+each*5*3) with: (each*10) -> (each*10+each*5*4) with: (each*10) -> (each*10+each*5*5) with: (each*10) -> (each*10+each*5*6) ). view treeLayout. ]. view edgesFromAssociations: (Array with: 1 -> 2 with: 1 -> 3 with: 1 -> 4). view treeLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'AlexandreBergel 8/21/2012 10:35'! viewSimpleTreeMapOn: view "Adding basic interaction capabilities: - Add a menu item which lets one explore the model of a node - Show the node name on hover" view interaction item: 'Explore Element' action: #explore; popupText: [ :node | node ]. "The treemap should have a dimension of 400 by 400." view shape width: 400; height: 400. "The nodes we draw are simply the numbers from 0 to 76." view nodes: (0 to: 76). view edgesFrom: [ :each | each // 10 ]. "The weights we use to draw the treemap are the models itself: the numbers." view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'DennisSchenk 9/19/2012 11:15'! viewSimpleTreeOn: view "Displays the same tree as displayed in viewSimpleTreeMap but as normal tree." view shape rectangle. view nodes: (0 to: 76). view edgesFrom: [ :each | each // 10 ]. view treeLayout. ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'AlexandreBergel 8/21/2012 10:35'! viewTreeMapOn: view "Adding basic interaction capabilities: - Add a menu item which lets one explore the model of a node - Show the node name on hover" view interaction item: 'Explore Element' action: #explore; popupText: [ :node | node ]. "The treemap should have a dimension of 500 by 500." view shape width: 500; height: 500. "The nodes we draw are simply the numbers from 0 to 999." view nodes: (0 to: 999). view edgesFrom: [ :each | each // 10 ]. "The weights we use to draw the treemap are the models itself: the numbers." view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ! ! !ROMondrianExample methodsFor: 'layout tree map' stamp: 'AlexandreBergel 9/23/2012 12:48'! viewVerySimpleTreeMapOn: view "Draw a Treemap that ihas a size of 100x100." view shape size: 100. "The nodes we draw are simply the numbers from 0 to 6." view nodes: (OrderedCollection new add: 1; add: 2; add: 3; add: 4; add: 5; add: 6; yourself). view edgesFromAssociations: (OrderedCollection new add: 1 -> 2; add: 1 -> 3; add: 3 -> 4; add: 3 -> 5; add: 4 -> 6; yourself). "The weights we use to draw the treemap are the models itself: the numbers." view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model ]). ! ! !ROMondrianExample methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 18:12'! zOrderingOn: view "zOrdering tells about the order the objects have to be displayed. This example gives a zIndex of 5 to edges, and 10 to nodes. Edges will be displayed first as a consequence." view raw zOrdering: (ROZOrdering new setZIndex: 5 if: #isEdge; setZIndex: 10 if: #isNotEdge). view shape label text: #yourself. view nodes: (1 to: 20). view edges: (1 to: 20) from: [:x | x // 2] to: 1. view edges: (1 to: 20) from: [:x | x // 3] to: 2. view edges: (1 to: 20) from: [:x | x // 5] to: #yourself. view edges: (1 to: 20) from: [:x | x // 7] to: #yourself. view dominanceTreeLayout.! ! !ROMondrianExample methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 18:12'! zOrderingOnDepthOn: view "zOrdering tells about the order the objects have to be displayed. This example gives a zIndex of 5 to edges, and 10 to nodes. Edges will be displayed first as a consequence." view raw zOrdering: (ROZOrdering new setZIndex: [ :element | element depth ] if: true). view shape label text: #yourself. view nodes: (1 to: 20). view edges: (1 to: 20) from: [:x | x // 2] to: 1. view edges: (1 to: 20) from: [:x | x // 3] to: 2. view edges: (1 to: 20) from: [:x | x // 5] to: #yourself. view edges: (1 to: 20) from: [:x | x // 7] to: #yourself. view dominanceTreeLayout.! ! !ROObject commentStamp: '' prior: 34304403! A ROObject is the root of the roassal class hierarchy. The idea to have ROObject is to have an empty initialize and a new on the class side that calls the initialize. This class is particuarly useful in VisualWorks since Object does not has an initialize! !ROAbstractAnimationMergeStrategy commentStamp: '' prior: 34304732! A ROAbstractAnimationMergeStrategy is a hierarchy of merging strategy for animation. Each animation has a merging strategy. ! !ROAbstractAnimationMergeStrategy class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 5/2/2013 18:59'! instance ^ instance isNil ifTrue: [ instance := self new ] ifFalse: [ instance ]! ! !ROAbstractAnimationMergeStrategy methodsFor: 'hooks' stamp: 'AlexandreBergel 5/7/2013 14:44'! added: animation in: aView "The animation for which I am associated with has been added in aView" self subclassResponsibility! ! !ROAbstractAnimationMergeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 5/2/2013 18:58'! isAppend ^ false! ! !ROAbstractAnimationMergeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 5/2/2013 19:02'! isExclusive ^ false! ! !ROAnimationAppend commentStamp: '' prior: 34304916! A ROAbstractAnimationAppend means that an animation is simply added to the queue kept in the view. This is the default strategy! !ROAnimationAppend methodsFor: 'hooks' stamp: 'AlexandreBergel 5/2/2013 19:16'! added: animation in: aView "The animation for which I am associated with has been added in aView" "Good, so we do nothing"! ! !ROAnimationAppend methodsFor: 'testing' stamp: 'AlexandreBergel 5/2/2013 18:57'! isAppend ^ true! ! !ROAnimationExclusive commentStamp: '' prior: 34305106! A ROAnimationExclusive replaces all other animation for the element! !ROAnimationExclusive methodsFor: 'hooks' stamp: 'AlexandreBergel 5/3/2013 08:37'! added: animation in: aView "The animation for which I am associated with has been added in aView" "We need to remove all other animation" aView removeAnimationSuchThat: [ :ani | ani class == animation class ]! ! !ROAnimationExclusive methodsFor: 'testing' stamp: 'AlexandreBergel 5/2/2013 19:02'! isExclusive ^ true! ! !ROAbstractCanvas commentStamp: 'AlexandreBergel 8/19/2012 13:01' prior: 34305251! A ROAbstractCanvas is the abstract class of the canvases. In the core of Roassal, it has only one subclass, RONullCanvas. The platform package should subclass ROAbstractCanvas. Instance Variables camera: canvas: extent: camera - xxxxx canvas - xxxxx extent - xxxxx ! !ROAbstractCanvas class methodsFor: 'public' stamp: 'AlexandreBergel 4/19/2012 12:18'! canvas: canvas camera: camera ^ self new canvas: canvas; camera: camera; yourself! ! !ROAbstractCanvas class methodsFor: 'configuration' stamp: 'AlexandreBergel 4/19/2012 12:17'! defaultExtent ^ 40 @ 30! ! !ROAbstractCanvas class methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:19'! onCamera: camera "Return a new canvas with a created canvas" "Implementation example: | form canvas | form := Form extent: camera realExtent depth: Display depth. canvas := FormCanvas on: form. ^ self canvas: canvas camera: camera " self subclassResponsibility! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 4/19/2012 12:00'! camera ^ camera! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 4/19/2012 12:00'! camera: aROCamera camera := aROCamera! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 7/27/2012 17:44'! canvas ^ nativeCanvas! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 7/27/2012 17:44'! canvas: aNativeCanvas nativeCanvas := aNativeCanvas! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 8/29/2013 08:09'! drawPolygon: listOfPoints color: color borderWidth: borderWidthValue borderColor: borderColorValue "Render a polygon at a given position. nativeCanvas drawPolygon: (listOfPoints collect: [ :p | self virtualToRealPoint: p ]) color: color borderWidth: borderWidthValue borderColor: borderColorValue. " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:06'! drawString: aByteString at: aPoint "Render a string at a given position. No specification about the font is given. Use the default then" "Implementation example: canvas drawString: aByteString at: (self virtualToRealPoint: aPoint) font: nil color: Color black " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:06'! drawString: aByteString at: aPoint color: color "Render a colored string at a given position. No specification about the font is given. Use the default then" "Implementation example: canvas drawString: aByteString at: (self virtualToRealPoint: aPoint) font: nil color: color " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:06'! drawString: aByteString at: p font: f color: color "Render a colored string at a given position using a particular font." "Implementation example: canvas drawString: aByteString at: (self virtualToRealPoint: p) font: f color: color " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 4/19/2012 12:00'! extent: aPoint extent := aPoint! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:06'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 "Render an oval" "Implementation example canvas fillOval: (self virtualToRealRectangle: aRectangle) color: aColor borderWidth: aSmallInteger borderColor: aColor4 " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:07'! fillRectangle: aRectangle color: fillColor "Render a rectangle" "Implementation example canvas fillRectangle: (self virtualToRealRectangle: aRectangle) color: fillColor " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:07'! form "Return a bitmap" "Implementation example ^ canvas form " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:05'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor "Render a framed rectangle. Implementation example: canvas frameAndFillRectangle: (self virtualToRealRectangle: aRectangle) fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor. " self subclassResponsibility.! ! !ROAbstractCanvas methodsFor: 'initialize' stamp: 'AlexandreBergel 7/27/2012 15:47'! initialize super initialize. extent := self class defaultExtent. "Maybe a global camera would be useful. The camera object is never used normally. Since the camera of the view has to be set prior any drawing" camera := ROCamera new. offset := 0 @ 0! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:07'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor "Draw a line between two points" "Implementation example canvas line: (self virtualToRealPoint: aPoint) to: (self virtualToRealPoint: aPoint2) width: aSmallInteger color: aColor. " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 7/27/2012 15:52'! offset ^ offset! ! !ROAbstractCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 7/27/2012 15:22'! offset: anOffsetAsPoint offset := anOffsetAsPoint ! ! !ROAbstractCanvas methodsFor: 'convenient' stamp: 'AlexandreBergel 4/19/2012 12:07'! paintBackground: color self frameAndFillRectangle: (camera realToVirtualRectangle: (0@0 extent: extent)) fillColor: color borderWidth: 0 borderColor: Color white.! ! !ROAbstractCanvas methodsFor: 'hooks' stamp: 'AlexandreBergel 4/19/2012 12:08'! paintImage: aForm at: aPoint "Render a bitmap on screen" "Implementation example canvas paintImage: aForm at: (self virtualToRealPoint: aPoint) " self subclassResponsibility ! ! !ROAbstractCanvas methodsFor: 'initialize' stamp: 'AlexandreBergel 4/19/2012 12:02'! realToVirtualPoint: aPoint "Return a real point from a one expressed in the virtual coordinates" ^ camera realToVirtualPoint: aPoint ! ! !ROAbstractCanvas methodsFor: 'initialize' stamp: 'AlexandreBergel 4/19/2012 12:02'! realToVirtualRectangle: aRectangle "Return a rectangle with virtual coordinates from one expressed in the real coordinates" ^ camera realToVirtualRectangle: aRectangle! ! !ROAbstractCanvas methodsFor: 'util' stamp: 'AlexandreBergel 7/27/2012 15:51'! virtualToRealPoint: aPoint "Return a real point from a one expressed in the virtual coordinates" ^ (camera virtualToRealPoint: aPoint) + offset ! ! !ROAbstractCanvas methodsFor: 'util' stamp: 'VanessaPena 11/13/2012 19:39'! virtualToRealRectangle: aRectangle "Return a rectangle with real coordinates from one expressed in the virtual coordinates" ^ (camera virtualToRealRectangle: aRectangle) translateBy: offset! ! !ROCountingNullCanvas class methodsFor: 'instance creation'! on: aForm "we do nothing" ^ self new! ! !ROCountingNullCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 4/11/2013 14:26'! camera ^ ROCamera new! ! !ROCountingNullCanvas methodsFor: 'accessing'! clipRect ^1@1 extent: 100000@100000! ! !ROCountingNullCanvas methodsFor: 'drawing-rectangles'! frameAndFillRectangle: bounds fillColor: c borderWidth: width borderColor: cc numberOfRectangles := numberOfRectangles + 1. ! ! !ROCountingNullCanvas methodsFor: 'initialization'! initialize super initialize . numberOfRectangles := 0. numberOfLines := 0. numberOfImages := 0! ! !ROCountingNullCanvas methodsFor: 'drawing'! line: fromPoint to: toPoint width: width color: color numberOfLines := numberOfLines + 1.! ! !ROCountingNullCanvas methodsFor: 'accessing'! numberOfImages ^ numberOfImages! ! !ROCountingNullCanvas methodsFor: 'accessing'! numberOfLines ^ numberOfLines! ! !ROCountingNullCanvas methodsFor: 'accessing'! numberOfRectangles ^ numberOfRectangles! ! !ROCountingNullCanvas methodsFor: 'drawing-images'! paintImage: cacheForm at: position numberOfImages := numberOfImages + 1. ! ! !ROCountingNullCanvas methodsFor: 'hook'! warpImage: aForm transform: aTransform at: extraOffset sourceRect: sourceRect cellSize: cellSize "We cancel this method. It is defined as abstract in the Canvas class"! ! !RONullCanvas commentStamp: '' prior: 34305612! A RONullCanvas is a null canvas. Useful when testing.! !RONullCanvas class methodsFor: 'public' stamp: 'AlexandreBergel 7/29/2012 12:45'! onCamera: camera self error: 'Should not be called'! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! drawString: aByteString at: aPoint ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! drawString: aByteString at: aPoint color: color ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! drawString: aByteString at: p font: f color: color ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! fillRectangle: aRectangle color: fillColor ! ! !RONullCanvas methodsFor: 'util' stamp: 'AlexandreBergel 7/27/2012 09:33'! form ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor ! ! !RONullCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 09:33'! paintImage: aForm at: aPoint ! ! !ROPharoCanvas class methodsFor: 'public' stamp: 'AlexandreBergel 7/27/2012 09:35'! onCamera: camera " | form canvas | form := Form extent: camera realExtent depth: Display depth. canvas := FormCanvas on: form. " ^ self canvas: RONullCanvas new camera: camera! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 8/29/2013 08:06'! drawPolygon: listOfPoints color: color borderWidth: borderWidthValue borderColor: borderColorValue nativeCanvas drawPolygon: (listOfPoints collect: [ :p | self virtualToRealPoint: p ]) color: color borderWidth: borderWidthValue borderColor: borderColorValue.! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'VanessaPena 12/22/2012 20:18'! drawString: aByteString at: aPoint nativeCanvas drawString: aByteString at: (self virtualToRealPoint: aPoint) font: nil color: Color black! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'VanessaPena 12/23/2012 20:08'! drawString: aByteString at: aPoint color: color " nativeCanvas drawString: aByteString at: (self virtualToRealPoint: aPoint) font: nil color: color" nativeCanvas drawString: aByteString at: (self virtualToRealPoint: aPoint) font: nil color: color! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 17:44'! drawString: aByteString at: p font: f color: color nativeCanvas drawString: aByteString at: (self virtualToRealPoint: p) font: f color: color! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'VanessaPena 11/13/2012 19:39'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 nativeCanvas fillOval: (self virtualToRealRectangle: aRectangle) color: aColor borderWidth: aSmallInteger borderColor: aColor4! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 17:45'! fillRectangle: aRectangle color: fillColor nativeCanvas fillRectangle: (self virtualToRealRectangle: aRectangle) color: fillColor! ! !ROPharoCanvas methodsFor: 'util' stamp: 'AlexandreBergel 7/27/2012 17:45'! form ^ nativeCanvas form! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 17:45'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor nativeCanvas frameAndFillRectangle: (self virtualToRealRectangle: aRectangle) fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor. ! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 17:45'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor nativeCanvas line: (self virtualToRealPoint: aPoint) to: (self virtualToRealPoint: aPoint2) width: aSmallInteger color: aColor. ! ! !ROPharoCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 7/27/2012 17:45'! paintImage: aForm at: aPoint nativeCanvas paintImage: aForm at: (self virtualToRealPoint: aPoint) ! ! !ROTracingCanvas commentStamp: '' prior: 34305723! A ROTracingCanvas records all the drawing operations. It is essentially used by the test Instance Variables trace: trace - list of drawing operations performed on the canvas! !ROTracingCanvas class methodsFor: 'public' stamp: 'AlexandreBergel 12/10/2012 19:18'! onCamera: camera self error: 'Should not be called'! ! !ROTracingCanvas methodsFor: 'util' stamp: 'AlexandreBergel 12/14/2012 13:57'! colToStr: aColor "This method is useful for VW when Color white printString = 'ColorValue white'" | str | str := aColor printString. ^ ((RONativeExampleUtility current substringsFor: str) size = 2) ifTrue: [ 'Color ', (RONativeExampleUtility current substringsFor: str) second ] ifFalse: [ str ]! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 8/28/2013 14:00'! drawPolygon: points color: c borderWidth: w borderColor: bc. trace add: (Array with: #drawPolygon with: points printString with: w with: bc)! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:44'! drawString: aByteString at: aPoint trace add: (Array with: #drawString with: aByteString with: (self pointToStr: aPoint))! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:44'! drawString: aByteString at: aPoint color: color trace add: (Array with: #drawStringColor with: aByteString with: (self pointToStr: aPoint) with: (self colToStr: color))! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 6/12/2013 12:50'! drawString: aByteString at: p font: f color: color | array | array := Array new: 4. array at: 1 put: #drawStringColor; at: 2 put: aByteString; at: 3 put: (self pointToStr: p); at: 4 put: (self colToStr: color). trace add: array.! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:49'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 trace add: (Array with: #fillOval: with: (self recToStr: aRectangle) with: aSmallInteger with: (self colToStr: aColor))! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:45'! fillRectangle: aRectangle color: fillColor trace add: (Array with: #fillRectangle with: (self recToStr: aRectangle) with: (self colToStr: fillColor))! ! !ROTracingCanvas methodsFor: 'util' stamp: 'AlexandreBergel 4/22/2013 09:15'! fontToStr: f ^ f name, ' ', f pointSize printString ! ! !ROTracingCanvas methodsFor: 'util' stamp: 'AlexandreBergel 12/10/2012 19:18'! form ! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:45'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor trace add: ((Array with: #frameAndFillRectangle: with: (self recToStr: aRectangle) with: (self colToStr: fillColor)), (Array with: aSmallInteger with: (self colToStr: aColor)))! ! !ROTracingCanvas methodsFor: 'initialize' stamp: 'AlexandreBergel 12/10/2012 19:18'! initialize super initialize. trace := OrderedCollection new! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:46'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor trace add: ((Array with: #line with: (self pointToStr: aPoint) with: (self pointToStr: aPoint2)), (Array with: aSmallInteger with: (self colToStr: aColor)))! ! !ROTracingCanvas methodsFor: 'rendering' stamp: 'AlexandreBergel 12/14/2012 13:46'! paintImage: aForm at: aPoint trace add: (Array with: #paintImage with: (self pointToStr: aPoint))! ! !ROTracingCanvas methodsFor: 'util' stamp: 'AlexandreBergel 12/14/2012 13:33'! pointToStr: aPoint ^ '(', aPoint x printString, '@', aPoint y printString, ')'! ! !ROTracingCanvas methodsFor: 'util' stamp: 'AlexandreBergel 12/14/2012 13:34'! recToStr: rectangle "Return a textual description of a rectangle" ^ (self pointToStr: rectangle origin), ' corner: ', (self pointToStr: rectangle corner)! ! !ROTracingCanvas methodsFor: 'accessing' stamp: 'AlexandreBergel 12/11/2012 11:59'! trace ^ trace copy asArray! ! !ROAbstractResizeStrategy commentStamp: 'AlexandreBergel 3/2/2012 19:40' prior: 34305994! This hierarchy defines how a parent should behave when a child is resized.! !ROAbstractResizeStrategy class methodsFor: 'public'! instance instance ifNil: [ instance := self new ]. ^ instance! ! !ROAbstractResizeStrategy class methodsFor: 'public' stamp: 'AlexandreBergel 4/22/2013 19:28'! reset instance := nil! ! !ROAbstractResizeStrategy class methodsFor: 'public' stamp: 'AlexandreBergel 5/6/2013 17:59'! resetAll self allSubclasses do: #reset! ! !ROAbstractResizeStrategy methodsFor: 'configuration' stamp: 'JurajKubelka 4/24/2013 10:30'! defaultPadding ^ 5 @ 5! ! !ROAbstractResizeStrategy methodsFor: 'initialize-release' stamp: 'JurajKubelka 4/24/2013 10:30'! initialize super initialize. padding := self defaultPadding! ! !ROAbstractResizeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:24'! isExtensible ^ false! ! !ROAbstractResizeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:24'! isFixed ^ false! ! !ROAbstractResizeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 4/29/2013 16:37'! isPermissive ^ false! ! !ROAbstractResizeStrategy methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:24'! isShrinking ^ false! ! !ROAbstractResizeStrategy methodsFor: 'action'! on: childElement self subclassResponsibility ! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:19'! padding ^ padding! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:19'! padding: aPoint self assert: [ aPoint class == Point ]. padding := aPoint! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingBottom ^ self paddingTop! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingGap: aSmallInteger self padding: aSmallInteger @ aSmallInteger! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingLeft ^ self padding x! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingRight ^ self paddingLeft! ! !ROAbstractResizeStrategy methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingTop ^ self padding y! ! !ROAbstractResizeStrategy methodsFor: 'action' stamp: 'AlexandreBergel 4/29/2013 15:04'! translate: innerElement by: aPoint innerElement translateWithoutUpdatingContainedElementsBy: aPoint.! ! !ROExtensibleParent commentStamp: 'AlexandreBergel 3/2/2012 19:41' prior: 34306147! The parent get expended! !ROExtensibleParent methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:23'! isExtensible ^ true! ! !ROExtensibleParent methodsFor: 'action' stamp: 'AlexandreBergel 5/22/2012 00:33'! on: element ROAdjustSizeOfNesting on: element! ! !ROFixedSizedParent commentStamp: '' prior: 34306231! The size of the parent is fixed. Inner nodes cannot escape the outter element when they are dragged away.! !ROFixedSizedParent methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:21'! isFixed ^ true! ! !ROFixedSizedParent methodsFor: 'action' stamp: 'AlexandreBergel 5/22/2012 00:33'! on: element "We do nothing"! ! !ROFixedSizedParent methodsFor: 'action' stamp: 'AlexandreBergel 4/29/2013 16:41'! translate: innerElement by: deltaPoint | adjustedDelta newPos parent parentExtent innerElementExtent initialPositionInner | adjustedDelta := deltaPoint. initialPositionInner := innerElement position. newPos := initialPositionInner + deltaPoint. (newPos x < padding x) ifTrue: [ adjustedDelta := (adjustedDelta x - newPos x + padding x) @ adjustedDelta y ]. (newPos y < padding y) ifTrue: [ adjustedDelta := adjustedDelta x @ (adjustedDelta y - newPos y + padding y) ]. parent := innerElement parent. parentExtent := parent extent. innerElementExtent := innerElement extent. (newPos x > (parentExtent x - innerElementExtent x - padding x) ) ifTrue: [ adjustedDelta := (parentExtent x - innerElementExtent x - padding x - initialPositionInner x) @ adjustedDelta y ]. (newPos y > (parentExtent y - innerElementExtent y - padding y)) ifTrue: [ adjustedDelta := adjustedDelta x @ (parentExtent y - innerElementExtent y - padding y - initialPositionInner y) ]. innerElement translateWithoutUpdatingContainedElementsBy: adjustedDelta! ! !ROPermissiveParent commentStamp: '' prior: 34306397! A ROPermissiveParent is a fixed size of the parent, but does not constraint inner nodes to escape the outter node. This strategy is useful when we temporarily need to add many inner nodes without having to go through all the constraints (e.g., with the Mondrian builder or in the tree map layout)! !ROPermissiveParent methodsFor: 'testing' stamp: 'AlexandreBergel 4/29/2013 16:37'! isPermissive ^ true! ! !ROPermissiveParent methodsFor: 'action' stamp: 'AlexandreBergel 4/29/2013 16:40'! on: element "We do nothing"! ! !ROShrinkingParent commentStamp: '' prior: 34306753! A ROShrinkingParent is the minimum it can have according to the children it has! !ROShrinkingParent methodsFor: 'testing' stamp: 'AlexandreBergel 4/22/2013 19:24'! isShrinking ^ true ! ! !ROShrinkingParent methodsFor: 'action' stamp: 'AlexandreBergel 9/16/2012 12:48'! on: element ROShrikingSize on: element! ! !ROAttachPoint class methodsFor: 'public - creation' stamp: 'AlexandreBergel 1/23/2013 16:53'! instance "Useful to avoid create unnecessary instances" instance ifNil: [ instance := self new ]. ^ instance! ! !ROAttachPoint class methodsFor: 'public - creation' stamp: 'AlexandreBergel 10/15/2012 13:06'! resetInstance " self withAllSubclassesDo: #resetInstance " instance := nil.! ! !ROAttachPoint methodsFor: 'public - hooks'! endingPointOf: anEdge self subclassResponsibility! ! !ROAttachPoint methodsFor: 'public - hooks'! startingPointOf: anEdge self subclassResponsibility! ! !ROCenteredAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 05:20'! endingPointOf: anEdge ^ anEdge to absolutePosition + (anEdge to extent / 2) asIntegerPoint! ! !ROCenteredAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 05:17'! startingPointOf: anEdge ^ (anEdge from absolutePosition + (anEdge from extent / 2)) asIntegerPoint! ! !ROHorizontalAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 05:20'! endingPointOf: anEdge ^ anEdge to absolutePosition + (0 @ (anEdge to bounds height / 2) asInteger)! ! !ROHorizontalAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 05:18'! startingPointOf: anEdge ^ anEdge from absolutePosition + (anEdge from bounds width @ (anEdge from bounds height / 2) asInteger) ! ! !ROShorterDistanceAttachPoint methodsFor: 'util' stamp: 'AlexandreBergel 12/11/2012 05:21'! attachPointFor: anEdge on: anElement with: elementsPossibleAttachPoints "Returns the attach point having the shortest route for given edge on given element." | p dp t | p := anElement absolutePosition + (anElement width @ anElement height). "We get the list of dot products" dp := elementsPossibleAttachPoints collect: [ :pp | t := p - pp. Array with: (t dotProduct: t) with: pp ]. "We look for the shortest path and return the point" ^ (dp inject: dp first into: [ :shorter :el | (shorter first < el first) ifTrue: [ shorter ] ifFalse: [ el ]]) second! ! !ROShorterDistanceAttachPoint methodsFor: 'util' stamp: 'AlexandreBergel 12/11/2012 05:21'! attachPointsFor: anEdge on: anElement "Return the four possible attach points for each of the four sides for given edge on given element." ^ Array "upper side" with: (anElement absolutePosition) + (((anElement bounds width / 2) + offset) asInteger @ 0) "right side" with: (anElement absolutePosition) + (anElement bounds width @ ((anElement bounds height / 2) + offset) asInteger) "lower side" with: (anElement absolutePosition) + (((anElement bounds width / 2) + offset) asInteger @ (anElement bounds height)) "left side" with: (anElement absolutePosition) + (0 @ ((anElement bounds height / 2) + offset) asInteger) ! ! !ROShorterDistanceAttachPoint methodsFor: 'util' stamp: 'DennisSchenk 10/9/2012 12:24'! destinationAttachPointsFor: anEdge "Return the four possible attach points for each of the four sides for this edges destination node." ^ self attachPointsFor: anEdge on: (anEdge to). ! ! !ROShorterDistanceAttachPoint methodsFor: 'public - hooks' stamp: 'DennisSchenk 10/9/2012 12:26'! endingPointOf: anEdge ^ self attachPointFor: anEdge on: (anEdge from) with: (self destinationAttachPointsFor: anEdge).! ! !ROShorterDistanceAttachPoint methodsFor: 'initialize-release' stamp: 'AlexandreBergel 10/11/2012 13:13'! initialize super initialize. offset := 0.! ! !ROShorterDistanceAttachPoint methodsFor: 'accessing' stamp: 'DennisSchenk 10/9/2012 09:39'! offset ^ offset.! ! !ROShorterDistanceAttachPoint methodsFor: 'accessing' stamp: 'DennisSchenk 10/9/2012 09:39'! offset: aNumber offset := aNumber.! ! !ROShorterDistanceAttachPoint methodsFor: 'util' stamp: 'DennisSchenk 10/9/2012 12:24'! startingAttachPointsFor: anEdge "Return the four possible attach points for each of the four sides for this edges starting node." ^ self attachPointsFor: anEdge on: (anEdge from).! ! !ROShorterDistanceAttachPoint methodsFor: 'public - hooks' stamp: 'DennisSchenk 10/9/2012 12:26'! startingPointOf: anEdge ^ self attachPointFor: anEdge on: (anEdge to) with: (self startingAttachPointsFor: anEdge).! ! !ROVerticalAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 12:13'! endingPointOf: anEdge ^ (anEdge to absolutePosition) + ((anEdge to bounds width / 2) asInteger @ 0) ! ! !ROVerticalAttachPoint methodsFor: 'public - hooks' stamp: 'AlexandreBergel 12/11/2012 12:13'! startingPointOf: anEdge ^ (anEdge from absolutePosition) + ((anEdge from bounds width / 2) asInteger @ (anEdge from bounds height )) ! ! !ROBasicZOrdering methodsFor: 'accessing-computing' stamp: 'DennisSchenk 3/20/2013 09:22'! setZindexOf: aGraphicalComponent aGraphicalComponent zIndex: (self zIndexOf: aGraphicalComponent)! ! !ROBasicZOrdering methodsFor: 'accessing-computing' stamp: 'DennisSchenk 2/26/2013 16:54'! zIndexOf: aComponent ^ aComponent zIndex.! ! !ROZOrdering methodsFor: 'accessing-computing' stamp: 'AlexandreBergel 12/3/2012 21:37'! defaultZIndex ^ 0! ! !ROZOrdering methodsFor: 'initialize-release' stamp: 'AlexandreBergel 12/3/2012 21:33'! initialize super initialize. mapping := OrderedCollection new! ! !ROZOrdering methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 21:31'! numberOfEntries ^ mapping size! ! !ROZOrdering methodsFor: 'action' stamp: 'AlexandreBergel 1/25/2013 08:31'! setZIndex: integerOrValue "integerOrValue is evaluated against the graphical element of Roassal. aBlockOrAValue has to return a boolean. The block takes one argument, which is the element." self setZIndex: integerOrValue if: true! ! !ROZOrdering methodsFor: 'action' stamp: 'AlexandreBergel 12/13/2012 18:10'! setZIndex: integerOrValue if: aBlockOrAValue "integerOrValue is evaluated against the graphical element of Roassal. aBlockOrAValue has to return a boolean. The block takes one argument, which is the element." mapping add: (integerOrValue -> aBlockOrAValue)! ! !ROZOrdering methodsFor: 'action' stamp: 'AlexandreBergel 12/3/2012 21:52'! setZindexOf: aGraphicalComponent aGraphicalComponent zIndex: (self zIndexOf: aGraphicalComponent)! ! !ROZOrdering methodsFor: 'accessing-computing' stamp: 'AlexandreBergel 7/19/2013 19:35'! zIndexOf: aComponent mapping do: [ :assoc | (assoc value roValue: aComponent) ifTrue: [ ^ assoc key roValue: aComponent ] ]. ^ aComponent zIndex " ^ self defaultZIndex roValue: aComponent"! ! !ROCamera commentStamp: 'AlexandreBergel 11/14/2012 13:41' prior: 34306903! ROCamera represents the notion of camera. A camera is the point of view from which a view object is actually viewed. The direction of the camera is always perpendicular to the view. A camera has an altitude. Varying the altitude simulate the zooming facility of Roassal. A view is always associated to a camera. Instance Variables: position Position of the camera angle Angle of aperture realExtent The far extent. extent What we are seeing windowSize The size of the window in which I am displayed! !ROCamera class methodsFor: 'defaults'! defaultAngle ^ 95! ! !ROCamera class methodsFor: 'defaults'! defaultExtent "Maybe this has to be replaced by defaultAngle and default Height" ^ 500 @ 500! ! !ROCamera class methodsFor: 'defaults'! defaultHeight ^ 200! ! !ROCamera class methodsFor: 'defaults'! defaultPosition ^ 0 @ 0! ! !ROCamera class methodsFor: 'public'! realExtent: aPoint ^ self new realExtent: aPoint! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 11:56'! altitude ^ (self extent x / 2) / (self angleInRadian / 2 ) tan ! ! !ROCamera methodsFor: 'accessing' stamp: 'DR 3/25/2013 22:01'! altitude: h "Adjust the extent variable to reflect what we are seeing" | nx ny oldExtent | nx := 2 * h * (self angleInRadian / 2) tan. ny := self extent x * nx / self extent y. oldExtent := extent. extent := nx asInteger @ ny asInteger. self translateBy: ((extent - oldExtent ) / 2) asIntegerPoint! ! !ROCamera methodsFor: 'accessing'! angle ^ angle! ! !ROCamera methodsFor: 'accessing'! angleInRadian ^ angle asFloat / 180 * 3.1415! ! !ROCamera methodsFor: 'accessing'! bounds "bounds " ^ position extent: extent " | ra v p | ra := self angleInRadian. v := height * ra sin. p := position. ^ ((p x - v) @ (p y - v)) asIntegerPoint corner: ((p x + v) @ (p y + v)) asIntegerPoint"! ! !ROCamera methodsFor: 'accessing' stamp: 'VanessaPena 3/12/2013 16:11'! bounds: rec |aNumber max ext| "Should be removed!!" aNumber := self extent. position := rec topLeft. ext := rec extent. max := ext x max: ext y. self extent: max@max. aNumber := aNumber / self extent. scale := scale * aNumber. ! ! !ROCamera methodsFor: 'rendering' stamp: 'AlexandreBergel 7/25/2012 16:11'! canvas ^ ROPlatform current canvasClass onCamera: self! ! !ROCamera methodsFor: 'accessing'! centerPosition ^ self bounds center! ! !ROCamera methodsFor: 'accessing'! extent ^ extent! ! !ROCamera methodsFor: 'accessing'! extent: anExtent extent := anExtent! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 12:00'! height ^ self extent y! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 12:00'! height: h self extent: (self width @ h)! ! !ROCamera methodsFor: 'initialize' stamp: 'MathieuDehouck 7/3/2013 13:12'! initialize super initialize. angle := self class defaultAngle. position := self class defaultPosition. realExtent := self class defaultExtent. extent := self class defaultExtent. windowSize := self class defaultExtent. "NOT sure of scale" scale := 1@1.! ! !ROCamera methodsFor: 'public' stamp: 'AlexandreBergel 11/14/2012 11:57'! moveDown self altitude: self altitude - 10! ! !ROCamera methodsFor: 'public'! moveToSee: aRectangle | t | t := aRectangle extent x min: aRectangle extent y. position := t @ t. "height := (t / 2 / (self angleInRadian / 2) tan) asInteger" "height := ((aRectangle extent x) / 2 / (self angleInRadian / 2) tan) asInteger"! ! !ROCamera methodsFor: 'public' stamp: 'AlexandreBergel 11/14/2012 11:56'! moveUp self altitude: self altitude +10! ! !ROCamera methodsFor: 'accessing'! position ^ position! ! !ROCamera methodsFor: 'accessing'! realBounds ^ position extent: realExtent! ! !ROCamera methodsFor: 'accessing'! realBounds: rec "Should be removed!!" position := rec topLeft. self realExtent: rec extent.! ! !ROCamera methodsFor: 'accessing'! realExtent ^ realExtent! ! !ROCamera methodsFor: 'accessing'! realExtent: anObject realExtent := anObject! ! !ROCamera methodsFor: 'util' stamp: 'AlexandreBergel 11/14/2012 12:25'! realToVirtualPoint: aPoint "Return a real point from a one expressed in the virtual coordinates" | r | r := self realToVirtualPointNoTrunc: aPoint. ^ r x asInteger @ r y asInteger ! ! !ROCamera methodsFor: 'util' stamp: 'AlexandreBergel 11/14/2012 12:24'! realToVirtualPointNoTrunc: aPoint "Return a real point from a one expressed in the virtual coordinates" | visibleBounds offset | (realExtent = (0 @ 0)) ifTrue: [ ^ 1 @ 1 ]. visibleBounds := self bounds. offset := self position. ^ ((aPoint x asFloat / realExtent x * visibleBounds width + offset x) asFloat) @ ((aPoint y asFloat / realExtent y * visibleBounds height + offset y) asFloat) ! ! !ROCamera methodsFor: 'util'! realToVirtualRectangle: aRectangle "Return a rectangle with virtual coordinates from one expressed in the real coordinates" ^ (self realToVirtualPoint: aRectangle origin) corner: (self realToVirtualPoint: aRectangle corner)! ! !ROCamera methodsFor: 'accessing' stamp: 'VanessaPena 3/12/2013 18:15'! scale ^ scale! ! !ROCamera methodsFor: 'public'! translateBy: pos position := position + pos! ! !ROCamera methodsFor: 'public'! translateBy: aPoint during: aBlock self translateBy: aPoint. aBlock value. self translateBy: aPoint negated.! ! !ROCamera methodsFor: 'public'! translateByRealStep: aStep "aStep represents the step in pixel on what the user see the visu" self translateBy: (self realToVirtualPoint: aStep)! ! !ROCamera methodsFor: 'public'! translateTo: pos position := pos! ! !ROCamera methodsFor: 'util' stamp: 'AlexandreBergel 7/23/2012 12:18'! virtualToRealPoint: aPoint "Return a virtual point from a one expressed in the real coordinates" ^ (self virtualToRealPointNoTrunc: aPoint) asIntegerPoint ! ! !ROCamera methodsFor: 'util'! virtualToRealPointNoTrunc: aPoint "Return a virtual point from a one expressed in the real coordinates" | visibleBounds offset | visibleBounds := self bounds. offset := self position. ^ ((aPoint x asFloat - offset x * realExtent x / visibleBounds width) asFloat) @ ((aPoint y asFloat - offset y * realExtent y / visibleBounds height) asFloat) ! ! !ROCamera methodsFor: 'util'! virtualToRealRectangle: aRectangle "Return a rectangle with real coordinates from one expressed in the virtual coordinates" ^ (self virtualToRealPoint: aRectangle origin) corner: (self virtualToRealPoint: aRectangle corner)! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 6/5/2012 11:17'! width ^ self extent x! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 12:01'! width: w self extent: (w @ self height)! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 1/1/2013 17:41'! windowSize "Size of the window, as a point" ^ windowSize! ! !ROCamera methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 13:42'! windowSize: anExtent "called when the window is resized" windowSize := anExtent ! ! !ROCanvasWrapper class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/4/2013 10:12'! onCanvas: aROCanvas ^self new canvas: aROCanvas! ! !ROCanvasWrapper methodsFor: 'accesing' stamp: 'VanessaPena 1/4/2013 10:41'! camera ^canvas camera! ! !ROCanvasWrapper methodsFor: 'accesing' stamp: 'VanessaPena 1/4/2013 10:24'! camera: aROCamera canvas camera: aROCamera ! ! !ROCanvasWrapper methodsFor: 'accesing' stamp: 'VanessaPena 1/4/2013 10:22'! canvas ^canvas! ! !ROCanvasWrapper methodsFor: 'accesing' stamp: 'VanessaPena 1/4/2013 10:13'! canvas: aROCanvas canvas := aROCanvas! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! drawString: aByteString at: aPoint canvas drawString: aByteString at: aPoint ! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! drawString: aByteString at: aPoint color: color canvas drawString: aByteString at: aPoint color: color! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! drawString: aByteString at: p font: f color: color canvas drawString: aByteString at: p font: f color: color! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 canvas fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 ! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! fillRectangle: aRectangle color: fillColor canvas fillRectangle: aRectangle color: fillColor ! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:34'! form ^canvas form! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:35'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor canvas frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor ! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:35'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor canvas line: aPoint to: aPoint2 width: aSmallInteger color: aColor ! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:25'! paintBackground: backgroundColor canvas paintBackground: backgroundColor! ! !ROCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:35'! paintImage: aForm at: aPoint canvas paintImage: aForm at: aPoint! ! !RONoTextCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:37'! drawString: aByteString at: aPoint ! ! !RONoTextCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:37'! drawString: aByteString at: aPoint color: color! ! !RONoTextCanvasWrapper methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:37'! drawString: aByteString at: p font: f color: color! ! !ROCell class methodsFor: 'instance creation' stamp: 'JurajKubelka 4/17/2013 10:10'! elements: aCollection columns: anInteger ^ self new columns: anInteger; elements: aCollection; yourself! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:28'! column ^((number - 1) rem: columns) + 1! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:42'! columnWidthAt: index "private" ^ columnWidths at: index! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:27'! columns ^ columns! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:27'! columns: anObject columns := anObject! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:38'! computeColumnWidths columnWidths := Array new: elements columnCount. 1 to: elements columnCount do: [ :columnIndex | columnWidths at: columnIndex put: ((elements atColumn: columnIndex) select: #notNil thenCollect: #width) max ].! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:38'! computeRowHeights rowHeights := Array new: elements rowCount. 1 to: elements rowCount do: [ :rowIndex | rowHeights at: rowIndex put: ((elements atRow: rowIndex) select: #notNil thenCollect: #height) max ].! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:27'! element ^ element! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:27'! element: anObject element := anObject! ! !ROCell methodsFor: 'accessing' stamp: 'AlexandreBergel 6/12/2013 10:14'! elements: aCollection | rows col | rows := (aCollection size / columns) ceiling rounded. col := Array new: rows * columns. 1 to: aCollection size do: [ :i | col at: i put: (aCollection at: i)]. elements := ROCellMatrix rows: rows columns: columns contents: col. self computeColumnWidths. self computeRowHeights.! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/17/2013 10:05'! extent ^ self width @ self height! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:44'! height ^ self rowHeightAt: self row! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:28'! number ^ number! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:28'! number: anObject number := anObject! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 4/16/2013 22:28'! row ^((number - 1) quo: columns) + 1! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:42'! rowHeightAt: index "private" ^ rowHeights at: index! ! !ROCell methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 23:45'! width ^ self columnWidthAt: self column! ! !ROCellMatrix class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 6/12/2013 10:03'! rows: rows columns: columns contents: contents ^self new rows: rows columns: columns contents: contents! ! !ROCellMatrix methodsFor: 'accessing rows/columns' stamp: 'AlexandreBergel 6/12/2013 10:05'! atColumn: column | p | p := (self indexForRow: 1 andColumn: column) - ncols. ^ (1 to: nrows) collect: [ :row | contents at: (p := p+ncols) ] ! ! !ROCellMatrix methodsFor: 'accessing rows/columns' stamp: 'AlexandreBergel 6/12/2013 10:05'! atRow: row (row between: 1 and: nrows) ifFalse: [ self error: '1st subscript out of range' ]. ^ contents copyFrom: (row - 1) * ncols + 1 to: row * ncols! ! !ROCellMatrix methodsFor: 'accessing' stamp: 'AlexandreBergel 6/12/2013 10:04'! columnCount ^ ncols! ! !ROCellMatrix methodsFor: 'private' stamp: 'AlexandreBergel 6/12/2013 10:20'! indexForRow: row andColumn: column (row between: 1 and: nrows) ifFalse: [self error: '1st subscript out of range']. (column between: 1 and: ncols) ifFalse: [self error: '2nd subscript out of range']. ^ (row - 1) * ncols + column! ! !ROCellMatrix methodsFor: 'accessing' stamp: 'AlexandreBergel 6/12/2013 10:04'! rowCount ^ nrows! ! !ROCellMatrix methodsFor: 'private' stamp: 'AlexandreBergel 6/12/2013 10:19'! rows: rows columns: columns contents: anArray (((rows isInteger and: [rows >= 0]) and: [columns isInteger and: [columns >= 0]]) and: [ rows * columns = anArray size ]) ifFalse: [ self error: 'Wrong parameters' ]. nrows := rows. ncols := columns. contents := anArray! ! !ROCommand methodsFor: 'accessing' stamp: 'VanessaPena 12/5/2012 15:54'! name ^name! ! !ROExportCommand class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 11/19/2012 22:32'! commands |commands| commands := OrderedCollection new. self subclasses do:[:cl | commands add: cl new]. ^commands ! ! !ROExportCommand methodsFor: 'execute' stamp: 'AlexandreBergel 8/29/2013 09:24'! executeOn: view self prepareViewForExport: view. self exportView: view.! ! !ROExportCommand methodsFor: 'execute' stamp: 'AlexandreBergel 8/29/2013 09:24'! exportView: view self subclassResponsibility! ! !ROExportCommand methodsFor: 'util' stamp: 'AlexandreBergel 8/29/2013 09:20'! prepareViewForExport " canvas camera windowSize: view encompassingRectangle bottomRight. canvas view: view. canvas addStart."! ! !ROExportCommand methodsFor: 'util' stamp: 'AlexandreBergel 8/29/2013 09:22'! prepareViewForExport: view view makeAllElementAsRendered. ! ! !ROExportHTMLCommand methodsFor: 'execute' stamp: 'AlexandreBergel 8/29/2013 09:24'! exportView: view ROPlatform current htmlExporterClass exportViewAsHTML: view! ! !ROExportHTMLCommand methodsFor: 'initialize-release' stamp: 'VanessaPena 11/25/2012 14:55'! initialize name := 'Export as HTML'! ! !ROExportPNGCommand methodsFor: 'execute' stamp: 'AlexandreBergel 8/29/2013 09:24'! exportView: view ROPlatform current imageExporterClass exportViewAsPNG: view! ! !ROExportPNGCommand methodsFor: 'initialize-release' stamp: 'VanessaPena 11/19/2012 22:29'! initialize name := 'Export as PNG'! ! !ROExportSVGCommand methodsFor: 'execute' stamp: 'AlexandreBergel 8/29/2013 09:24'! exportView: view ROPlatform current svgExporterClass exportViewAsSVG: view! ! !ROExportSVGCommand methodsFor: 'initialize-release' stamp: 'VanessaPena 11/19/2012 22:29'! initialize name := 'Export as SVG'! ! !ROLoadViewCommand methodsFor: 'running' stamp: 'VanessaPena 12/5/2012 15:51'! execute view := ROPlatform current serializerClass new interactiveImportView! ! !ROLoadViewCommand methodsFor: 'initialize-release' stamp: 'VanessaPena 12/5/2012 15:51'! initialize name := 'Load View'! ! !ROLoadViewCommand methodsFor: 'accessing' stamp: 'VanessaPena 12/5/2012 15:51'! view ^view! ! !ROSaveViewCommand class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 12/5/2012 16:08'! on: aROView ^self new view: aROView ! ! !ROSaveViewCommand methodsFor: 'running' stamp: 'VanessaPena 12/5/2012 15:54'! execute ROPlatform current serializerClass new interactiveExportView: view! ! !ROSaveViewCommand methodsFor: 'initialize-release' stamp: 'VanessaPena 12/5/2012 15:54'! initialize name := 'Save view'! ! !ROSaveViewCommand methodsFor: 'accessing' stamp: 'VanessaPena 12/5/2012 15:54'! view: aROView view := aROView ! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 4/14/2013 14:13'! constraintInItsParent: element element on: ROElementTranslated do: [ :event | element translateTo: ((element position max: (0 @ 0)) min: (element parent extent - element extent)) ]! ! !ROConstraint class methodsFor: 'util' stamp: 'AlexandreBergel 9/30/2012 21:05'! move: element above: anotherElement ^ element translateTo: anotherElement position - (0 @ element height)! ! !ROConstraint class methodsFor: 'util' stamp: 'AlexandreBergel 9/30/2012 21:04'! move: element below: anotherElement ^ element translateTo: anotherElement position + (0 @ anotherElement height)! ! !ROConstraint class methodsFor: 'util' stamp: 'AlexandreBergel 6/11/2013 11:21'! move: element between: el1 and: el2 ^ element translateTo: ((el1 position + el2 position) / 2)! ! !ROConstraint class methodsFor: 'util' stamp: 'VanessaPena 3/14/2013 16:46'! move: element onTheCenterOf: anotherElement |p| p := ((anotherElement width - element width) /2) @ ((anotherElement height - element height ) /2). ^ element translateTo: anotherElement position + p.! ! !ROConstraint class methodsFor: 'util' stamp: 'AlexandreBergel 9/30/2012 19:28'! move: element onTheLeftOf: anotherElement ^ element translateTo: anotherElement position - (element width @ 0)! ! !ROConstraint class methodsFor: 'util' stamp: 'AlexandreBergel 9/30/2012 21:02'! move: element onTheRightOf: anotherElement ^ element translateTo: anotherElement position + (anotherElement width @ 0)! ! !ROConstraint class methodsFor: 'util - window' stamp: 'AlexandreBergel 7/10/2013 13:56'! moveAtBottomRightOfTheWindow: element | windowSize | windowSize := element view camera windowSize. element translateTo: windowSize - (element extent)! ! !ROConstraint class methodsFor: 'util - window' stamp: 'AlexandreBergel 10/15/2013 14:19'! moveAtCenterOfTheWindow: element | windowSize | windowSize := element view camera windowSize. element translateTo: ((windowSize / 2) asIntegerPoint - (element bounds extent / 2) asIntegerPoint )! ! !ROConstraint class methodsFor: 'util - window' stamp: 'AlexandreBergel 7/4/2013 16:48'! moveAtTheBottomOfTheWindow: element | windowSize | windowSize := element view camera windowSize. element translateTo: (0 @ (windowSize y - element height))! ! !ROConstraint class methodsFor: 'util - window' stamp: 'AlexandreBergel 7/4/2013 17:13'! moveAtTheTopRightOfTheWindow: element | windowSize | windowSize := element view camera windowSize. element translateTo: ((windowSize x - element width) @ 0)! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2012 09:30'! stick: element above: anotherElement self move: element above: anotherElement. anotherElement on: ROElementEvent do: [ :event | self move: element above: anotherElement ]! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 10/2/2012 20:05'! stick: element below: anotherElement self move: element below: anotherElement. anotherElement on: ROElementEvent do: [ :event | self move: element below: anotherElement ]. ! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 6/11/2013 11:20'! stick: element between: el1 and: el2 self move: element between: el1 and: el2. el1 on: ROElementEvent do: [ :event | self move: element between: el1 and: el2. ]. el2 on: ROElementEvent do: [ :event | self move: element between: el1 and: el2. ]. ! ! !ROConstraint class methodsFor: 'public' stamp: 'VanessaPena 3/14/2013 16:47'! stick: element onTheCenterOf: anotherElement self move: element onTheCenterOf: anotherElement. anotherElement on: ROElementEvent do: [ :event | self move: element onTheCenterOf: anotherElement ]. ! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2012 09:30'! stick: element onTheLeftOf: anotherElement self move: element onTheLeftOf: anotherElement. anotherElement on: ROElementEvent do: [ :event | self move: element onTheLeftOf: anotherElement ]. ! ! !ROConstraint class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2012 09:30'! stick: element onTheRightOf: anotherElement self move: element onTheRightOf: anotherElement. anotherElement on: ROElementEvent do: [ :event | self move: element onTheRightOf: anotherElement ]. ! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 7/10/2013 13:55'! stickAtBottomRightOfTheWindow: element self moveAtBottomRightOfTheWindow: element. element view on: ROWindowResized do: [ :event | self moveAtBottomRightOfTheWindow: element ]! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 10/15/2013 14:17'! stickAtCenterOfTheWindow: element self moveAtCenterOfTheWindow: element. element view on: ROWindowResized do: [ :event | self moveAtCenterOfTheWindow: element ]! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 7/4/2013 16:51'! stickAtTheBottomOfTheWindow: element self moveAtTheBottomOfTheWindow: element. element view on: ROWindowResized do: [ :event | self moveAtTheBottomOfTheWindow: element ]! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 7/4/2013 17:13'! stickAtTheTopRightOfTheWindow: element self moveAtTheTopRightOfTheWindow: element. element view on: ROWindowResized do: [ :event | self moveAtTheTopRightOfTheWindow: element ]! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 12/18/2012 15:38'! stickToBottomLeft: element ^ self stickToBottomLeft: element offset: 0! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 12/18/2012 15:38'! stickToBottomLeft: element offset: aNumber element translateTo: (aNumber @ element view camera windowSize y - element height - aNumber). element view on: ROWindowResized do: [ :event | element translateTo: (aNumber @ (event extent y - element height - aNumber)) ]. ! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 12/18/2012 15:39'! stickToTopRight: element ^ self stickToTopRight: element offset: 0! ! !ROConstraint class methodsFor: 'public - window' stamp: 'AlexandreBergel 12/18/2012 15:39'! stickToTopRight: element offset: aNumber element translateTo: ((element view camera windowSize x - element width) - aNumber @ aNumber). element view on: ROWindowResized do: [ :event | element translateTo: ((event extent x - element width) - aNumber @ aNumber)].! ! !ROAbstractComponent class methodsFor: 'public' stamp: 'AlexandreBergel 4/11/2013 10:55'! model: anObject ^ self on: anObject! ! !ROAbstractComponent class methodsFor: 'public' stamp: 'JurajKubelka 5/17/2013 12:09'! on: anObject ^ self new on: anObject; yourself! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 9/14/2013 15:08'! + aShape "Add a shape to myself. aShape could either be an instance of a shape class or a class" self addShape: aShape. ! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 9/10/2012 09:00'! - aShape "Remove a shape from myself. aShape could either be an instance of a shape class or a class" self removeShape: aShape. ^ self ! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 9/10/2012 09:01'! @ anInteractionClassOrInstance "Add an interaction to the node" self addInteraction: anInteractionClassOrInstance! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'BenComan 10/14/2012 23:11'! addInteraction: anInteractionClassOrInstance "Add an interaction to the node" interactions at: anInteractionClassOrInstance key put: (anInteractionClassOrInstance initializeElement: self) ! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 9/14/2013 15:15'! addShape: aShapeOrShapeClass "Add a shape to myself. aShape could either be an instance of a shape class or simply a class" | s | s := (aShapeOrShapeClass installedOn: self). s addLast: shape. shape := s. ! ! !ROAbstractComponent methodsFor: 'enumerating' stamp: 'AlexandreBergel 9/10/2012 09:03'! allElementsDo: aBlock "aBlock is a one-arg block. This method executes aBlock for each element that I contains. The block receive the element as argument" self elementsDo: [:each | aBlock value: each. each allElementsDo: aBlock ]! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 8/19/2012 13:20'! announce: anEvent "trigger an event. Objects who registered to me will get notified" | eventToBeSent | eventToBeSent := anEvent isBehavior ifTrue: [ anEvent new ] ifFalse: [ anEvent ]. eventToBeSent element: self. eventHandler announce: eventToBeSent! ! !ROAbstractComponent methodsFor: 'cache' stamp: 'AlexandreBergel 9/14/2013 12:44'! attributeCaches ^ self attributes keys select: [ :k | k endsWith: 'Cache' ]! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 9/10/2012 09:03'! change: aShapeClass for: aShape "aDecorator could be a class or a shape" shape := shape change: aShapeClass for: (aShape installedOn: self). ! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'AlexandreBergel 9/10/2012 09:03'! changeInteraction: anInteractionClass for: anInteraction "Change an interaction, instance of anInteractionClass, for an Interaction" self removeInteraction: anInteractionClass. self @ anInteraction! ! !ROAbstractComponent methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 12/4/2012 08:43'! depth ^ 1 + parent depth! ! !ROAbstractComponent methodsFor: 'drawing' stamp: 'AlexandreBergel 9/14/2012 19:03'! drawOn: aCanvas "This should be changed. drawOn: should not do an explicit iteration, but letting each shape call drawOn: on its next " shape chainedDrawOn: aCanvas for: self ! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:25'! forShape: shapeClass do: aOneArgBlock "Find the shape that correspond to the shape class, and evaluate the block by passing the shape to it" | v | v := ( self getShape: shapeClass). v ifNotNil: [ aOneArgBlock value: v ]! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 8/19/2012 17:12'! forward eventHandler forward! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 8/19/2012 17:12'! forward: obj eventHandler forward: obj! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'AlexandreBergel 8/20/2012 09:19'! getInteraction: anInteractionClass ^ interactions at: anInteractionClass ! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'BenComan 10/14/2012 22:07'! getInteraction: anInteractionClass ifPresent: aBlock ^ interactions at: anInteractionClass ifPresent: aBlock ! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:26'! getShape: shapeClass "Return a shape instance, instance of the shape class provided as parameter" ^ self shapeDetect: [ :de | de isKindOf: shapeClass ]! ! !ROAbstractComponent methodsFor: 'initialize-release' stamp: 'JurajKubelka 5/17/2013 12:04'! initialize super initialize. parent := ROView nullView. eventHandler := ROAnnouncer new. view := ROView nullView. shape := RONullShape new. "Actually, I am not sure we need to have a variable interactions" interactions := IdentityDictionary new. zIndex := 0! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'AlexandreBergel 8/19/2012 17:16'! interactionsDo: aBlock "Execute a block for each interaction" interactions ifNil: [ ^ self ]. interactions values do: aBlock! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 10/20/2013 15:21'! is: anInteractionClass "Return true if the element has the interaction class provided in parameter" interactions ifNil: [ ^ false ]. ^ interactions includesKey: anInteractionClass! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 5/7/2013 14:47'! isEdge "True if I am an edge" self subclassResponsibility! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 11/27/2012 21:00'! isElement ^ self isEdge not! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 8/19/2012 13:18'! isNotEdge ^ self isEdge not! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 4/11/2013 15:16'! isRendered "Return true I will be rendered by the view that contains me" ^ self view isRendered: self ! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 8/19/2012 12:39'! isShapedAs: aShapeClass ^ shape isShapedAs: aShapeClass! ! !ROAbstractComponent methodsFor: 'testing' stamp: 'AlexandreBergel 10/20/2013 15:21'! isVisibleIn: rectangle "Return true if the element is completely or partially visible in the rectangle given in parameter" self subclassResponsibility! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 8/19/2012 12:37'! model "Return the object behind the element" ^ model! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:38'! model: anObject "Set the object behind the element" model := anObject. self modelChanged. self resetCache.! ! !ROAbstractComponent methodsFor: 'events' stamp: 'JurajKubelka 5/17/2013 11:57'! modelChanged "We should do an annoucement like ROModelChanged. But for now it is not useful. It is here just because of cache of ROLabel." self shapesDo: [ :eachShape | eachShape modelChanged: self ]! ! !ROAbstractComponent methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 9/2/2012 20:44'! numberOfInteractions "Answer the number of interactions" " ^ eventHandler numberOfSubscriptions " interactions ifNil: [ ^ 0 ]. ^ interactions size ! ! !ROAbstractComponent methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 9/5/2012 08:39'! numberOfShapes "Return the number of shapes associated to the element" ^ self shapes size ! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 12/11/2012 15:29'! on: anObject "Set the object model of myself. The object model is used by the shape when computing metrics that may be used by the shapes" self model: anObject! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 9/2/2012 21:12'! on: eventClass do: aBlock "Register a block as an handler for eventClass" eventHandler when: eventClass do: aBlock. "interactions at: eventClass put: aBlock"! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 11/25/2012 11:01'! on: eventClass doOnce: aBlock "Register a block as an handler for eventClass. The callback is removed when exected" eventHandler when: eventClass do: [ :arg | aBlock value: arg. eventHandler unsubscribeForEvent: eventClass. "self removeInteraction: eventClass "]! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 9/10/2012 09:04'! parent "Return the node in which I am contained" ^ parent! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 9/10/2012 09:04'! parent: aViewOrAnElement "Set the node in which I am contained" parent := aViewOrAnElement! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 9/10/2012 09:07'! parentAnnounce: event "Make the parent announce something" parent announce: event! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'AlexandreBergel 12/11/2012 15:03'! remove "Remove myself from the view I belong to (if I actually belong to the view, else do nothing) and from my parent." self removeFromParent. self view removeElementToRender: self. "We remove all the subelements" self allElementsDo: #remove! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'AlexandreBergel 12/11/2012 15:02'! removeFromParent parent remove: self ifAbsent: [ ]! ! !ROAbstractComponent methodsFor: 'interaction' stamp: 'AlexandreBergel 9/2/2012 20:58'! removeInteraction: anInteractionClass "Remove an interaction from the receiver. No error is raised if no interaction is found" | ds | ds := interactions select: [ :d | d isKindOf: anInteractionClass ]. ds associationsDo: [ :assoc | interactions removeKey: assoc key. eventHandler unsubscribe: assoc value ]. ! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:26'! removeShape: aShapeClass "Remove a shape of the element" shape := shape removeShape: aShapeClass! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'AlexandreBergel 9/14/2013 12:44'! resetCache self attributeCaches do: [ :k | self removeAttribute: k ]! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'DR 1/15/2013 21:23'! reversedShapesDo: aBlock ^ self shapes reverse do: aBlock! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'AlexandreBergel 5/7/2013 19:25'! setAsNotRendered self view markAsToBeRemoved: self.! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'AlexandreBergel 5/7/2013 19:37'! setAsRendered self view markAsToBeAdded: self! ! !ROAbstractComponent methodsFor: 'actions' stamp: 'DR 1/15/2013 20:52'! setZindexFrom: aZOrdering aZOrdering setZindexOf: self! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:34'! shapeDetect: aBlock ^ shape shapeDetect: aBlock! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/27/2013 21:48'! shapes "Return the list of shapes" | ans d | ans := OrderedCollection new. d := shape. [ d hasNext ] whileTrue: [ ans add: d. d := d next ]. ans add: d. ^ ans.! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:34'! shapesCollect: aBlock ^ self shapes collect: aBlock! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 9/24/2012 11:56'! shapesDo: aBlock ^ shape shapesDo: aBlock! ! !ROAbstractComponent methodsFor: 'shapes' stamp: 'AlexandreBergel 8/19/2012 12:35'! shapesSelect: aBlock ^ self shapes select: aBlock! ! !ROAbstractComponent methodsFor: 'events' stamp: 'AlexandreBergel 8/19/2012 17:13'! signalUpdate "Trigger a redisplay of the view" ^ view signalUpdate! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 8/19/2012 12:41'! view "Answer the view in which I am defined" ^ view! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 11/28/2012 18:26'! view: aView "Set the view in which I am defined. All my elements should also belong to the same view" view := aView. ! ! !ROAbstractComponent methodsFor: 'enumerating' stamp: 'TudorGirba 9/9/2012 21:40'! withAllElementsDo: aBlock aBlock value: self. self allElementsDo: aBlock! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 21:40'! zIndex ^ zIndex! ! !ROAbstractComponent methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 21:40'! zIndex: anInteger zIndex := anInteger! ! !ROEdge class methodsFor: 'public' stamp: 'AlexandreBergel 7/14/2012 15:01'! arrowedLineFrom: f to: t ^ (self from: f to: t) + (ROLine new addBegining: ROArrow new) ; yourself! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 9/1/2013 09:21'! buildEdgesFromAssociations: associations inView: view "associations could be {2 -> 5 . 1 -> 5 }. Takes the model of element into account" ^ self buildEdgesFromElements: associations from: #key to: #value inView: view! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 9/1/2013 09:20'! buildEdgesFromAssociations: associations using: aLineShape "associations could be {2 -> 5 . 1 -> 5 }. Takes the model of element into account" ^ self buildEdgesFromElements: associations from: #key to: #value using: aLineShape! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 9/1/2013 09:28'! buildEdgesFromAssociations: associations using: aLineShape inView: view "associations could be {2 -> 5 . 1 -> 5 }. Takes the model of element into account" | edges associationsOfElements | associationsOfElements := associations collect: [ :assoc | (view elementFromModel: assoc key) -> (view elementFromModel: assoc value) ]. associationsOfElements ifEmpty: [ ^ #() ]. edges := OrderedCollection new. associationsOfElements do: [ :associationOfTwoElements | | edge | edge := ROEdge from: associationOfTwoElements key to: associationOfTwoElements value. edge + aLineShape. edges add: edge ]. view addAll: edges. ^ edges ! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 8/11/2013 22:03'! buildEdgesFromElements: elements from: fromBlock to: toBlock "Handy method to easily build edges. Return a list of edges" ^ self buildEdgesFromElements: elements from: fromBlock to: toBlock using: ROLine! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 9/1/2013 14:34'! buildEdgesFromElements: elements from: fromBlock to: toBlock using: aLineShape "Handy method to easily build edges. Return a list of edges" "fromBlock and toBlock operate on the model of the elements" | edges container fromElement toElement elementsWithModels | elements ifEmpty: [ ^ #() ]. edges := OrderedCollection new. elementsWithModels := elements select: [ :el | el model notNil ]. elementsWithModels do: [ :element | container := element parent. fromElement := container elementFromModel: (fromBlock roValue: element model). toElement := container elementFromModel: (toBlock roValue: element model). (fromElement notNil and: [ toElement notNil ]) ifTrue: [ | edge | edge := ROEdge from: fromElement to: toElement. edge + aLineShape. edges add: edge. container add: edge ] ]. ^ edges ! ! !ROEdge class methodsFor: 'public - edges constructions' stamp: 'AlexandreBergel 10/21/2013 14:13'! buildEdgesFromElements: elements from: fromBlock toAll: toBlock using: aLineShape "Handy method to easily build edges. Return a list of edges" "fromBlock and toBlock operate on the model of the elements" "toBlock should return a collection of models" | edges container fromElement toElements elementsWithModels | elements ifEmpty: [ ^ #() ]. edges := OrderedCollection new. elementsWithModels := elements select: [ :el | el model notNil ]. elementsWithModels do: [ :element | container := element parent. fromElement := container elementFromModel: (fromBlock roValue: element model). "We get the list of elements that corresponds to (toBlock roValues: element model)" toElements := OrderedCollection new. (toBlock roValue: element model) do: [ :model | | v | v := container elementFromModel: model. v notNil ifTrue: [ toElements add: v ] ]. (fromElement notNil and: [ toElements notEmpty ]) ifTrue: [ toElements do: [ :toElement | | edge | edge := ROEdge from: fromElement to: toElement. edge + aLineShape. edges add: edge. container add: edge ] ] ]. ^ edges ! ! !ROEdge class methodsFor: 'public' stamp: 'TudorGirba 7/29/2012 22:44'! from: fromNode to: toNode ^ self on: nil from: fromNode to: toNode! ! !ROEdge class methodsFor: 'public'! lineFrom: f to: t ^ (self from: f to: t) + ROLine ; yourself! ! !ROEdge class methodsFor: 'public'! linesFor: associations "Return a collection of edges, one for each provided association" ^ associations collect: [ :assoc | self lineFrom: assoc key to: assoc value ]! ! !ROEdge class methodsFor: 'public' stamp: 'TudorGirba 7/29/2012 22:44'! on: aModel from: f to: t self assert: [ f isKindOf: ROElement ]. self assert: [ t isKindOf: ROElement ]. ^ (self on: aModel) from: f to: t; yourself! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 4/11/2013 15:30'! absolutePosition ^ self from absolutePosition ! ! !ROEdge methodsFor: 'visiting'! accept: aVisitor aVisitor visitEdge: self! ! !ROEdge methodsFor: 'actions' stamp: 'AlexandreBergel 8/19/2012 13:14'! addedInAnElement: el el addElement: self. self parent: el; view: el view. ! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 8/19/2012 18:37'! bounds ^ Rectangle merging: (Array with: self from bounds with: self to bounds)! ! !ROEdge methodsFor: 'testing' stamp: 'AlexandreBergel 1/26/2013 19:14'! contains: aPoint ^ shape contains: aPoint for: self ! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 12/5/2012 17:21'! edgeFromModel: object "if the object is equal to the mode, then return itself, else nil" (self model = object) ifTrue: [ ^ self ]. ^ nil! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 8/23/2012 22:52'! elementAt: aPoint "Do nothing since an edge cannot contain other elements" ^ self ! ! !ROEdge methodsFor: 'actions' stamp: 'AlexandreBergel 12/5/2012 17:21'! elementFromModel: object "if the object is equal to the mode, then return itself, else nil" "(self model = object) ifTrue: [ ^ self ]." ^ nil! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 8/19/2012 13:19'! elementsDo: aBlock "Do nothing"! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 9/5/2012 09:16'! extent ^ self bounds extent ! ! !ROEdge methodsFor: 'accessing'! from ^ from! ! !ROEdge methodsFor: 'accessing'! from: f to: t from := f. to := t! ! !ROEdge methodsFor: 'accessing' stamp: 'VanessaPena 8/29/2012 05:07'! height ^((self from position y) - (self to position y)) abs! ! !ROEdge methodsFor: 'testing'! isEdge ^ true! ! !ROEdge methodsFor: 'testing' stamp: 'AlexandreBergel 10/20/2013 15:30'! isVisibleIn: rectangle "Return true if the element is completely or partially visible in the rectangle given in parameter" "In the case of an edge, the method returns true if one of the boundary is on screen. This has the effect to display the edge even if one extremity is not visible" ^ (from isVisibleIn: rectangle) or: [ to isVisibleIn: rectangle ] ! ! !ROEdge methodsFor: 'accessing' stamp: 'VanessaPena 8/26/2012 09:19'! position ^self from position ! ! !ROEdge methodsFor: 'accessing'! source ^ self from! ! !ROEdge methodsFor: 'accessing'! target ^ self to! ! !ROEdge methodsFor: 'accessing'! to ^ to! ! !ROEdge methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 1/26/2013 19:14'! topLeft ^ (shape lineSegmentsFor: self) first ! ! !ROEdge methodsFor: 'translation' stamp: 'VanessaPena 8/29/2012 05:05'! translateBy: aPoint ! ! !ROEdge methodsFor: 'translation' stamp: 'VanessaPena 8/29/2012 05:07'! translateTo: aPoint ! ! !ROEdge methodsFor: 'accessing' stamp: 'VanessaPena 8/29/2012 05:03'! width ^(self getShape: ROLine) width ! ! !ROButtonElement class methodsFor: 'instance creation' stamp: 'AlexandreBergel 6/1/2012 15:01'! named: aName do: aOneArgBlockAsCallback ^ self basicNew initializeWithName: aName Callback: aOneArgBlockAsCallback! ! !ROButtonElement methodsFor: 'public' stamp: 'AlexandreBergel 6/1/2012 15:04'! initializeWithName: aName Callback: callbackAsOneArgBlock super initialize. self + (ROLabel text: aName). self @ ROLightlyHighlightable. self on: ROMouseClick do: callbackAsOneArgBlock. ! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 9/25/2012 20:23'! bare "Only has a nullshape, no children shape" ^ self basicNew initializeBare! ! !ROElement class methodsFor: 'defaults' stamp: 'JurajKubelka 10/11/2013 17:31'! defaultBounds ^ (0 @ 0 corner: ROShape defaultExtent)! ! !ROElement class methodsFor: 'public'! forCollection: aCollection ^ (aCollection collect: [ :v | self on: v ]) asArray! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 18:43'! label ^ self new + ROLabel! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 6/11/2012 12:38'! labelsOn: collection ^ (self forCollection: collection) collect: [ :v | v + ROLabel ]! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 5/7/2012 11:54'! sprite ^ self new extent: 50 @ 50; addInteraction: RODraggable; addShape: (ROBorder new color: Color red); yourself! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 18:44'! spriteOn: value ^ self sprite on: value! ! !ROElement class methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 18:44'! spritesOn: values ^ values collect: [:v | self sprite on: v ]! ! !ROElement methodsFor: 'accessing'! absolutePosition "Return the absolute position of the element, the top left corner" ^ parent ifNil: [ self position ] ifNotNil: [ self position + parent absolutePosition ]! ! !ROElement methodsFor: 'visiting' stamp: 'AlexandreBergel 11/27/2012 19:36'! accept: aVisitor aVisitor visitElement: self! ! !ROElement methodsFor: 'actions' stamp: 'AlexandreBergel 12/13/2012 14:45'! add: el self assert: [ el isKindOf: ROAbstractComponent ]. self addChild: el. self view addElementRecursivelyToRender: el! ! !ROElement methodsFor: 'public'! addAll: els els do: [:el | self add: el ]! ! !ROElement methodsFor: 'actions' stamp: 'VanessaPena 12/22/2012 19:47'! addChild: el el addedInAnElement: self.! ! !ROElement methodsFor: 'shapes' stamp: 'JurajKubelka 10/11/2013 16:53'! addShape: aShapeOrShapeClass | e1 e2 | "The super call set the shape to have in the 'shape' variable" e1 := self extent. super addShape: aShapeOrShapeClass. e2 := shape extentFor: self. self extent: (e2 max: e1)! ! !ROElement methodsFor: 'actions' stamp: 'AlexandreBergel 6/21/2013 09:44'! addedInAnElement: el "self translateBy: el topLeft negated." self translateBy: el resizeStrategy padding. self parent: el; view: el view. el addElement: self. el adjustSizeIfNecessary ! ! !ROElement methodsFor: 'actions' stamp: 'VanessaPena 12/21/2012 02:00'! adjustSizeIfNecessary resizeStrategy on: self! ! !ROElement methodsFor: 'accessing' stamp: 'VanessaPena 4/12/2013 12:25'! allEdgesFrom |edges| edges := OrderedCollection new. self view allElementsDo: [ :edge | edge isEdge ifTrue: [ (edge from == self) ifTrue: [ edges add: edge ] ] ]. ^edges ! ! !ROElement methodsFor: 'accessing' stamp: 'VanessaPena 4/12/2013 12:25'! allEdgesTo |edges| edges := OrderedCollection new. self view allElementsDo: [ :edge | edge isEdge ifTrue: [ (edge to == self) ifTrue: [ edges add: edge ] ] ]. ^edges ! ! !ROElement methodsFor: '*RoassalExtras-TreeMap' stamp: 'RobertoMinelli 10/8/2013 17:31'! area ^ self attributes at: #area ifAbsent: [ ^ nil ] .! ! !ROElement methodsFor: '*RoassalExtras-TreeMap' stamp: 'RobertoMinelli 10/8/2013 17:32'! area: anArea self attributes at: #area put: anArea .! ! !ROElement methodsFor: 'accessing'! bottomCenter ^ self bounds bottomCenter! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 08:53'! bottomLeft ^ self bounds bottomLeft! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 08:53'! bottomRight ^ self bounds bottomRight! ! !ROElement methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:17'! bounds "Return the bounds of the element" ^ self position extent: self extent! ! !ROElement methodsFor: 'accessing'! center ^ self bounds center! ! !ROElement methodsFor: 'accessing'! center: pos ^ self translateTo: (pos - (self extent / 2))! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 09:18'! center: aPoint radius: d position := (aPoint - (d @ d)). self extent: (2 * d @ ( 2 * d))! ! !ROElement methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/24/2012 15:29'! collectPathToRootIn: aCollection "Return the path from this graph to the root graph" aCollection addLast: self. self parent ifNotNil: [self parent collectPathToRootIn: aCollection]! ! !ROElement methodsFor: 'testing' stamp: 'AlexandreBergel 12/11/2012 15:22'! contains: aPoint "Return true if aPoint is within the bounds of myself. Note that aPoint is relative to the owner of the element" ^ (aPoint < (self extent + self absolutePosition)) and: [ aPoint >= (self absolutePosition) ] " ^ shape element: self containsPoint: aPoint "! ! !ROElement methodsFor: 'copying' stamp: 'AlexandreBergel 4/24/2013 09:27'! copy "Return a copy of myself, shapes and interactions are not copied" | answer | answer := self class new. answer translateTo: self position; extent: self extent. self shapesDo: [ :d | answer + d ]. self interactionsDo: [ :i | answer @ i ]. ^ answer ! ! !ROElement methodsFor: 'actions'! elementsFromModels: objects ^ self elementsSuchThat: [ :el | objects includes: el model ]! ! !ROElement methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:42'! extent "Return the extent of myself" ^ self shapeCache extentIfAbsentPut: [ shape maxChainedExtentFor: self ].! ! !ROElement methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 17:13'! extent: aPoint "Set the extent of myself. Do nothing if the new extent is the same that the one I have" self extent = aPoint ifTrue: [ ^ self ]. self shapeCache extent: aPoint. shape elementExtent: aPoint. self announce: ROElementResized. self callback element: self resizedTo: aPoint ! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:11'! father ^ self attributes at: #father ifAbsent: [ ^ nil ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! father: aNode self attributeAt: #father put: aNode! ! !ROElement methodsFor: 'accessing'! height ^ self extent y! ! !ROElement methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:27'! height: h "h is a numerical value" (h = self height) ifTrue: [ ^ self ]. self announce: ROElementResized. self shapeCache height: h ! ! !ROElement methodsFor: 'initialization' stamp: 'JurajKubelka 5/17/2013 12:05'! initialize super initialize. position := 0 @ 0.! ! !ROElement methodsFor: 'initialization' stamp: 'AlexandreBergel 4/22/2013 19:19'! initializeBare super initialize. position := 0 @ 0. shape := RONullShape new. ! ! !ROElement methodsFor: 'testing'! isEdge ^ false! ! !ROElement methodsFor: 'testing' stamp: 'AlexandreBergel 10/20/2013 15:24'! isVisibleIn: rectangle "Return true if the element is completely or partially visible in the rectangle given in parameter" ^ self bounds intersects: rectangle ! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:11'! layer ^ self attributes at: #layer ifAbsent: [ ^nil ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! layer: anInteger self attributeAt: #layer put: anInteger! ! !ROElement methodsFor: 'accessing'! leftCenter ^ self bounds leftCenter! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:11'! leftContour ^ self attributes at: #left ifAbsent: [ ^ nil ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! leftContour: aNode self attributeAt: #left put: aNode! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:20'! mod ^ self attributes at: #mod ifAbsent: [ ^ 0 ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! mod: aFloat self attributeAt: #mod put: aFloat! ! !ROElement methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/24/2012 15:15'! mostSpecificParentCommonWith: anotherElement "Search the smallest possible element that is parent of self and of anotherNode" | anotherPathToRoot | anotherPathToRoot := anotherElement pathToRoot. self pathToRoot do: [ :eachElement | (anotherPathToRoot includes: eachElement) ifTrue: [ ^ eachElement ] ]! ! !ROElement methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/24/2012 15:22'! pathToRoot "Return the path from this graph to the root graph" | path | path := OrderedCollection new. self parent ifNotNil: [self parent collectPathToRootIn: path]. ^path! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:11'! pointer ^ self attributes at: #pointer ifAbsent: [ ^ nil ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! pointer: aNode self attributeAt: #pointer put: aNode! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 09:18'! position "Return the position of the element. Return a point of floats" ^ position! ! !ROElement methodsFor: 'accessing'! positionAsInteger "Return the position as integer" ^ self position asIntegerPoint ! ! !ROElement methodsFor: 'accessing'! positionRelativeTo: anElement "Return the position of myself against the position of one of my parent, anElement. The returned position is relative to it." "This method is useful to draw edges that are nested" (anElement == self) ifTrue: [ ^ 0 @ 0 ]. ^ self topLeft + (parent positionRelativeTo: anElement)! ! !ROElement methodsFor: 'printing' stamp: 'AlexandreBergel 12/16/2012 18:27'! printOn: stream "A textual representation of myself. ROElement new printString => 'a ROElement' (ROElement on: 10) printString => 'a ROElement<10>' " super printOn: stream. model ifNotNil: [ stream nextPutAll: '<'. model printOn: stream. stream nextPutAll: '>' ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:21'! r ^ self attributes at: #r ifAbsent: [ ^ 0 ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! r: aFloat self attributeAt: #r put: aFloat! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 5/17/2012 20:31'! radius ^ self extent r / 2 ! ! !ROElement methodsFor: 'accessing'! radius: d ^ self center: self position radius: d! ! !ROElement methodsFor: 'actions' stamp: 'VanessaPena 4/11/2013 18:53'! removeAllEdgesFrom self view allElementsDo: [ :edge | edge isEdge ifTrue: [ (edge from == self) ifTrue: [ edge remove ] ] ]. ! ! !ROElement methodsFor: 'actions' stamp: 'BenComan 10/8/2012 14:12'! removeAllEdgesTo self view allElementsDo: [ :edge | edge isEdge ifTrue: [ (edge to == self) ifTrue: [ edge remove ] ] ]. ! ! !ROElement methodsFor: 'accessing'! rightCenter ^ self bounds rightCenter! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:11'! rightContour ^ self attributes at: #right ifAbsent: [ ^ nil ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! rightContour: aNode self attributeAt: #right put: aNode! ! !ROElement methodsFor: 'translation'! setBounds: aBounds self extent: aBounds extent. self translateTo: aBounds origin.! ! !ROElement methodsFor: 'cache system' stamp: 'JurajKubelka 10/11/2013 15:39'! shapeCache ^ self attributeAt: #shapeCache ifAbsentPut: [ ROShapeCache new ]! ! !ROElement methodsFor: 'accessing'! size: d self extent: d @ d! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:23'! theta ^ self attributes at: #theta ifAbsent: [ ^ 0 ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! theta: aFloat self attributeAt: #theta put: aFloat! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 12:51'! top ^ self attributes at: #top ifAbsent: [ ^ false ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! top: aBoolean self attributeAt: #top put: aBoolean ! ! !ROElement methodsFor: 'accessing'! topCenter ^ self bounds topCenter! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 08:52'! topLeft ^ self bounds topLeft ! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/5/2012 08:52'! topRight ^ self bounds topRight! ! !ROElement methodsFor: 'translation' stamp: 'AlexandreBergel 4/29/2013 15:00'! translateBy: aPoint parent translate: self by: aPoint ! ! !ROElement methodsFor: 'translation' stamp: 'AlexandreBergel 9/16/2012 12:46'! translateByRealPoint: aPoint | p | p := self view camera virtualToRealPointNoTrunc: self position. self translateTo: (self view camera realToVirtualPointNoTrunc: (p + aPoint)). ! ! !ROElement methodsFor: 'translation'! translateTo: aPoint self translateBy: (aPoint - self bounds origin)! ! !ROElement methodsFor: 'translation' stamp: 'AlexandreBergel 4/22/2013 19:12'! translateToRealPoint: aPoint | p | p := self view camera realToVirtualPoint: aPoint. self translateTo: p. ! ! !ROElement methodsFor: 'translation' stamp: 'AlexandreBergel 10/21/2013 13:47'! translateWithoutUpdatingContainedElementsBy: aPoint "translate myself without updating the parent." aPoint = (0 @ 0) ifTrue: [ ^ self ]. position := position + aPoint. self announce: (ROElementTranslated step: aPoint)! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 22:26'! view: aView "Set the view in which I am defined. All my elements should also belong to the same view" super view: aView. self elementsDo: [ :el | el view: aView ] ! ! !ROElement methodsFor: '*RoassalExtras-TreeMap' stamp: 'RobertoMinelli 10/8/2013 17:33'! weight ^ self attributes at: #weight ifAbsent: [ ^ nil ] .! ! !ROElement methodsFor: '*RoassalExtras-TreeMap' stamp: 'RobertoMinelli 10/8/2013 17:33'! weight: aWeight ^ self attributes at: #weight put: aWeight .! ! !ROElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 18:56'! width "Return a numerical value" ^ self extent x! ! !ROElement methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:21'! width: w "w is a numerical value" (w = self width) ifTrue: [ ^ self ]. self announce: ROElementResized. self shapeCache with: w.! ! !ROElement methodsFor: 'tree layout utility' stamp: 'MathieuDehouck 5/6/2013 11:25'! x ^ self attributes at: #x ifAbsent: [ ^ 0 ]! ! !ROElement methodsFor: 'tree layout utility' stamp: 'AlexandreBergel 9/15/2013 00:45'! x: aFloat self attributeAt: #x put: aFloat! ! !ROMenuElement class methodsFor: 'example' stamp: 'AlexandreBergel 9/21/2012 14:00'! example " self example " "Preambule. It includes the initialization. " | rawView view element | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "enter your script below" "-------------" "-------------" view shape rectangle size: 80. element := view node: 100. element on: ROMouseClick do: [ :ann | | menu | menu := ROMenuElement new. menu item: 'foo10' action: [ :an | 10 inspect ]. menu item: 'foo20' action: [ :an | 20 inspect ]. menu item: 'foo30' action: [ :an | 30 inspect ]. menu create. view raw add: menu. menu translateTo: ann position - (10 @ 40). element on: ROMouseDragging do: [ :v | menu remove ]. element on: ROMouseClick do: [ :v | menu remove ]. "element on: ROMouseLeave doOnce: [ :v | menu remove ]. element on: ROMouseEnter doOnce: [ :v | menu remove ]. " view raw signalUpdate. ]. "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" "ROEaselMorphic new populateMenuOn: view." view open! ! !ROMenuElement methodsFor: 'private' stamp: 'AlexandreBergel 5/22/2013 11:18'! create self createEntries. self + ROBorder blue + ROBox white. self on: ROMouseLeave do: [ :event | event element remove ]. ! ! !ROMenuElement methodsFor: 'private' stamp: 'AlexandreBergel 5/22/2013 11:19'! createEntries | nameElements | nameElements := actionDictionary keys collect: [ :title | (ROLabel elementOn: title) @ ROLightlyHighlightable; forward: ROMouseLeave; on: ROMouseClick do: [ :event | (actionDictionary at: title) value: targetObject. self remove. self view signalUpdate ] yourself ]. self addAll: nameElements. ROVerticalLineLayout on: nameElements.! ! !ROMenuElement methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2012 19:51'! evaluate: aTitleAsString "Evaluate the callback associate to the title given as parameter" (actionDictionary at: aTitleAsString) value: targetObject! ! !ROMenuElement methodsFor: 'initialization' stamp: 'AlexandreBergel 9/1/2012 23:35'! initialize super initialize. targetObject := self. actionDictionary := Dictionary new. ! ! !ROMenuElement methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2012 19:45'! item: aTitleAsString action: aBlock "Register a menu entry. The title is used as the entry name when the menu is displayed. The callback is defined as a one-arg block. The block is evaluated with the content of the variable targetObject" actionDictionary at: aTitleAsString put: aBlock! ! !ROMenuElement methodsFor: 'accessing computed' stamp: 'AlexandreBergel 9/1/2012 19:38'! numberOfActions "Return the number of actions" ^ actionDictionary size! ! !ROMenuElement methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2012 19:46'! targetObject ^ targetObject! ! !ROMenuElement methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2012 19:46'! targetObject: anObject "set the object that is passed to the callback blocks when being evaluated" targetObject := anObject! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 8/12/2013 18:47'! addElement: element elements add: element. callback addElement: element in: self! ! !ROContainer methodsFor: 'translating' stamp: 'AlexandreBergel 8/27/2013 21:47'! adjustSizeIfNecessary self subclassResponsibility ! ! !ROContainer methodsFor: 'enumerating' stamp: 'AlexandreBergel 6/10/2013 09:59'! allElementsDo: aBlockOrSymbol "Recursively perform an action for each elements." self elementsDo: [ :each | each withAllElementsDo: aBlockOrSymbol ]! ! !ROContainer methodsFor: 'accessing-attributes' stamp: 'AlexandreBergel 9/15/2013 00:41'! attributeAt: aKey ^ self attributes at: aKey! ! !ROContainer methodsFor: 'accessing-attributes' stamp: 'JurajKubelka 10/11/2013 15:41'! attributeAt: aKey ifAbsentPut: aBlockClosure ^ self attributes at: aKey ifAbsentPut: aBlockClosure ! ! !ROContainer methodsFor: 'accessing-attributes' stamp: 'AlexandreBergel 9/15/2013 00:45'! attributeAt: aKey put: value ^ self attributes at: aKey put: value! ! !ROContainer methodsFor: 'accessing-attributes' stamp: 'VanessaPena 12/22/2012 18:27'! attributes "Return the list of attributes associated to the element. Attributes are useful for caching values" ^ attributes ifNil: [ attributes := Dictionary new ]! ! !ROContainer methodsFor: 'hooks' stamp: 'AlexandreBergel 8/27/2013 21:34'! bounds self subclassResponsibility ! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 8/11/2013 21:44'! callback ^ callback! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 8/11/2013 21:44'! callback: rocontainercallback callback := rocontainercallback! ! !ROContainer methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 5/7/2013 14:47'! edgeFromModel: object "Recursively look for the element with a model object" | v | (self model = object) ifTrue: [ ^ self ]. v := elements detect: [ :e | (e model = object) and: [ e isEdge ] ] ifNone: [ nil ]. v ifNotNil: [ ^ v ]. elements do: [ :e | v := e elementFromModel: object. v ifNotNil: [ ^ v ] ]. ^ nil ! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 12/5/2012 18:30'! elementFromModel: object "Recursively look for the element with a model object" | v | (self model = object) ifTrue: [ ^ self ]. v := elements reverse detect: [ :e | (e model = object) and: [ e isElement ] ] ifNone: [ nil ]. v ifNotNil: [ ^ v ]. elements reverse do: [ :e | v := e elementFromModel: object. v ifNotNil: [ ^ v ] ]. ^ nil "^ (self elementsSuchThat: [ :el | object = el model ]) first"! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 22:30'! elements ^ elements copy asArray! ! !ROContainer methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 8/11/2013 22:01'! elementsAsEdge ^ elements select: #isEdge! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 12/3/2012 22:30'! elementsCollect: aBlock ^ elements collect: aBlock! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 12/3/2012 22:29'! elementsDo: aBlock ^ elements copy do: aBlock! ! !ROContainer methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 12/3/2012 22:29'! elementsNotEdge ^ elements reject: #isEdge! ! !ROContainer methodsFor: 'enumerating' stamp: 'AlexandreBergel 12/6/2012 16:51'! elementsReverseDo: aBlock ^ elements reverse do: aBlock! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 12/3/2012 22:29'! elementsSuchThat: aBlock ^ elements select: aBlock! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 12/3/2012 22:29'! elementsWithModelDo: aBlock ^ (elements copy select: [ :n | n model notNil ]) do: aBlock ! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 4/24/2013 09:21'! encompassingNestedRectangle elements isEmpty ifTrue: [ ^ Rectangle origin: self topLeft extent: self padding ]. ^ ((Rectangle merging: (self elementsNotEdge collect: #bounds)) translateBy: self topLeft) extendBy: self padding! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 4/19/2013 18:42'! encompassingRectangle elements isEmpty ifTrue: [ ^ self bounds ]. ^ Rectangle merging: (Array with: self encompassingNestedRectangle), (Array with: self bounds)! ! !ROContainer methodsFor: 'testing' stamp: 'JurajKubelka 5/16/2013 16:21'! hasAttribute: aKey "Return true if atribute is present" ^ attributes notNil and: [ attributes includesKey: aKey ]! ! !ROContainer methodsFor: 'testing' stamp: 'JurajKubelka 5/16/2013 16:18'! hasAttributes "Return true if at least one attributes is present" ^ attributes notNil and: [ attributes notEmpty ]! ! !ROContainer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 8/11/2013 21:38'! initialize super initialize. elements := OrderedCollection new. "Per default, the parent is always extensible" resizeStrategy := ROExtensibleParent instance. callback := ROContainerCallbackNull instance ! ! !ROContainer methodsFor: 'testing' stamp: 'JurajKubelka 4/22/2013 13:47'! isView ^ false! ! !ROContainer methodsFor: 'hooks' stamp: 'AlexandreBergel 5/7/2013 14:49'! model "Return the domain object that is behind the Roassal element. Could be nil" self subclassResponsibility ! ! !ROContainer methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 12/3/2012 22:29'! numberOfElements ^ elements size! ! !ROContainer methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 4/24/2013 09:23'! padding ^ resizeStrategy padding! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 8/11/2013 21:40'! remove: element "Remove the element from myself. However, the element is not removed from the visualization. Send #remove to element to actually remove it." elements remove: element. callback removeElement: element in: self! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 12/3/2012 22:29'! remove: element ifAbsent: aBlock elements remove: element ifAbsent: aBlock! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 8/11/2013 21:40'! removeAllElements elements := OrderedCollection new. callback removeAllElementsFrom: self! ! !ROContainer methodsFor: 'actions' stamp: 'JurajKubelka 5/16/2013 16:26'! removeAttribute: aKey self attributes removeKey: aKey! ! !ROContainer methodsFor: 'actions' stamp: 'AlexandreBergel 8/28/2013 13:58'! replace: element by: anotherElement "Replace an element by another. The position in the list of elements is preserved" | index oldElements | index := elements indexOf: element. oldElements := elements copy. element remove. self add: anotherElement. elements := oldElements. elements at: index put: anotherElement. callback removeElement: element in: self. callback addElement: anotherElement in: self! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 4/22/2013 19:20'! resizeStrategy "No reason to give the object itself" ^ resizeStrategy copy! ! !ROContainer methodsFor: 'accessing' stamp: 'AlexandreBergel 4/22/2013 19:20'! resizeStrategy: anInstanceOfROAbstractResizeStrategy resizeStrategy := anInstanceOfROAbstractResizeStrategy! ! !ROContainer methodsFor: 'hooks' stamp: 'AlexandreBergel 8/27/2013 21:34'! topLeft self subclassResponsibility ! ! !ROContainer methodsFor: 'translating' stamp: 'AlexandreBergel 4/29/2013 15:04'! translate: innerElement by: aPoint "Translate innerElement by aPoint amount of pixels" resizeStrategy translate: innerElement by: aPoint. self adjustSizeIfNecessary ! ! !ROView commentStamp: 'AlexandreBergel 3/6/2013 11:56' prior: 34307527! ROView is the main container of all Roassal objects. A view contains elements, typically instances of ROElement and ROEdges. It has also a camera that indicates what is currently visible. A view also contains animations that are currently operating. A view has a title, which is used when displayed in a window. ROView is an essential class. elementsToRender is the list of elements that are displayed. It contains a sorted collection of associations. Each association has a number of a key, and a collection of elements as a value. The key number corresponds to the zIndex. Elements with a low zIndex are displayed first. Instance Variables: camera eventHandler title backgroundColor animations <(Collection of: ROAnimation)> elementsToRender zOrdering Class Instance Variables: nullView ! !ROView class methodsFor: 'configuration'! defaultWindowTitle ^ 'Roassal visualization'! ! !ROView class methodsFor: 'initialize' stamp: 'AlexandreBergel 12/14/2012 14:08'! initialize self resetNullView ! ! !ROView class methodsFor: 'accessing' stamp: 'AlexandreBergel 1/10/2013 10:55'! nullView "Used when creating new element. For example, we have the relation: ROElement new view == ROView nullView" ^ nullView ifNil: [ nullView := self new ].! ! !ROView class methodsFor: 'public' stamp: 'AlexandreBergel 1/10/2013 10:55'! resetNullView nullView := nil! ! !ROView class methodsFor: 'public'! titled: aTitle "Create an instance of the view and set a title to it" ^ self new title: aTitle; yourself! ! !ROView methodsFor: 'interaction'! @ anInteractionClassOrInstance anInteractionClassOrInstance initializeElement: self ! ! !ROView methodsFor: 'accessing'! absolutePosition ^ 0 @ 0! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:47'! add: element "Add an element in the view. Do nothing if the element is already in" (element view ~~ ROView nullView) ifTrue: [ ^ self ]. element parent: self. element view: self. self addElementRecursivelyToRender: element. self addElement: element.! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 3/31/2013 11:43'! addAll: els "Add a collection of graphical objects in the view" self assert: [ els isKindOf: Collection ]. els do: [:n | self add: n ]! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/2/2013 19:23'! addAnimation: animation "Add an animation to the view. The animation takes effect as soon as it is added" animation addedIn: self. animations add: animation. self signalUpdate ! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 12/13/2012 14:46'! addElementRecursivelyToRender: element self addElementToRender: element. element allElementsDo: [ :el | self addElementToRender: el ]! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 5/7/2013 19:40'! addElementToRender: element element setZindexFrom: zOrdering. elementsToRender do: [ :assoc | (assoc key = element zIndex) ifTrue: [ assoc value add: element. ^ self ] ]. "We have found the key, so we need to add it" elementsToRender add: element zIndex -> (OrderedCollection with: element)! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 12/13/2012 14:49'! addElementsToRender: els els do: [ :el | self addElementToRender: el ]! ! !ROView methodsFor: 'accessing'! addFirst: element elements addFirst: element. element view: self! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 5/22/2012 00:42'! adjustSizeIfNecessary "do nothing"! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/2/2013 19:10'! animations "Return a copy of the animations" ^ animations copy! ! !ROView methodsFor: 'events'! announce: event eventHandler announce: event! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 5/22/2012 20:58'! backgroundColor ^ backgroundColor ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 5/22/2012 20:58'! backgroundColor: aColor backgroundColor := aColor! ! !ROView methodsFor: '*roassalmorphic-bitmap generation' stamp: 'AlexandreBergel 11/14/2012 12:14'! bitmap | canvas | canvas := self createCanvas. self drawOn: canvas. ^ canvas form! ! !ROView methodsFor: '*roassalmorphic-bitmap generation' stamp: 'AlexandreBergel 11/14/2012 12:14'! bitmapForElements: elementsToRender | canvas | canvas := self createCanvas. elementsToRender do: [ :n | n drawOn: canvas ]. ^ canvas form ! ! !ROView methodsFor: '*roassalmorphic-bitmap generation' stamp: 'VanessaPena 12/6/2012 23:05'! bitmapForEncompassingRectangle | formCanvas form canvas oldPosition rect| rect := self encompassingRectangle . form := Form extent: (rect extent + (5@5)) depth: Display depth. formCanvas := FormCanvas on: form. canvas := ROPharoCanvas canvas: formCanvas camera: self camera. canvas extent: (rect extent + (5@5)). oldPosition := self camera position. self translateTo: rect origin negated. self drawOn: canvas. self camera translateTo: oldPosition . ^canvas form! ! !ROView methodsFor: '*roassalmorphic-bitmap generation'! bitmapForRealSize: aPoint self camera realExtent: aPoint. ^ self bitmap! ! !ROView methodsFor: '*roassalmorphic-bitmap generation' stamp: 'AlexandreBergel 6/3/2012 15:29'! bitmapForSize: aPoint self camera realExtent: aPoint; extent: aPoint. ^ self bitmap! ! !ROView methodsFor: 'camera'! camera ^ camera! ! !ROView methodsFor: 'camera'! cameraTranslateBy: point camera translateBy: point. self signalUpdate! ! !ROView methodsFor: 'camera'! cameraTranslateByRealStep: aStep camera translateByRealStep: aStep. self signalUpdate! ! !ROView methodsFor: 'camera' stamp: 'AlexandreBergel 6/5/2012 00:29'! cameraTranslateTo: point camera translateTo: point. self signalUpdate! ! !ROView methodsFor: 'rendering'! canvasForRealSize: realSize ^ camera extent: realSize; realExtent: realSize; canvas! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 5/7/2013 19:39'! cleanRenderingElement "Check if some elements should be removed or added. This method is useful when the rendering queue has to be modified when being iterated." renderedElementsToBeRemoved size > 0 ifTrue: [ renderedElementsToBeRemoved do: [ :element | self removeElementToRender: element ]. renderedElementsToBeRemoved := OrderedCollection new ] . renderedElementsToBeAdded size > 0 ifTrue: [ renderedElementsToBeAdded do: [ :element | self addElementToRender: element ]. renderedElementsToBeAdded := OrderedCollection new ] . ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 15:22'! collectPathToRootIn: aCollection "Return the path from this graph to the root graph" aCollection addLast: self.! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/22/2013 18:17'! completeAllAnimations [ self numberOfAnimations > 0 ] whileTrue: [ self doAnimationCycle ]! ! !ROView methodsFor: '*roassalmorphic-bitmap generation' stamp: 'AlexandreBergel 11/14/2012 12:14'! createCanvas | formCanvas form | form := Form extent: camera realExtent depth: Display depth. formCanvas := FormCanvas on: form. ^ ROPharoCanvas canvas: formCanvas camera: self camera! ! !ROView methodsFor: 'opening'! defaultWindowSize ^ 500 @ 500! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/4/2012 08:45'! depth ^ 0! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 12/1/2012 10:58'! doAllAnimationCycles "This methos is useful in testing. It executes all the animation without actually displaying anything" [ self hasAnimation ] whileTrue: [ self doAnimationCycle ] ! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/19/2013 19:06'! doAnimationCycle animations notEmpty ifTrue: [ self signalUpdate ]. animations do: [ :e | e doCycle ]. animations := animations reject: #hasCompleted. ! ! !ROView methodsFor: 'rendering' stamp: 'MathieuDehouck 7/3/2013 15:17'! drawAllElementsOn: canvas canvas camera: self camera. self elementsDo: [ :n | n drawOn: canvas ]. self cleanRenderingElement! ! !ROView methodsFor: 'rendering' stamp: 'AlexandreBergel 5/7/2013 19:22'! drawElementsOn: canvas canvas camera: self camera. self elementsToRenderDo: [ :n | n drawOn: canvas ]. self cleanRenderingElement! ! !ROView methodsFor: 'rendering' stamp: 'MathieuDehouck 7/3/2013 15:16'! drawFullOn: canvas canvas paintBackground: backgroundColor. self drawAllElementsOn: canvas. self doAnimationCycle. ! ! !ROView methodsFor: 'rendering' stamp: 'AlexandreBergel 5/7/2013 19:12'! drawOn: canvas canvas paintBackground: backgroundColor. self drawElementsOn: canvas. self doAnimationCycle. ! ! !ROView methodsFor: 'rendering' stamp: 'MathieuDehouck 7/3/2013 15:31'! drawWithoutSettingCameraElementsOn: canvas self elementsDo: [ :n | n drawOn: canvas ].! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/13/2012 14:29'! elementAt: aPoint "The lookup has to be done in an order reversed from the display" self elementsToRenderReverseDo: [ :el | (el contains: aPoint) ifTrue: [ ^ el ] ]. ^ self! ! !ROView methodsFor: 'accessing'! elementAtRealPosition: aPoint "The lookup has to be done in an order reversed from the display" ^ self elementAt: (self camera realToVirtualPoint: aPoint) ! ! !ROView methodsFor: 'accessing'! elementDetect: aBlock ^ elements copy detect: aBlock! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 4/14/2012 18:33'! elementsFromModels: objects ^ (objects collect: [ :o | self elementFromModel: o ]) copyWithout: nil ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/13/2012 14:51'! elementsToRender "Return the number of elements that will be rendered" | answer | answer := OrderedCollection new. self elementsToRenderDo: [ :el | answer add: el ]. ^ answer asArray.! ! !ROView methodsFor: 'enumerating' stamp: 'AlexandreBergel 8/12/2013 14:15'! elementsToRenderDo: aBlock elementsToRender do: [ :assoc | assoc value do: aBlock ]! ! !ROView methodsFor: 'enumerating' stamp: 'AlexandreBergel 12/13/2012 14:56'! elementsToRenderReverseDo: aBlock elementsToRender reverse do: [ :assoc | assoc value reverse do: aBlock ] ! ! !ROView methodsFor: 'accessing' stamp: 'VanessaPena 1/5/2013 15:46'! encompassingRectangle "Return the encompassing rectangle of the view. All the elements are contained in this rectangle" | max maxPoint lowerPoint | elements isEmpty ifTrue: [ ^ 0@0 corner: 1@1 ]. max := 1000000. maxPoint := max negated @ max negated. lowerPoint := max @ max. self elementsDo: [ :el | maxPoint := maxPoint max: el bounds bottomRight. lowerPoint := lowerPoint min: el position ]. ^ lowerPoint corner: maxPoint! ! !ROView methodsFor: 'testing' stamp: 'AlexandreBergel 11/30/2012 17:27'! hasAnimation "Return true if some animations are present in the visualization" ^ animations notEmpty! ! !ROView methodsFor: 'initialize' stamp: 'AlexandreBergel 8/12/2013 14:15'! initialize super initialize. camera := ROCamera new. eventHandler := ROAnnouncer new. title := self class defaultWindowTitle. backgroundColor := Color white. animations := OrderedCollection new. zOrdering := ROZOrdering new. elementsToRender := OrderedCollection new. "We need the following two variables essentially because the rendering loop should _not_ be modified while we are drawing" renderedElementsToBeRemoved := OrderedCollection new. renderedElementsToBeAdded := OrderedCollection new. self on: ROWindowResized do: [ :event | self updateElementsToRender ]. self on: ROCameraTranslated do: [ :event | self updateElementsToRender ]. self on: ROCameraResized do: [ :event | self updateElementsToRender ].! ! !ROView methodsFor: 'testing' stamp: 'AlexandreBergel 4/18/2012 15:35'! is: aClass "Not sure whether this is important or not" ^ false! ! !ROView methodsFor: 'testing' stamp: 'AlexandreBergel 4/11/2013 15:10'! isRendered: anElement elementsToRender do: [ :assoc | (assoc value includes: anElement) ifTrue: [ ^ true ] ]. ^ false! ! !ROView methodsFor: 'testing' stamp: 'JurajKubelka 4/22/2013 13:47'! isView ^ true! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 9/25/2012 15:42'! localElementAt: aPoint "The lookup has to be done in an order reversed from the display" | el | el := (elements reverse detect: [ :e | e contains: (aPoint - e topLeft) ] ifNone: [ ^ self ]). ^ el elementAt: (aPoint - el topLeft) ! ! !ROView methodsFor: 'accessing'! localElementAtRealPoint: aPoint ^ self localElementAt: (camera realToVirtualPoint: aPoint)! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 6/10/2013 10:17'! makeAllElementAsRendered "Make all the elements as rendered." self allElementsDo: [ :el | el isRendered ifFalse: [ el setAsRendered ] ]. self cleanRenderingElement.! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 6/10/2013 09:24'! markAsToBeAdded: element "element will be added to the rendering queue at the next rendering" renderedElementsToBeAdded add: element. ! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 6/10/2013 09:24'! markAsToBeRemoved: element "element will be removed from the rendering queue at the next rendering" renderedElementsToBeRemoved add: element. ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 7/29/2012 09:20'! model "To be polymorphic with ROElement" ^ self ! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/2/2013 19:05'! numberOfAnimations ^ animations size! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/13/2012 14:48'! numberOfElementsToRender "Return the number of elements that will be rendered" | t | t := 0. self elementsToRenderDo: [ :el | t := t + 1 ]. ^ t! ! !ROView methodsFor: 'events' stamp: 'AlexandreBergel 4/18/2012 13:58'! on: event do: aBlock eventHandler when: event do: aBlock! ! !ROView methodsFor: 'events' stamp: 'AlexandreBergel 11/25/2012 10:50'! on: eventClass doOnce: aBlock "Register a block as an handler for eventClass. The callback is removed when exected" "interactions at: eventClass put: aBlock." eventHandler when: eventClass do: [ :arg | aBlock value: arg. eventHandler unsubscribeForEvent: eventClass. "self removeInteraction: eventClass "]! ! !ROView methodsFor: 'opening' stamp: 'AlexandreBergel 11/23/2012 08:34'! open ^ self openInWindowSized: self defaultWindowSize! ! !ROView methodsFor: 'opening' stamp: 'AlexandreBergel 7/25/2012 16:15'! openInWindowSized: aPoint ^ ROPlatform current widgetFactory forView: self windowSized: aPoint ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 11/28/2012 22:23'! position ^ 0 @ 0! ! !ROView methodsFor: 'accessing'! positionRelativeTo: anElement ^ 0 @ 0! ! !ROView methodsFor: 'rendering elements' stamp: 'AlexandreBergel 8/12/2013 14:16'! removeAllElementsToRender elementsToRender := OrderedCollection new.! ! !ROView methodsFor: 'animation' stamp: 'AlexandreBergel 5/2/2013 19:19'! removeAnimationSuchThat: aOneArgBlock "Remove all animations that satisfy the one-arg block passed as parameter" | animationsToRemove | animationsToRemove := animations select: aOneArgBlock. animations := animations copyWithoutAll: animationsToRemove! ! !ROView methodsFor: 'rendering elements' stamp: 'DennisSchenk 2/19/2013 13:03'! removeElementToRender: element elementsToRender do: [ :assoc | (assoc key = element zIndex) ifTrue: [ assoc value remove: element ifAbsent: [ ] ] ]. ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 6/2/2012 14:26'! resizeStrategy ^ ROFixedSizedParent instance! ! !ROView methodsFor: 'events' stamp: 'AlexandreBergel 7/9/2013 15:38'! signalUpdate "self updateElementsToRender." self announce: RORefreshNeeded instance! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 5/22/2012 13:55'! sortElementsWith: aTwoArgBlock elements sort: aTwoArgBlock ! ! !ROView methodsFor: 'accessing'! title ^ title! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 7/6/2012 13:58'! title: aString "Set the title of the view. Useful when opening up a window" title := aString! ! !ROView methodsFor: 'camera' stamp: 'VanessaPena 1/5/2013 17:35'! translateBy: point self cameraTranslateBy: point negated. self announce: (ROCameraTranslated new step: point negated).! ! !ROView methodsFor: 'camera'! translateByRealPoint: aPoint | p1 p2 | p1 := self camera position. p2 := self camera realToVirtualPoint: aPoint. self translateBy: (p2 - p1). ! ! !ROView methodsFor: 'camera' stamp: 'AlexandreBergel 6/5/2012 00:30'! translateTo: point self cameraTranslateTo: point negated! ! !ROView methodsFor: 'rendering' stamp: 'AlexandreBergel 10/20/2013 15:31'! updateElementsToRender | origin corner b | elementsToRender := SortedCollection new. origin := camera position. corner := camera windowSize / camera scale. b := origin corner: origin + corner. elements do: [ :e | (e isVisibleIn: b) ifTrue: [ self addElementRecursivelyToRender: e ] ].! ! !ROView methodsFor: 'accessing'! view ^ self ! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 11/15/2012 15:11'! windowSize: anExtent "Tell the camera what is the size of the window that contains me" | oldExtent | oldExtent := self camera windowSize. self camera windowSize: anExtent. self announce: (ROWindowResized new oldExtent: oldExtent; extent: anExtent)! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/10/2012 19:01'! zOrdering ^ zOrdering! ! !ROView methodsFor: 'accessing' stamp: 'AlexandreBergel 12/13/2012 15:11'! zOrdering: aZOrdering "Dedicated object to assign zIndex to graphical elements" | oldEls | zOrdering := aZOrdering. oldEls := self elementsToRender. elementsToRender := SortedCollection sortBlock: [ :a :b | a key < b key ]. self addElementsToRender: oldEls ! ! !ROViewStack methodsFor: 'accessing'! addFirst: aView views addFirst: aView. self announce: (ROViewChanged new newView: aView).! ! !ROViewStack methodsFor: 'accessing'! addLast: aView views addLast: aView. self announce: (ROViewChanged new newView: aView).! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/4/2013 08:42'! addMenu: aButtonTitle callBack: aBlock | label | label := ROLabel elementOn: aButtonTitle. label @ ROLightlyHighlightable lightGray + ROBorder gray + ROBox white. label on: ROMouseLeftClick do: [ :event | ROBlink unhighlight: label. label view signalUpdate. aBlock roValue: self ]. self add: label. ROHorizontalLineLayout on: self elements! ! !ROViewStack methodsFor: 'accessing'! addView: aView self addLast: aView! ! !ROViewStack methodsFor: 'rendering' stamp: 'AlexandreBergel 5/18/2013 07:57'! drawOn: aROCanvas self viewReverseDo: [ :v | v drawOn: aROCanvas ]. self drawElementsOn: aROCanvas. self doAnimationCycle. ! ! !ROViewStack methodsFor: 'accessing' stamp: 'AlexandreBergel 4/30/2012 17:36'! elementAtRealPosition: aPoint "Override of the superclass. If nothing is found in myself, then we look in the embedded views" | t el | el := self elementAt: (self camera realToVirtualPoint: aPoint). (el == self) ifTrue: [ self viewDo: [ :v | ^ v elementAtRealPosition: aPoint ] ] ifFalse: [ ^ el ]. ^ self ! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/3/2013 18:09'! exportButton self addMenu: 'Export' callBack: [ :stack | | exporters index| exporters := SortedCollection sortBlock: [ :a1 :a2 | a1 key < a2 key ]. ROExportCommand commands do: [:cm | exporters add: cm name -> cm ] . index := UIManager default chooseFrom: (exporters collect: #key). index > 0 ifTrue: [ (exporters at: index) value executeOn: self firstView ] ]! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/3/2013 18:10'! findButton self addMenu: 'Find...' callBack: [ :stack | | allModels index element | allModels := SortedCollection sortBlock: [ :a1 :a2 | a1 value < a2 value ]. stack firstView elementsDo: [ :el | el isNotEdge ifTrue: [ allModels add: el -> el model printString ] ]. index := UIManager default chooseFrom: (allModels collect: #value). index > 0 ifTrue: [ element := (allModels at: index) key. ROFocusView on: element ] ].! ! !ROViewStack methodsFor: 'accessing'! firstView ^ views first! ! !ROViewStack methodsFor: 'initialize'! initialize super initialize. views := OrderedCollection new. ! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/4/2013 08:47'! moveFirstViewBelowButtons self firstView translateBy: 0 @ 30 "We also do a small scrolling to not have the buttons over the nodes"! ! !ROViewStack methodsFor: 'interactions'! on: eventClass do: aBlock super on: eventClass do: aBlock. self viewDo: [ :v | v on: eventClass do: aBlock ]! ! !ROViewStack methodsFor: 'accessing' stamp: 'VanessaPena 1/8/2013 11:19'! removeFirst views removeFirst. self announce: (ROViewChanged new newView: views first).! ! !ROViewStack methodsFor: 'accessing' stamp: 'AlexandreBergel 7/9/2013 10:27'! replaceFirstBy: view | size | size := views first camera windowSize. views removeFirst. view camera windowSize: size. self addFirst: view ! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/3/2013 18:10'! serializeButton self addMenu: 'Save/Open' callBack: [ :stack | | commands index saveCommand loadCommand| commands := SortedCollection sortBlock: [ :a1 :a2 | a1 key < a2 key ]. saveCommand := ROSaveViewCommand on: self firstView. loadCommand := ROLoadViewCommand new. commands add: ('Save view as...' -> [ saveCommand execute ] ). commands add: ('Open...' -> [loadCommand execute. loadCommand view ifNil: [ ^ self ]. loadCommand view open ]). index := UIManager default chooseFrom: (commands collect: #key). index > 0 ifTrue: [ (commands at: index) value value ] ]! ! !ROViewStack methodsFor: 'rendering' stamp: 'AlexandreBergel 7/9/2013 10:28'! updateElementsToRender self viewDo: [ :v | v updateElementsToRender ]! ! !ROViewStack methodsFor: 'accessing' stamp: 'AlexandreBergel 7/9/2013 10:28'! viewDo: aBlock views isNil ifFalse: [ views do: [:v | aBlock value: v ] ]! ! !ROViewStack methodsFor: 'opening' stamp: 'VanessaPena 1/8/2013 10:50'! viewReverseDo: aBlock views reverseDo: [:v | aBlock value: v ]. ! ! !ROViewStack methodsFor: 'accessing' stamp: 'VanessaPena 1/8/2013 10:33'! viewsSize ^views size! ! !ROViewStack methodsFor: 'accessing' stamp: 'AlexandreBergel 11/14/2012 13:51'! windowSize: anExtent super windowSize: anExtent. views do: [ :v | v windowSize: anExtent ]! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/3/2013 18:10'! zoomInButton self addMenu: 'Zoom in' callBack: [ :stack | ROZoomInMove new on: stack firstView ].! ! !ROViewStack methodsFor: 'buttons' stamp: 'AlexandreBergel 7/3/2013 18:11'! zoomOutButton self addMenu: 'Zoom out' callBack: [ :stack | ROZoomOutMove new on: stack firstView ].! ! !ROContainerCallback class methodsFor: 'instance creation' stamp: 'AlexandreBergel 8/11/2013 17:49'! instance ^ self new! ! !ROContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 8/12/2013 18:47'! addElement: element in: parentElement self subclassResponsibility ! ! !ROContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:07'! childrenHasBeenResized: container "One of my children has been resized" self subclassResponsibility! ! !ROContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 15:51'! element: element resizedTo: aPoint self subclassResponsibility ! ! !ROContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 21:40'! removeAllElementsFrom: anElement self subclassResponsibility ! ! !ROContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 17:46'! removeElement: element in: parentElement self subclassResponsibility ! ! !ROContainerCallbackLayout class methodsFor: 'public' stamp: 'AlexandreBergel 8/11/2013 17:48'! for: aLayout ^ self new layout: aLayout; yourself! ! !ROContainerCallbackLayout methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:21'! addElement: element in: parentElement element callback: self. self doLayoutIn: parentElement! ! !ROContainerCallbackLayout methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:13'! childrenHasBeenResized: container "One of my children has been resized" self doLayoutIn: container. container isView ifFalse: [ container parent callback childrenHasBeenResized: container parent ]! ! !ROContainerCallbackLayout methodsFor: 'util' stamp: 'AlexandreBergel 8/11/2013 21:47'! doLayoutIn: element layout on: element elements! ! !ROContainerCallbackLayout methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:12'! element: anElement resizedTo: aPoint self doLayoutIn: anElement. anElement parent callback childrenHasBeenResized: anElement parent "anElement parent callback element: anElement resizedTo: aPoint"! ! !ROContainerCallbackLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 8/11/2013 21:45'! layout ^ layout! ! !ROContainerCallbackLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 8/11/2013 21:45'! layout: aLayout layout := aLayout! ! !ROContainerCallbackLayout methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 21:47'! removeAllElementsFrom: anElement self doLayoutIn: anElement! ! !ROContainerCallbackLayout methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 21:47'! removeElement: element in: parentElement self doLayoutIn: parentElement! ! !ROContainerCallbackNull class methodsFor: 'instance creation' stamp: 'AlexandreBergel 8/11/2013 17:49'! instance "Singleton pattern" instance ifNil: [ instance := self new ]. ^ instance! ! !ROContainerCallbackNull methodsFor: 'calling' stamp: 'AlexandreBergel 8/12/2013 18:47'! addElement: element in: parentElement "do nothing"! ! !ROContainerCallbackNull methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:07'! childrenHasBeenResized: container "One of my children has been resized" "do nothing"! ! !ROContainerCallbackNull methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 15:51'! element: anElement resizedTo: aPoint "do nothing"! ! !ROContainerCallbackNull methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 21:41'! removeAllElementsFrom: anElement "do nothing"! ! !ROContainerCallbackNull methodsFor: 'calling' stamp: 'AlexandreBergel 8/11/2013 17:47'! removeElement: element in: parentElement "do nothing"! ! !ROPluggableContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/1/2013 12:16'! addElement: element in: parentElement addingBlock value: element! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:13'! addingBlock ^ addingBlock! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:13'! addingBlock: anObject addingBlock := anObject! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/2/2013 19:08'! childrenHasBeenResized ^ childrenHasBeenResized! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/2/2013 19:08'! childrenHasBeenResized1: anObject childrenHasBeenResized := anObject! ! !ROPluggableContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/2/2013 19:08'! childrenHasBeenResized: container "One of my children has been resized" childrenHasBeenResized value: container! ! !ROPluggableContainerCallback methodsFor: 'initialize-release' stamp: 'AlexandreBergel 9/2/2013 19:09'! initialize | b | super initialize. "Empty blocks" b := [ :v | v ]. addingBlock := b. removingBlock := b. removingAllBlock := b. childrenHasBeenResized := b! ! !ROPluggableContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/1/2013 12:31'! removeAllElementsFrom: element removingAllBlock value: element! ! !ROPluggableContainerCallback methodsFor: 'calling' stamp: 'AlexandreBergel 9/1/2013 12:17'! removeElement: element in: parentElement removingBlock value: element! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:30'! removingAllBlock ^ removingAllBlock! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:30'! removingAllBlock: anObject removingAllBlock := anObject! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:13'! removingBlock ^ removingBlock! ! !ROPluggableContainerCallback methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 12:13'! removingBlock: anObject removingBlock := anObject! ! !RODummyNode commentStamp: '' prior: 34308481! A RODummyNode is used by the sugiyama layout! !RODummyNode class methodsFor: 'instance creation' stamp: 'AlexandreBergel 5/3/2012 19:18'! on: anEdge slot: anIndex ^(self new) edge: anEdge; slot: anIndex; yourself! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! edge ^edge! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! edge: anEdge edge := anEdge! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! height ^0! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/20/2012 19:15'! position ^ 0 @ 0! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/20/2012 19:16'! signalUpdate "do nothing"! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! slot: anIndex ! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/20/2012 19:16'! translateBy: apoint "do nothing"! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! translateTo: aPoint "edge index: index point: aPoint"! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 4/13/2013 22:14'! view ^ ROView new! ! !RODummyNode methodsFor: 'accessing' stamp: 'AlexandreBergel 5/3/2012 19:18'! width ^0! ! !ROEaselMorphic commentStamp: 'AlexandreBergel 8/21/2012 11:05' prior: 34308601! A ROEaselMorphic describes the Pharo version of the easel. To create an icon: ThemeIcons createIconMethodsFromFile: 'ObjectProfileLogo' directory: '/Users/alexandrebergel/Documents/ObjectProfile/Logos/' ! !ROEaselMorphic class methodsFor: 'menu' stamp: 'AlexandreBergel 6/18/2012 16:03'! menuCommandOn: aBuilder (aBuilder item: #'RoassalEasel') order: 0.1; parent: #Tools; label: 'Roassal Easel'; icon: self roassalWithTransparentIcon; action:[ ROEaselMorphic open]! ! !ROEaselMorphic class methodsFor: 'public' stamp: 'AlexandreBergel 5/1/2012 17:45'! open ^ self new open! ! !ROEaselMorphic class methodsFor: 'logo' stamp: 'AlexandreBergel 5/1/2012 17:57'! readme " Doit to import a new icon in .png ThemeIcons createIconMethodsFromFile: 'RoassalWithTransparent' directory: '/Users/alexandrebergel/Documents/ObjectProfile/Logos' "! ! !ROEaselMorphic class methodsFor: 'logo' stamp: 'AlexandreBergel 5/1/2012 17:56'! roassalWithTransparentIcon "Private - Generated method" ^ icon ifNil: [ icon := Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self roassalWithTransparentIconContents readStream) ].! ! !ROEaselMorphic class methodsFor: 'logo' stamp: 'AlexandreBergel 5/1/2012 17:55'! roassalWithTransparentIconContents "Private - Method generated with the content of the file /Users/alexandrebergel/Documents/ObjectProfile/Logos/RoassalWithTransparent.png" ^ 'iVBORw0KGgoAAAANSUhEUgAAAA0AAAAYCAYAAAAh8HdUAAAACXBIWXMAAAsTAAALEwEAmpwY AAABrklEQVQ4jc2TP0+TURSHn99tQwxYXQATmtc/pHXQtthCCImbA4mJRh3o6ICTX8AY/ALK 5OjqwASMEEg0JITAIIJvMMYoW6kaJRLSxKHw3uNQLW2JRpz4JWc4957n3HPPPVdmxlHljkwc fyh+aCUXZDF/FyMPnAVLgL4A85xy4yyXvh9AV4IkUTQBDICeI8ZRfBNF3Xh/A+MRFT8IXJOZ Qd/5C/jqCmgV3BhGmrel6aYKsj0zGNeJdSVqd/J790HTbJRvgh+DaIpCuqu5blWACmH441d5 bpbO1BJgYGdAn1n7+K0enw/SGLeRHgCmlokQ2eQOsEhnW5Ht/SGwYbAiTg8Jt6agteX5IIXZ acQq29UXWLQAPiBov/wbOAx5PwCA6TUxjSKFmIY4md9vDGuGIqtB7sQr3mx9wHgMluL90r0/ Q6IfqUS4+RWAS1cnQeuYnlDoPQdAMdPW2AiR6dlFeslG+U49UV+yQMQK2CfEU0wp17B5EUgg 1ptOD8trxNwthAHDxOPPDsYochnwVaR3tCoszQG9dd/MajYyErNcrqPu/8VaH/efdMx/7n9B PwE6FbKAkaTh8gAAAABJRU5ErkJggg=='! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 7/14/2012 14:33'! adjustRoassalWindow: aSystemWindow aSystemWindow bounds: self defaultRoassalBounds! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 7/14/2012 14:32'! adjustWorkspaceWindow: aSystemWindow aSystemWindow bounds: self defaultWorkspaceBounds! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 7/14/2012 18:18'! changeView: view forExampleMethod: aCompiledMethod "aCompiledMethod is a method that belongs to an example class" | builder sourceCode | self fadeAwayView: view. sourceCode := self getExampleSourceFor: aCompiledMethod. CurrentWorkspace setContent: sourceCode. CurrentWorkspace changed. self openViewFor: sourceCode! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'VanessaPena 11/29/2012 18:03'! close "Remove the windows" workspaceWindow ifNotNil: [ workspaceWindow delete ]. roassalWindow ifNotNil: [ roassalWindow delete ].! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 3/30/2013 21:56'! createWorkspace CurrentWorkspace := Workspace new. CurrentWorkspace contents: self templateScript. CurrentWorkspace openLabel: 'Roassal Easel Script'. ^ CurrentWorkspace acceptAction: [ :str | self openViewFor: str ]! ! !ROEaselMorphic methodsFor: 'configuration' stamp: 'AlexandreBergel 7/14/2012 14:33'! defaultRoassalBounds ^ (89.0@22.0) corner: (740.0@555.0) ! ! !ROEaselMorphic methodsFor: 'configuration' stamp: 'AlexandreBergel 7/14/2012 14:33'! defaultWorkspaceBounds ^ (746.0@23.0) corner: (1196.0@293.0)! ! !ROEaselMorphic methodsFor: 'buttons and menu' stamp: 'AlexandreBergel 7/4/2013 08:53'! exampleButtonOn: aStack aStack addMenu: 'Example...' callBack: [ :s | | v | v := ROView new. v @RODraggable @ RODraggableWithVelocity. self showExamplesOnView: v. s replaceFirstBy: v. v translateBy: 0@30. ].! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'RobertoMinelli 10/17/2013 09:34'! extraPackageIsInstalled ^ (SystemOrganization categories includes: #'RoassalExtras')! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 5/19/2013 14:55'! fadeAwayView: view " 60 timesRepeat: [ view translateBy: -8 @ 0. World refreshWorld ]"! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 5/7/2013 13:53'! getExampleSourceFor: compiledMethod "This method transform the compiled method source code into a runnable example for the Easel" | sourceCode completeSourceCode cleanedSourceCode | sourceCode := compiledMethod sourceCode. cleanedSourceCode := self removeHeadingOf: sourceCode. completeSourceCode := (self scriptPreambuleForMethod: compiledMethod), cleanedSourceCode, (self postScriptForMethod: compiledMethod). ^ completeSourceCode! ! !ROEaselMorphic methodsFor: 'string manipulation' stamp: 'AlexandreBergel 7/14/2012 16:02'! getRawTempStringOf: sourceCode | l | l := sourceCode lines second. l trimBoth isEmpty ifTrue: [ ^ '' ]. ^ (l trimBoth first = $|) ifTrue: [ l ] ifFalse: [ '' ] ! ! !ROEaselMorphic methodsFor: 'string manipulation' stamp: 'AlexandreBergel 7/14/2012 14:26'! getTempStringOf: sourceCode ^ (self getRawTempStringOf: sourceCode) trimBoth! ! !ROEaselMorphic methodsFor: 'string manipulation' stamp: 'AlexandreBergel 7/14/2012 14:30'! getTempsOf: sourceCode | tempString | tempString := self getTempStringOf: sourceCode. ^ (tempString copyWithout: $|) substrings! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 5/21/2012 21:49'! getWindowOf: aBlock "Evaluate the block, and return the window that has been created. Convenient when opening a workspace" | allWindows r | allWindows := SystemWindow allInstances. aBlock value. r := SystemWindow allInstances copyWithoutAll: allWindows. ^ r isEmpty ifTrue: [ nil ] ifFalse: [ r anyOne ]! ! !ROEaselMorphic methodsFor: 'buttons and menu' stamp: 'AlexandreBergel 7/4/2013 08:53'! infoButtonOn: aStack aStack addMenu: 'Info...' callBack: [ :stack | | v lbl1 lbl2 lbl3 logoPanel logo1 logo2 arr | v := ROView new. v add: (lbl1 := ((ROLabel elementOn: self roassalDescription))). v add: (logoPanel := (ROElement new)). logoPanel add: (logo1 := (ROElement new + (ROImage new form: self roassalIcon))). logoPanel add: (logo2 := (ROElement new + (ROImage new form: self objectprofileIcon))). ROHorizontalLineLayout on: (Array with: logo1 with: logo2). logo2 translateBy: 50@0. v add: (lbl2 := ((ROLabel elementOn: self thanks))). v add: (lbl3 := ((ROLabel elementOn: self license))). arr := OrderedCollection new. arr add: lbl1; add: logoPanel; add: lbl2; add: lbl3. logo1 forward. logo2 forward. ROVerticalLineLayout on: arr. arr do: #forward. stack replaceFirstBy: v. v translateBy: 0@30. v @ RODraggable @ RODraggableWithVelocity ].! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 5/29/2012 09:04'! license ^ ' Copyright (c) 2011-2012 ObjectProfile.com. Roassal is distributed under the MIT license Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.'! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 5/29/2012 09:12'! objectprofileIcon ^ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self objectprofileIconContents readStream)! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 8/21/2012 10:59'! objectprofileIconContents "Private - Method generated with the content of the file /Users/alexandrebergel/Documents/ObjectProfile/Logos//ObjectProfileLogo.png" ^ 'iVBORw0KGgoAAAANSUhEUgAAAKwAAAC9CAIAAACh2QGxAAAKtmlDQ1BJQ0MgUHJvZmlsZQAA SA2tlndUU9kWh8+96Q0IgUgn9I4U6dJrKNKrqIQkEFqMIUFA7AyOwFgQkaKiyKCAgqNSZCyI KLZBUQH7BBlU1HGwYENlbuARZ7315r931trnfPd3dvbdZ+eetTYA5HqWQJAJKwCQxRcJI/y9 GHHxCQzcA4AD6oAI6ADNYmcLPMPCgsG/jvdDAJJu3rKQxvpXt/+9QeVws9kAQGHIdjInm52F 8AnEStkCoQgAlAei668UCaTMQVhJiCSIcK6UU2e5VMrJs7xvxicqwhvxQeLgySyWMBUAUjei M3LYqUgckgRhKz4njQ8AGTk5cGPzWEhssjQH86ys5VIuQNg4+R9xUv/BLFayLCaLlSrj2bMg v0Re7JOWLchk5c08/D+nrEwxUq+ZoYXM5OyMyCBkVUJqlstm+UbOMY/LlP5nM7pA5BUxx2ki ZtQc88QB0XMszoj2nOOM5UEyf37yotA5nZ3tjdR+NmY+Lyp2jjlcH985Fi6PkPln50TK9Hye 96I5n3RWoLTWM7mxhAj9h7mZ/rL3CkRhsjz5mYtkZ0kR+sl8uNnfzyviRQXMxREJo2Q+KWl+ zDmdJwyQ6YLMmW96JgehOEJWBy4/WlZDDstHVlsQCfIAH7BBCGCBbCACXCAUcXNF0uS9lwvy hGmpPBHDE7kBXHMGk8+2NGfYWFnbAOl9kvoA8PbOzD2B6PjvmgDRnajIt9rzXUt2AKCjGgBV 6ndNvxYAeSTH9gS2WJgzEw6gpQsGuaXySCVVgRbQA8bAAtgAe+ACPIAvCAShIArEg6VI1jyQ BYRgJSgA60ERKAHbwE5QDWrBAXAIHAHHQAc4Bc6Bi+AquAEGwX0gAWPgBZgA78EUBEE4iALR IFVIGzKAzCAbyBFyg3yhYCgCioeSoFSID4mhAmgjVAKVQdXQfqgR+gU6CZ2DLkMD0F1oBBqH 3kCfYRRMhpVgTdgQng87wp5wEBwFL4FT4RVwPlwIb4Er4Tr4MNwOn4OvwoOwBH4BT6IAioSi o3RQFihHlDcqFJWASkEJUWtQxagKVB2qBdWF6kPdQklQL1Gf0Fg0Dc1AW6Bd0AHoaDQbvQK9 Bl2KrkYfQreje9G30CPoCfQ3DAWjgTHDOGOYmDhMKmYlpghTgWnAtGEuYAYxY5j3WCyWjjXC OmADsPHYdOwqbCl2D7YV240dwI5iJ3E4nCrODOeKC8WxcCJcEa4Kdxh3FncTN4b7iCfhtfE2 eD98Ap6P34CvwDfhz+Bv4p/ipwgKBAOCMyGUwCHkEbYS6gldhOuEMcIUkUo0IroSo4jpxPXE SmIL8QLxAfEtiUTSJTmRwklppHWkStJR0iXSCOkTWZFsSvYmJ5LF5C3kg+Ru8l3yWwqFYkjx oCRQRJQtlEbKecojykc5mpylHFOOI7dWrkauXe6m3Ct5gryBvKf8Uvl8+Qr54/LX5V8qEBQM FbwVWAprFGoUTioMK0xSaVRraig1i1pKbaJepj5TxCkaKvoqchQLFQ8onlccpaFoejRvGpu2 kVZPu0AbU8IqGSkxldKVSpSOKPUrTSgrKi9QjlHOVa5RPq0soaPohnQmPZO+lX6MPkT/PE9z nuc87rzN81rm3Zz3QUVdxUOFq1Ks0qoyqPJZlaHqq5qhul21Q/WhGlrNVC1cbaXaXrULai/V ldRd1NnqxerH1O9pwBqmGhEaqzQOaFzTmNTU0vTXFGhWaZ7XfKlF1/LQStcq1zqjNa5N03bT TtMu1z6r/ZyhzPBkZDIqGb2MCR0NnQAdsc5+nX6dKV0j3WjdDbqtug/1iHqOeil65Xo9ehP6 2voh+gX6zfr3DAgGjgY8g10GfQYfDI0MYw03GXYYPjNSMWIa5Rs1Gz0wphi7G68wrjO+bYI1 cTTJMNljcsMUNrUz5ZnWmF43g83szdLM9pgNmGPMncz55nXmwxZkC0+LHItmixFLumWw5QbL DstX8/XnJ8zfPr9v/jcrO6tMq3qr+9aK1oHWG6y7rN/YmNqwbWpsbttSbP1s19p22r5eYLaA u2Dvgjt2NLsQu012PXZf7R3shfYt9uMO+g5JDrsdhh2VHMMcSx0vOWGcvJzWOp1y+uRs7yxy Pub8l4uFS4ZLk8uzhUYLuQvrF4666rqyXPe7StwYbklu+9wk7jruLPc698ceeh4cjwaPp54m numehz1feVl5Cb3avD54O3uv9u72Qfn4+xT79Psq+kb7Vvs+8tP1S/Vr9pvwt/Nf5d8dgAkI CtgeMMzUZLKZjcyJQIfA1YG9QeSgyKDqoMfBpsHC4K4QOCQwZEfIg0UGi/iLOkJBKDN0R+jD MKOwFWG/hmPDw8Jrwp9EWEcURPRF0iKXRTZFvo/yitoadT/aOFoc3RMjH5MY0xjzIdYntixW Ejc/bnXc1Xi1+LT4zgRcQkxCQ8LkYt/FOxePJdolFiUOLTFakrvk8lK1pZlLTy+TX8ZadjwJ kxSb1JT0hRXKqmNNJjOTdydPsL3Zu9gvOB6ccs4415Vbxn2a4ppSlvIs1TV1R+o4z51XwXuZ 5p1WnfY6PSC9Nv1DRmjGwYzpzNjM1ix8VlLWSb4iP4Pfu1xree7yAYGZoEggWeG8YueKCWGQ sCEbyl6S3SlSQhqXa2Jj8Q/ikRy3nJqcjytjVh7Ppebyc6/lmeZtznua75f/8yr0KvaqngKd gvUFI6s9V+9fA61JXtOzVm9t4dqxdf7rDq0nrs9Y/9sGqw1lG95tjN3YVahZuK5w9Af/H5qL 5IqERcObXDbV/oj+Me3H/s22m6s2fyvmFF8psSqpKPlSyi698pP1T5U/TW9J2dK/1X7r3m3Y bfxtQ9vdtx8qo5bll43uCNnRXs4oLy5/t3PZzssVCypqdxF3iXdJKoMrO6v0q7ZVfanmVQ/W eNW07tbYvXn3hz2cPTf3euxtqdWsLan9vC9t3539/vvb6wzrKg5gD+QceFIfU9/3s+PPjQ1q DSUNXw/yD0oORRzqbXRobGzSaNraDDeLm8cPJx6+ccTnSGeLRcv+VnpryVFwVHz0+S9Jvwwd CzrWc9zxeMsJgxO722htxe1Qe177RAevQ9IZ3zlwMvBkT5dLV9uvlr8ePKVzqua08umtZ4hn Cs9Mn80/O9kt6H55LvXcaM+ynvvn487f7g3v7b8QdOHSRb+L5/s8+85ecr106rLz5ZNXHK90 XLW/2n7N7lrbb3a/tfXb97dfd7jeecPpRtfAwoEzN91vnrvlc+vibebtq4OLBgeGoofuDCcO S+5w7jy7m3n39b2ce1P31z3APCh+qPCw4pHGo7rfTX5vldhLTo/4jFx7HPn4/ih79MUf2X98 GSt8QnlS8VT7aeMzm2enxv3Gbzxf/HzsheDF1MuiP6l/7n5l/OrEXx5/XZuImxh7LXw9/ab0 rerbg+8WvOuZDJt89D7r/dSH4o+qHw99cvzU9zn289OplV9wXyq/mnzt+hb07cF01vS0gCVk zfQCKGSGU1IAeHMQAEo8ALQbABDlZvvdGQ9otkdHWNqrS006/otne+KZHXsADnQDEOUBQDCy Vq0DwBAxeeQ5DDFEh21tZQZmR3aKrc0MQaQOpDWpmJ5+i/SIOBMAvg5PT091TE9/bUB6nXsA dL+f7bOl3sEWiKYT5mvt1Is+nD8b6fv8N5Gw9E45PgU9AAABnWlUWHRYTUw6Y29tLmFkb2Jl LnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0i WE1QIENvcmUgNS4xLjIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMu b3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9u IHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUu Y29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xNzI8L2V4 aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTg5 PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwv cmRmOlJERj4KPC94OnhtcG1ldGE+CgyyweUAADj6SURBVHgB7Z15mCRHdeArj7q6qu97eu57 JI2kGd3IEqfEisU2lzG2Ob61DSy7GNYYf+tdY4zPlY/18dkf5g/sNRZe28AasV6wQAiMBJIl dI+kue/p6emruqu67spjf1Gpzs6uIzOrunqmpt3J0IqKePHixYsXL168uCTTNAPr379tDsj/ tqu/XnvBgXUhWJeDdSFYl4FAQF17TMDKkSRRLZP/iT9YPcRIpmmUK+tpA0lkAj4QkETGgAjw T2AQoTLqtcW1tSYEupk1jLxuFA2zFJBKJX3BNEu6mdf1omamaDv+utvCqtQhS+GAJIeULikQ lOWIEogqcocUUBQ5zE9Vjq8tGVhzmmAu+8x87umiPkc7GaYpBxT6cLlnC7XA59mVbUVSBhd6 xAwY4DBMQ5Wj8dCuse53SdKasqXWmiZQpe68llCkIE2o2Jq7HLB/Wa1b7295IFhKFMNA2XJS ZQntwpiyxiSAql4VEm3CfU3PaPqCGONdv3hkqypFXEGaTCwPIlI8ssszvxnQTVPzJNUTz2UD aF9NUDbKGM8zJWM+r03kSxdD6mBf9BZZCrlwR5YikeDGTPGULCkuYM0lMS50BLd45p3PPp8t ne2OHoiqo7IUlFaBEk8aGgJoTyGg1+mi7UvTNH9Bn8IoQysXSrNGpOAuBJKkxsNbM8XjjAYN McIHsBlVh4NKpzukZqQn049M5x6NLIz0d9zZ13FDPLRPlhhMxAjVnl97CQEjLro0r12iJxVK Cd3MyPIS+8xAHuNfDbg1A+N3WBldjWFbN7R46Bp3EaSNS/pssngoKHXqRuZS+p9mct+Nqzs7 w3tGu35UkUNSW1ri7SMEzOKLOe1SpnCyZDCvy2OvwLWKrpPJXwjHhsoT94qUpZ/h4EBI6S9o iRaPCJIZDY+4Fy2EwMgZeo4JJmE5EGFqmtQPpYqHZ7OP98fuGordHVR6UQyeeJbqs/qhdhAC UzcLaP5MkeafYU5WdszUJEwuGJcYKioM+AouqXJ3UBnIa1MtHBGwBnAbBOWeirIqfqLJ5nJP 42Ow48s6SaZSudLkePLLU5lHhmJvGOh4TSQ43D5aoSav7SqsekAofwZ+/VymcJbCBMuEq672 R9uLSVqgJAXCtSHKsSgAVYmJxdG6mFxy104yDC0S3hRW+msnL8bqZm4m/b0acy5IL9erWJq7 MP/387nnB2Ov7eu4RZU7y1phMf8V+u8VFAJTMzKp/OG8dhGPnm9eGJni2c7wbnd2dQZ3LqhH TYMxpTWCIEGfFJe8jLuiniqZOReLRJJlSYqki8czpROTC98cir9+uPNNkoStsKQ83Ku2GqlX oGz0uREoZUvnpzOP5rQzhlH0LQHMvfVc6YInI+KRPSGlV5TTik94CMwgpoYnsnThZQYOd7Dy cKYGTDmrnT87/79fmfrddOGEbhTcc61q6uUWAnikGfOp3KHZ7L8aZgbNSedooIZ0bMkwhCvG 7WM+JrfODi+7B4a6I9e6FVlOm87+IBDQPcEEgBgfVPRUKn/08PTvnE9+qahPmwGPevnC3DhQ Iw3QOPaKHDRepnAKTqEPy6Z7E6VLup7NlyYrMFf/jId3mi3TsaYidalyV3UpzpiSNl/QZ1xs GiewHZZlBV04kXrw8OT90+lHDbMgFM/l/ZpohmYIRJ/qRm4+/2yy8KJhMGo2bYtImpktaBc9 ieiJHlSUyhmmZ67aAKasKt21kxyxmdJpXctJHqOBI4MdRCnI4ax29sz8F47N/FnRnMFXZide hkDTjdEQbaamJ+ZyLxX1SarrYjf5RKoJL4KH9a+wIhwI64Hiym1DRQn3xQ560jaXf65kzrP6 3JwtinmIZZDI/mtBn9jU89O94RvEElj9uZInPf4BLoMmMHKlS9OZHxTx/govenMsWqoRSNAl 6JWlqJohrPDgaCtUK2NBLKLgJnL7UOn54kXWjVbSbHQPWQ7liuPHJv9gPPU1zZi9PKtQqysE WDoYPonc46ZZWLkCsBoBPHS4ojbv1iZC1qT+6G2etro7ElKZYnSExjxH6bw+ndMn0BmeCL0B ys6SC6m/PzL9x5nSmfKCpHemlUCslhDQBQ0zN5d9LpU/JKZqDifaSsgVebEvTEMzPYQAwKDa qyodK+1Mkh4L7vTs3yU9USjNBIwW8ZNRwFQzxRNHpu+fyT6x2nLQIqKrGlYPpBL5Z7KlM5LM wNbiUrAr89qM2EDm+smBIItJxsqMLMmMdIQ3uZZDorlQOKUH8o1Nd92RIgeSUiwlT8z+6cWF rxc0sVdqlb4WN49NZaZwLl+caHnzW/hhT1FHCDD63D6cx52R3QGp+ck33uJ4dIciRd2KYd+i kU7knlTlSCtMkGVFCamSgmfnvnAh9SWhUFfnWy0hYC9eLLgDv9jqkA1WDTnwQi5F1CG2mTQ9 ImDTRJRNiuyxVUkz8vnS+OpUlsEPo2Qza06eQ5IXN+qmr1YjwbjuyP5ocAte8Zb3D1EbU87B d68vqPQpgR7Dy5VbD40iByOhQc8ZDZ5sLZBt1E1Ur1A7nuVUw0ACNu7o/QjM9CTDzthoYLWE ADpkOdgTvS4a3IRVKOTA08JuiHYpoOlpTw3JMl042Cs1pUjx2LChzXNyCNVTmW9LrdZ58EsK 6PHQlm29H+yM7GmIN40Cr6IQQAr7cLoj18fUjWKVrKVFIVFGIKeZHuYSS1MhZbA5ByXTy5DS F1Q8vMWshqcLp1vfTQ0jom7cOfALXeG9jTZqo/AtbZlahQs5iN7YEdrC9KmF4wK2oWGUssXz tcpcFtcV2ScFsOyaUESSIiTAw7uVL15intLaAduU9EhwZHvvz3egR1f/W3UhoAplfbA/GsI+ 4CxYE41Rmw301JKRrZ3miI0GhxmYGi/XZE9pT/gaB6bawZnMv+gGA1Pt1EZjhR1gahF5eGf/ R7oiq64DLPIuhxBQEnIAQ8PBDawct8o+wMUqTpyZHivxzA6CcnejVhtDsiJHEVzPVkwWjzFZ bYkmoFA5YESUoe19H+pc/VHArtoKhYAO4Hfyyim+vujBkLxBOA9WWGyZfIOdqVqiWErYlakX 6Ivd1GhPZQxQ5Rhb3evhtOLZHGWwH0T2AHNHYqeiBMLK2I7+j3ZHrrMj3QNYJN7LKO4o6KJe AG7pJS1d0GYakAMp3B+/KaJskAw6sV/pqUcBnc+USnqAnSkeX1TdrMhyQwrblOSuMLMyj4/N sTntotyCqQFHnrVIaHRH/we7fY8CTI4WckfHU//H02/mXo3ml5I1I5sXe3/Z9imH1D6fu+RY ae3rOJDMh8pLIwZWgpfh5UY/EzNx7jigu3dZcbJYjpviFJvfTzKVLh/dkVpoRlKRY37x1oRj A61RigXHyqOA39kgteZ0xvHkbyUzxyLq2EDsrgZ26S0no0lNwBwaHSA0YcDkhFBRm/WvDyQp 3IUfSdnCqNC0G8eqBQsTBe0CXtvllar8xZFySoTRlQl1f5shtcdTPI1APlu8GGh+g4woHv3E iWcWKnf0/0JneF9dipYnwP9U7sjhmf+eLh1laf3w9G+m8i8vB2ngVzNCgP3CPirNSJWXBhg9 zaI+WyzNerpubLrYA9jbsT+kjiqWnWgnNBxgESFd0jxGBLRUPLjNv8phyhcL7fD0LhRKcwuF V1a4mRH2YSdt7/1QPLTdZ+2RgKx26vDMr+WM46WCqWsBOZgaT33FOpDvE4kTrBkhMIxsUWcL jT2BxqDRC/ps+f4HvyM9G2l6Ow6ElCExtDdqtjlqwDk1zfBwGQHOYhLWvklR5c7n8hdggLpC ezwPkub1iZx2zhPMQeyyYJmBWoe6ec/Ax7sa0AHGQvH4S1P/LW+cKeRf5XYR7he+cX7uAUbn ZWX4+9GwTSAGAh3lj3tkSYDKEyQ2g09GVCOooEiXklzIUKRIT/Sm+dwPxf7MZj9YWdCmzMBe d7NAkTvjoZ0FbdbH2TSTvSGK2u1OkWHoydzLTY8FZSksheXhHf3/kfUh97LsVMZcxO5Y4jdL 0mmNYziLH4eyikX9TPELXdEDA7HXuLNiMdPSfxsVAi5+mS7p1kCwhKUcQjFo7CTDYOEooE85 UOWOnuit8/nnCqWL1Kmp2bZUMBJMk9xvkWG+N9J1H9fYeBaBWoKJnqePJVlfKLwkmWLbeBMf yxmR0MadfR+Nhbb6zo4GPvPy1K/mjGPFIjZ1xYdKMk/O/nFEGRYL6I18jQlByUiVtDmnDlhe Ft3SpLexXhNW++uDLcvEHTB90ZsSAQP/q1g1aXxrpYnPqHSJPebL8Fb9YDFJ9aWhqnLWiuCw UaY47rOOVQhMej8S0JAOWMifODLzqZx5slRDAkQJhjjJdfr0/F9eM/RphL6q0LoRDXDFNIvc EBCQ3HZDl8c5rhaYLZlJ//MFLorqjRyMhkYZjRu1D4DHB1A0vHeb1eVBUwnJ7IuwQlBb1SXd 8eEV7ghu39H7sQYkwNQzhdPHEr+WD5wsFdysLkOXEoVHZrLfY9R2J8OZ6lcIyjOCeRxkPvxL WF8cM51kz51/OeB6sN7ozdHwWFmMnBTWDQt5MbA+lEhwWyy4tS7c6iR0hDePxN6scoyQ0YOJ nh9RYC7IVqXg1j0DvxgLb/RNl5kunDqS+FRWP15ctATr5eVwFptQzib/MqudqwdTHe/XMufK hUzxvHDL+FXXDPFySB6IBDnJ61fUxAGVwnNi77arfSD6n5heKyEVc++asDp4Re4B0Y18svDy heSXs0W2t2hieYJ/ZdqqGS1iTIMLbHYM/IL/2SA6Plsaf3nyV/LSkXxWXKLm/ZmBUETqD923 d/DTOEi84eGkxVB30PLE9DybOBoaAsEMfEgZiKgc5fRDvqBCM3LJ+nIATkRdYY1X6uBuonho BxM/d+JXO7WkJy+lH55JP1rQpw1h08g1q4oOiAU3bu//z53hHT5Jgu0LhZPHEr+R0Q6XikLu fX7ICtus9w381lD8dX56oB8hwBeUwOz3rQOcpKIr1WhwFKPMvxyU9PRc/ocYFmh7Z6FCqliF DASD8lBneGdYyFa7fKnCkYmFf04XDjNilptrqc1EyNSjwQ07+z4WD2/zSTHbzBcKJ47P/UZW P2b7A3zmBUzlDjd5+/Wjf9QR9J5/egtByUjnxPyNNYKaIu5JGHLA1u/BoNLtX5HAyvncszgA rDJF/2eTmhTkrhcuJ2AK2rSf3JPcpgEwnJP5I+OpBzmUaAQ4V2oNDsJBRUvsGvhYNOjXDkAC UoVXXpn+dNE8VywwCjTMeXKEIupg8J27Bz/pySsPIWCtj6NxaIKm/WJlnmLQBiPBoZC47sVv fbAP5vLPFLUprhKFC0G5MxbajVIRd8628cfokMg/N5F8EA8YQwCNEVaHdg98wr8/gFEgVXzl 8NRnCubphkaBCq6oXMlrdt4w8mflTaoVict+egpBNl06i0UjpHpFH51ZiaojIeGJ84uKhcq5 3HOGkQoFBzvD13Dr8IpIuIyZc6WJi6l/wgmmSuHt/R9l8PJZOBKAInll5ldyGv4An5nqggVD 0kD4rXsHP1V9BZgzj5sQMMFjpsfY7Me4cCKtGQYbx4TZ7NWQfcAtdjgoI+poTZxtHjmd+Zew OuJ/p6i4v6F48uTcH6a0Z4r5JatiZdWUbhn7X93RG1yQuAlBsTSf0y+uVAVUFq5Eg0OK1BYX NlWSdkV/cz1FIvfU8dk/KJrjwiPkV116EM2QEA/tPzD659hk9UDrzuBxCRTN2fId//XyNhPP cYFcaYrjpOi9ZvKv0TwsXieyT5xM/FHBuIBXuFUSALeYUeWMk5Ppb7s47uoKQVFPYu76H799 tk7ZtcaGlFkcvWg/n7laCsadKQXumuO6bHYlERD/jCw7tPBAtLQgv8jQAfP5p0+n/iRvnHWu DfrN7wrHJEWWChdTXyppdTdj1l5AMg2ei5hntbSVx2wdtKIGCtp0QDG5Y2xl8w4H0jpByqKB mWtwWTLs1k2qNkurl7cp63IgKiZgkqyKW4k6MaBwYDMTEa9ccDe1b19nncK9o6FtLvfksdk/ LJjnNTZqtWgUcBZcYMEpfGY6+/0NXT9ac5W5thBwL5BhtvSgtZOocliS9KLBzJO7i7t9rPFX 5feKoL25PaRkJLOliyV9JlM6m8w/X9An8UnqnFfgFlXxNArqUrVm4QoXFYp/4XhoWzy4l6WB YKA3FmaHalyRwp67jLzIqZ1eHgWeOjH3x0XzgtZ6tbtYKCOBqV1MfnWg405c7IuxS/+tYRga AY175XWTC4ZXQSyXirZCLP8Mcx10C/WBUPVGJpl7sWROz+Wen0k/Rm+j1dnOyVWSlFp24YnS hQfKooLAYkjXcf3yXgbXonYMxe/pDu+JBHfGgptwVHseT15E5uu/SECq8OLRxO/ktbPCDljl D/PuuuHfH47fW11ODSHQjYV06Vyz/sHqIjxi8CtHQgNKoMvTseWBiBsE2QCtTbLlMqsdnUg9 pEkz+JloVM+MtQCEhLBEgZh0ha7v77glFtwXD+0Oq8MtWaxC0XKNy9mFzy0UD63EI1SL8tpx ihzoDB84MPrZalGuFAI0R6Zw3pAyl9FIgt3MGzcEvS4KrF25cizqrqBNzuWfnkw/tFA4LKkL pZJp6HSvxQ7uktkrSbjeZLYQDXSGbhzregfb1IJyn38XeE306eLJQ5d+qRTAK+xvGbomlgYj Gdf2j/zPgdidFfkqbQJdz5um9wG/Ciwr+Sl87EIbN3+IByN/IX/4Uub/zuYe1QwOF0hUokxS CyQAPFpJ6GpdnclmHuZu6rHutwzF7isfaGl+ARMNw/wLw6QVUuqb/WrxfPIf+jpurVBmymc+ 8xkHDqznaU1c0dwa9jkw1w1yr2FQ7QkrvU30WvQWV4RMZR4+M/+5ucLTuo4x6LagX5cIHwm4 ztGOhplNay9mC+e5a447Tt03NrpgZSZSKiUyxlFDv3z+EkVma2OxO3yQdRwnbcs0AUoVq0oI gJgyi8602tLAioIsR8NyXzMSwFJb/si55AOzue9gzBqXhZl0XZb15oynFkqvDETu2dzzXtYG KzqWk7/1whhAm3vfl5x8Nq0e5uDA6n3O7qxpphKeupT+end02VnHZc4iptTMj1mn4VAAVJZP EFvb/mgsS8G2klqBk0U2XgLxtwHGWTamdbJw6HjiD6cy39S5NP+ySIBFAB1D1+gu6UuZrx6b +X32HDd3xRz7Ica6fiYU7Gjohm8nE1zCtD1oOShb5jHPekZYf+dETVfkenwzFRkrDEPahW1q /Cuwn4wL6XEaclCyvCTKiclXRaFV6gGNI0sd5Z60TCFVkFj9EwmYzz1zIvEnC6VjuIKa0CLV OJuLkRWzK3jDzoFf7Apf664PBO+E2lvW6/BfHZr4ZEp7toWOQlGC2MwYCAWjIaVDK6mcVGQF jt3YXaFr4hH2YgnPh7O+FULgTBJvgnITKSfuYDr76YRjVawpE8m/lQ4WYMDAZs8dh1WWler1 Q0hA/vkTid/DwL6cCqAmXaJdFak3esuOnv/EAdZqn5Ku66lUKpfL5fM81avHYrFQKNTfz378 V62uiYWHjs/+D1ZKm1S19lS+HKDtOyL9XNPEtDMW3N4R2hpRRrmrhcvkXExvNyFwVrssARqG UUnD385NXagF3LFiNHvVhCCwWDFnxrphk31wXR3BsQb7sTGbferE7O/lVsHNXpdUrwSW7ePB G3b3/1fBa5zhQp0ayWQynU5nMpnnn39+YmIim+URZyMajQ4ODt5zzz0jIyOKIiZEsPGVqV+f WPi6VyFL6a+y2eI7XYnfphyPjCpKXNck3II8rCPeh1RHfe7A8ysESyTw/CfKhmOQehpTmYqV Rw1csBYqXxpCqIGAEg9v5wYTB2bvINvuOIKTN463UH96l+oKQRNwqpY5Tk/orh09v6QVuqan p4vF4gsvvHDs2LFCoTA/Py8aqswfhgP0wa5duz7wgQ8MDLy6R5I9BM9c+IgWmDKqjxU5irba Hm0Px7lbj3/s21Ok4bDarUqdQ/F7u8J7sK7Ygcf5Pkc+72Bjg3EZn3Cp8hixonKBp3jGEB8t cwr2UnIABhNJTKMWVRs1rybBSuUKmUafA+MM/LnkX2aKR62xqBpzYzFO0pqyeml7MWk0JEOT 85ngxPwLU8o3Z8Y7Dx9+JZFIaNrSjeeip5Q/K3Dy5Mlz587ZQsBtj5t63nUh+/li3nG+cLEy FgvZX8tQTMOHI3HuNApKQ9HQGCfO+qJ30Jd4ps1F2y9iqvvfJoRgCReDOkZoSAzqPazOcRpM LNsQEM93IA1CZ1jmqdXwtkywWBcO+j2nZpXHMuCF5FcShUeblIByk1vtDgaBxLEygj5lVLMl tlzEUjXtEADkA4nAYEiFjFrIBzPJcHI6mpzqmJ+OZlPPsPJaxi/Eyu4MNgY7MD4+fuDAAYsh TMRGO986lfmWpp7iKJkNU8Yg6FSVaCwyqGthruPriewLyqOcXIiHd5T3aDnBmwyvSAicZQrd oPASbCeDnPjHXTpmnmcucbUhEMzj4V+ZKaKSvG3u+bKYEzlnMBK5J87PP2DKDa+2lpuWQVrc aFkqKLl0qFRUDNaQHdwW+lw2gxEt1l3A4Efllnu5aE4hHJAi5kYsQwhTKJ8LZpMgUS8c7UtM xEt5OZsOa0VFUQ2cMQLSx4dl4ISKBDeMdr7z9PyfB+QcjKPHwyvM+PJry9FocIwn9DpCm3BP hZVhuy85Mawk3DIhsIkQS3BlHzDvg4aUbipTXstPiWkFj8gaBe6LDqm9Fm/tXO4BDr2fSnwe CWCC7g5ZkcpALNS1rqRmo5lkiP46fqInt1DDEMFK6RrIbds/HYrqnb25eE9ZGjDyxBKUsLzy WSU5FdNKytSZ+PjJPiYmpUJQ54S+IsyhYMivp4ImZIIwNjZW0Zajnf9+NvevBelFLd/B8QRZ irF0OdL1o2zRxjvpecl2RcUb+tl6IbCLLzezqKmqxPknNKiR1wJpzgy5T6ltDFYARwU7d7Pa YRxeFYyrgFz2UxSP+aokJjoSk/Hxo70zF+NCAdCr63TW6fNd0+c7QxFteHNqeFuqdyTd2ZPP ZULz0x3FbHB+Kjp+oreYCyJVFgaqpgQbE0pKj0Qie/fu7erimsxlH1enbut5P29hdfRuG4zf HZTZbmMNX8vAVuNHE7OD1SDDDed87oUXJj9W0lJuQMvTaCR6dj6j0mzHnh5ZmInyEz2/HKrO L2HrSkrQ6BnOdfdnLRWSz4YY7BUFLP6Q1MJNowaDweuvv/6d73xnXx+e8nb5VlETtKSKmJmY ArKS8f9kIBKAAp+b7Dj13PCFY73FfNAa8v3SU+7fCM3seCwxERNb7LASuCet8U7vLNGSgOuu u+4nfuInenoa84858axGuN2FgDl0xnyZHWE+K48GRV1fOtPzwiNbUokwY0I9BUAz2ziF1b/0 S0QLVa+KTo/BaIOtJIAO2LNnz7vf/e52kwAq1dZCgBqYXHjYkKb82oNsaNekS6d6nvv25vRc VAnWMNZoe1QF2l5Vy2vD8AC50eVSUTZ1sWS2kpaumZfyOjo6du/ejQT09lYu3tTMcpkj21oI uKxxOv/PeX/77+i7rMkefWr06A9HSrkgzSyad/ETix6y2dFZ7B7Idfbn4735SEfJ3shSzClM 91OzkfnpWGae4d+yHxczr+y/rBS88Y1vvO2221g4WBmm1crdzkJgJrJPaybOVO/Kl+1o49zh oRPPDCEBFR2acT0SL23YMT+0OdUzlGH6xx1PTOgtGaHvE8QlkE2H5ic7mPqPH+9dSOAPXXIf eVNQG0LqH+hjpeCOO+4Ih5ct3NUGv0Kx7SsEXEA6k/mOptVQ6dW8QsPTbEeeHMmlwxVGADpg aGty4665DbvmaH7m/Zbnx0YiREEIhBnvzjMnHNmS7B3OnDvcN36sj9glZWJn8Beg3L7hws13 xm6/4+Z2lgBq075CwNWYqcLR5V7U2uwXA4EunT40lJyOVUgAOmBw08INd5/vHcnyMrWQAD6H SejAKJLo/WpE37RvtnsoC1p8gs0dP0F7dQ/m9tw+uWm/Jqlc9BR3FNR2wWV7HNqKOg4O8JiE 07lblzzJTE5FTx8aqOi2TBPiPflr7zw/sCnNBcDO6UBdVCQIpSB1D2Svu/vC6E6OYQnJ8P8B jOT1DOauvePixj3TBfkIl7z4z35FINtXCGYyTwi97eczA+eP9WPZOadzNEYorO259RK+P2FV 1O79dbGbhtwzmL32jvHOnoIvQSxjEuJiSF2D2WteM75x76wks43UKKwLQV02eyVkS+eW78Wq nQGlnc+q5w/3WtP6RSDR5mj1bfunylq+PAospvn8Lx26d0Nm1y0Tsor/0U8mATS4Obn/zvFN exJCIrE3dTNdPO0n8xWEaV9NwAX2jtuT67NIMqbOdqfnlx0BQPNHO4u7brqkhn2PAjVK4Diu ue26maHNHND2ECOkBJjBTalr7rwwtjdRfgxSZGHRLCuEwJd5W4OEyxLVpkLACQJOZ/jRw6pq supTwSsm+luum8E0e9USrEj2/ZPsrC9v3z/D7MMlExJgGPLI1vlr77owtCUt/I+20JhmunRq hc86uBTdkqQ2FYKSOa/pOTfGL9Yefidnos7nymkSWdVHt8/7GU0W0dT9L8bBwOZUNMYm29ow ZQmQBjakrv2R8eFNC2WNsaQ20ARFbZoTcbUzt0dsmwoBF1azv7ke323WMV5k5iPsD2DwtSNR y939+Wis5EeR2LlcApGotmH3fE2lYlG4aW9i/90XBsZqP4xXPhPNXpj2/dpUCMQFCT7GUVky 5qaiRfapODjMQnDfhoVonOPojtgVBPE/Dm5cYMJZgWNRAmavv+vc8FbLbqiEIQu6CjmoyNtW P9tUCMo7QnwwCk0w16GXlj06gALvHswzli8NzD4wuYCIS1SrNg4JCZACI9vmr/uRC12Deec6 hQuq9kxqUyGg91R4fmqyD3utmFeZy4n+tvjRPOwOWj5jXExr+r/LSihjkQIbds7tv/t810C+ 5kjhLEpUp42/NhUCcUOMD4ctwz82ILsXK7QwXuQWc70KHSPRzgOT/RuynhKANDe0ne7yS0ub CkFYGVDlSHlt0IMnkQ5NHLt06A0m97lUSCs0f+FBRZEIgC6WnSqipc4+bx0gMhlsvW3fJUQI bFchCA4qSkcl2ytagTHACMR6ckpIXPZgfywTsy0MN2LFgrIN0HBAD2RToQqJBHk44uPpMXFK qLPRYzYNU7iyDG0qBOywZse67XGpV0dsQJYHo9FlB/wV2WBPQD5TY195PTzu8ZomXzzO+fml fQ0MQ10DWTWEO9I9q9iREAmOiUM6bfy1qRDAMfH2rNckjzZggxBqWTjpFj+M+UI2uDAbdcQt pjX+X3p8ej4ye4H71ZYyo4HG9nDCcCmmXogzipxS5Z2OegDtEN++QsCV6HQ4Tx7pmozHvhru 1IuDnDTyzO4NwBLlkT6dDWeOMhDOgdEFH9SJU5udYY6Fty+f4UD7Etcfv9Pb8BZmgTy6Yy6E f9DxsX9k8kwXu8ScU0dHut8geGYvxs++xE6FJU0DVX3D7FHLL+5Pq48NBWUq/l86qI9odVPa Vwj6IjdzgYFn7RkR2DTGSgEPTDiAaTTp2FOj7BmkIR3xDQQZCIp55chTI+nksnkKHkkWqWPd 3q8SoQbCgU3+HzxpgLiWgravEKhKZyy4s3yRg0eN0bVbr5sJx7i50CEHZiAxGTv85AZWFpqQ A9xQnDQ9+fzwxEmOTS5TA5Gu4si2pNiquhRdm8JQSOqO3Fp9R1Bt6CsX275CwFDFs7+Kn0dN Tal/Q3rzNQmnDYHVRkNyDO3lx8fYg8omH/9MLusA+eQLw8efGdZL4u0t+8MaGNsx3zuc5ZCC HVkvwGPe3VHuMmprJwHEe9ekXg1XOx4/G3cBqVK/54owIwK+/R03TsZ7ONe9pAyQA6Mkn3lx 8KXHNk6dYWTh3InbnK7cscVpw4VE+NjTG47/cCSbCjslgK7P3sPtN0zhk3ZDVGaNyoKGNtIV uXa1GbVy/G19IJXFt5OJz04WHuBdSPeq0t6sJqO6n/p/2/NZ8QKUE54FwFhnYWTHPCfP6cRY eRUrCwgOMCz6cwb5xLPDM+c7cTdVnDpgrAlGSne+7fjQ1pSfpSlFDQxH375v6FNtPjWAUe27 5RziuNFoMHb3pfSDspJ035ZBv6QhhzfP77394qHHNuol3k9ekgPhSM6Ezr4ykLjY2dmfGxxb GNqSCoa5G+ZVRcgrLLMTnVPnOpPTHRxD1kpkxr+zhEGsUUnm/rvGBzezbcQxVXDKmiPM0TMl 0Lep96faXwLaXQigrzO0Lyrv0M1nPVQBut6U6Hzbb5jmCoHDT4zSs51yACqGBvYgLcyFp891 Hnt2JMxa82JrFotKKa+IG0xKYh0CgWLgsNtUoFKM3TdPbLt+CpxOy8OGqQhgz/ZFb48Ht1fE t+fPttYEsIwbLbb3//yhyV8OBNKea/bog/I28wlE4sQzw8WiukwOytYC2w+5cySQCWQcqkJM K+yGXzIqRJMhAZFYkY1DY7vn1KCvbau8qqBKI1t6fsa6saU9G95JVfsahjaVPdGDvdE7eSHF jnENSOFoadfNEwf/3elYFxvUxHU1FfD0cqw/ZyQ/nV3fSmIIIO/QpuRN955lChqJcr9rJSon EjscDMmbut8Tw1t8lXztrglgI1OsrT3/IT15uKBe8DyjLowD3rDp0DfunovGS6dfHGTtR5iK 4jqqZQ3v0kDCAjADsb4cG0f33DYR7y4ovg8whcJyRN47HLsXdeBSRFsltfXswOYU959x/eup 5O8XtXTFJW82TEVAzA8NYQ/Onu/kzoqps52pRBQ5YMpX3emtvAgQXZ/FoZ7hzNjO+Q075zs5 wR4TS5Qk+fmYzXIn1+7+XxuKvbadp98Vdbk6hACiecHu6Mz9k9lvuE8TllVPDPQMB3IuraZm oqwvT53vYmdAIR0sYQAu/5CPMAuS/fmxXXPd/bm+kbQa5qYa8vsaAsrIxNVz23o+vKnnZzBl lqNv619XjRDAxUzhzOHpX8+ZL4mn5H03TbnfCx8At89lyjuO8Prl06HkTAePY4GWXt7RVejq z+M8CIa1WC+X1xmquKEY5jTQeOiegejr9w3/KpfKN5CtDUCvJiHAWb+Qf+XwzG/kjRM8HQTT /X8WsGhU/on7aQJMCG1DjyFfDQlXgPifmBw21vzAq8FAd/C2nf3/pTO8xz9VbQJ5NQkBLGPU 5hWi08k/TRUOreSO60UBsnt6o62+rPkwBXoiB3YN/DLPpXHh1bK0q+GHz3lXu1SFBYWeyPVb uz8aVbaq3PLd7IdKKP+j7a1/zSLC56oGusLX7+j7RDx4VUoANb/KhACKeViiJ3Ljjt5PxJRr QmxMtztz8+3YdE7WIKSYeu3O/l/iYYmrxTVUXdurbDiwK8Da0kLh6InE/Wnt8OV5XNIu2grg jWAU6I4c3NbzkZ7ojVfjKGDX6GoVAirAzdkLxSMXM/9wce7hgJxvYOpo134FAW5139j908Px +zrDO6pfvVkB4iuQ9SoWAriFU7igX5pOP3Yu9cWCdoHe2eyjuH5Zz44xjNMOdefm7p8aiL22 PBts3jTxW+oqw13dQmAxhztNFvJHx9Nfnss9biqZIl6E1flCPBQoxXpCt2/u+ulYeJfKpvg1 8a0FIaAhuJk8X5pI5J5eKD15IfkQewHK3uWW9VGePMN/MBi7ty/ymp7IQV52vqqNgArRXSNC YNWK15iK2sx8/rnpzHdmM08FZJ6kEP4hn8sNy1jDZJRuzylEfMdysL/j1sH463vCB0PikOQa UQB2fdeUECyKQraoT+Jjns0+OV/4oWakCloiyKE01AX7Afgn7jWpnFkKVyH/l8VxERI1TQmp 3bw80R+9szd6MKJujKjDPB9rM24tBdagEFjNww3pRX2upCcypdPJ7AuFwERBmymWZktG2jA4 MrDssApZUO+s+vAAdiQ0GFL6ItLmzui+juC2CF1f6bmK1oWbkM41KwQ2L6wXmMTLO2amoE2X NB6sz9PVbQArgKuHR6J5aSoSGlECkbJAdF5di4EVNfL/c+0LgYMXPMmFDuAisRrTBwYJWTzh xTPhLTvO7Ci6rYP/poSgrVviChJ39a0dXEFmrdWi14VgrbZsA/VaF4IGmLVWQdeFYK22bAP1 WheCBpi1VkFXZW/8qVOnnn/++ampqXxeHP9w4V00Gh0eHubR0G3btsmLx49PnDjxjW98Q9d9 XQqtKApPzvLg3I033sjLcy5lOZN4vP6hhx4qFou4CXmvdNOmTdD5j//4j+fPn3cn2EZCRoi/ 7777Nm/ebEUmEolnn3323LlzmUxG0yr9EHZGAtSUB7NvueWWHTt2EIZLX/rSl2ZnZ50wLmGK ftOb3sQ7my4wDSW1WAjg4OOPP/61r30tl+OUuN9WfOKJJ9785je/8Y1vtEhPp9OIES3ksyYw 5dChQ6+88sp73/teXiL2k6tQKBw/frzEznNFWVjgaXfx0X6nT592bz8Lkr8UyhN34LFiaMK/ +qu/unjxIjgN8dKKx4egv/DCC69//etpTph29uzZS5cu+ZQ/VVVtmj2K8ZfcYiFIJpMPPvjg /Dw3e4kVPLtz1yMGfsF02vs73/kOvZkeCSS8gJXEEwCDhcoFA0nAIwdHjx694YYb6kE648HM ZzWYEz8xlux6Ug6ARSFoCTz22GM0pCW4IHTidJZrha2iAf7Wt751zTXXbNiwoUwORySWpMeK seAriAHMCVmNv9GYFgvB4cOH6ccQQR3i8Tg15HnYejTBO9QyWhTgubk59IElBDY83ZqnZTs7 OwGwIysCdCnGHSJpP/RqRWoTP+H4yMjIrl27QOieneHAevw8m80+/fTTFjzZt27dOjo66kIz /fjIkSNIG4Mgb6YCuX///i1btthZkCHYgm4jAMJbb73VKQeAdXd389dd1NyJd6a2WAjQqNQN 4lCVP/dzP7dx40Z0l103Z8HAADk+Pv7Xf/3X6A+SUqnKd9F5TvDuu++GU86MdhgMYEbmPve5 z01OThLPGGSnNh2A3cjij//4j9ck20ZLKpDW6EPzUwULngb7sR/7MZeHECEbeMY75IbHs61n U61BgSQb/zPPPEOP4ieRb3nLW5yvq1IQ+J3Adq7mAi0WAksNwJ3t5c/TUgOAbkfz16sSAGgC l7rBHbojAyowliZ3AfaTBCUYCqgxP8A2jFU0au+uu+7iXdx61bHgaUWGLYY/SrEgq+sYCi0t YXgywSajuUCLhQANb9WK6qEDPGmCa3QmhAa+8DnhwWN9zsjqMHkp1Ip36X/VGV1iKNcltWaS NUiTEYn0zA4AzKlu+JqYL0Okdzs1QYQnF5w469k4yATdCxsec6EmDKUAgz3PmEKgie7rJMMO UxZzvDNnzrjbBJSIzDGQ2xmtQEN1r8h7pX6uihC0qjIYXN/85jdhqwtnmaTRWihMZpjYoSsv GiFgMMbUdymUUkjFAPzwhz+88hKvOIa2FgI0AQa/e2PQI/kw1Om+CIRzKG2OuWBj8mYPMfWQ oHiYCddLvbri21oIMPpe97rXDQ0NufCUlnjkkUcwzp966ika5u1vf7sfW8QFIUYGTsADBw54 yoE1P3RBdbUkrZYQuHffau7UhKc5cY7aftnqXMRYQ/jDDz/MxOQHP/jBPffc09PTUxPSGVmz OAsAIWCW/4Y3vKGmIeJEAqTzJyqEny6YncBtFV4tIbA44qeqFtfqwRPvqeHHxsZoD9qMscOz 5WyS6rUW8XyNTjSsXCCvVxG73DYMLJPlldPH2AwX+LCuPdUpxTGQ43UHnjB8rCCAGD+6nbHA anv+Wqgq8FT/xMlouf0poqJD16SkGoMzhkItJFQZ17UzqV6Y0r/97W/7YVE9DC2Mb7EmQBXD Dgw6vDd/+7d/izeUflyzYeA+jMBtjLMPeBq7ur3hEYY6U8SaGOACSJChJ598kjAwiCBIECyc svwktZpTROK1ffTRRymUVMyICk2DJOGyffHFFz2niDg5mCDgwQUnSIAnL02L43JgYMCFZkau l19+GYc3HMAbWJPOaspXL6bFQrB3715WgSEXFrBKRmO41BAYuIApDgzh6rEfbsJT2tXq6DW5 gKBYSwY0Jz445or08q9+9asu6wh2FuSVNQIazImZsvDpsh5YrxUtYGjG2/O+970PIUD4GJJo VPIi03CgWqAriqDikIEpAwGQ7Uy9/OEWCwENuXPnTphIP6N1qap7lWAlLcG3b98+vO4VwPDU c83UEjIw0C9ZaOAvjUdXw8fg0opWucjNa17zGqdbHgLIBdkuMmQRSYkgoSH5iRCwKMy6CcqA irsXbWen9L6+Pj9mrJVl9f62WAjwAX/gAx/4/ve/jxpnRKArU9V61NPGsI9NJUjA7bffbrvr aQZyWeq6Xl4rHkg++uK2bdsYeqwuRcPQGDRSvbxgZnaHJr+2/NmQxFMuCOtldMYjAZRiCQFh 9sX85E/+JIMIxpC1HuYErghTcdYX2AXDvpIKPWRD2lXwwwc7V3OB1p87gIl0I4ZVOgQVcOEp vIPpKHA6BNa43Rj0frQxnPKsEsjJxXiMHKCcrdEdyaNTksRXEwPlAokc8FlZAAMYLyGU18tV gQokFM0oYCsSNB+UsxiGInFHQl56C5uL+FuvkyBJExMTFh6UKxqugoAW/my9EFjEQb2fVgQY VsIUZ5X857Vykd36/Be9mGNZuRDs3nhOIq1wBfFkt75qyIoYCCBvRaTzp5OYeoLihF9JeLWE YCU0ree9zBxwE8bLTMp6cVeKA+tCcKU430blrgtBGzXGlSJlXQiuFOfbqNyV+gkwhpkr89dP nTCJAcObZgUIk5FpJJawHeOJB8ia/jiQWFNqd2LIDgCWeQUS8lrZPQmwACwy+GuVC047BgB4 QjyB6oLc8eMecKe/Iruz0Iok/z9XKgRMyj//+c/7nNYz1WFmzB5LFmqZo0MlU2rObDCt90Mx FeZjXn7w4EEwOBf6cBXjYGbxhsm6e1vSKpCBZ+K1r30tlNjz7+eeew5nM23ghxLaCTfXJz7x Cfx9x44d++IXv0i5uBw+/vGPM/sHw1e+8hUQUtbNN9/M5mO7FHfkIPnt3/5tWEo13SGtVMBw tX3wgx9c4XbFlQoB1OCjxbNh+c48SYcvLPmwK/Bnf/Zn4aOd3Sf3qTbZaXI8UewKt3ozpVuS 5EcnWV12ZmYG19473vEO3L0WzRDA/hSawbMKFgBuJauvU6iVkerY8kdDEkllodMnQguM1TJP j7WNEPx0iYY0h53XGWiZTUDz8EGWywcAFFNJ1tBQHhYdVh2sXPRR98/KAos5sTQ9PW39/N73 voezz5JCl9LtJIsMWv273/1uxWEHksBpQ7oE7Pa2aOCvszGcYRvAT8AmgIBL6XZSNRl+SqmA aYEmACN1pvHuvPNOnPH1+jT9hp0/LLVZdNOhOY5pU0N2/P+sANXLDiQZObCB+iVMk7MMzRYg wvRpq1OidW+66SZWIsBmY3YGoBO1wVEnVBFZ0AeMRM6TnbCekYKDkbYz2Jm9Imy7nCviV/4T OmEFC4yWTLggRBpWTkZrhMASWxzprKPU7ARWZVgyuf/++y2XuNWP7UoSgPssqLhUGMyM4p/+ 9KcthUlDWsBsILAIgHGMEdYAXI8M4hGdz372s4gUclC9SonVwlqUdTrMhRirRBeAFSaxHos9 UbMWTsyQUU/inWDu4dYIgVUGUulOEKkWAHVDpVdTZqVWx9sxrDbRxggBlbeHW0sNEMMpAJrQ Bq4XYOcqC06M2fUAPCtSkZGiK2JW/rMlreuTjJbZBD7Ls/nlKeM1EdI8dke3MVgB/trIa+a1 IxE1y6KsB08pNrCfgE2JH2CfMPVo85m9IbBWaoKKmXdNOqxeS1I1sB/Wk8s2nq3JRc1S3CNp M5dmY9aKtYGqcIEBPyMxGnv1mgrbGfPFEz9HPjm47QnmzpCWCQGtyyDNTN2FdxhiKGEA6Ivs qqigjAGCatfLTj0pgptEsBwJ8zFFrsCw8p+Uzk4IDkqDvx4llEIqBtAnP/lJz/GrOZLAj5uB LSru2ekSbFFkS587mGdqy4QAO4sZFxs4XXhHX6efQRPNaRn2NjDZ6X9/8Rd/YauKCtLhCzDs VrKmD9SfWUAFTEt+QoBFpAs2ixgbgJ92uFUBOEN93bHBT08YdwxWasuEAHSwz27UmmVDsaXz mZVV3EdBRox8OrozI5F8doxVZ/5iFtx7773uJ5PsXI0GsD2ZrFaPVhV42Ba2Gm1vlUKt/Ryt hAAclACvkJKWCQF0MI5inNfryjQeyhOArVu3ct9ThRlPdsZ4JmY2r6kb7jM6JQitVDQwqWRk IsoG0aZVsQvLSMKf/Z73vMdJiU2SMwCkJdBEOiXVCbOSMHfY+DlfCxl8KymIvC0TAroO0/Tb brutnrcHluGBoRPTeJaF7ySdSMY2dnA7HbcvvfTS17/+dcuMoG2414MbLagzZTklwOICf+1W cWKuDkOhpUVrNh6YMfqcCxPVGC5PjLOOq1piy4QAKlnGqLd31qqDu8wiGUgJn11hujsI/+Zv /gaVgHOJlaq3vvWt7Eu2AawAzKI5aVfuzUNJeLYfph8+IkvBuJNUUVATP8HfXBE+BboJkqqz tFIIwN5chS2yqvslrcv8h4vpkAMmDsjBl7/8ZQYIroRx8ohRHAxk5xpBxAXPY5nzNZQk8cww L1y4YFuXLdn2X6/WyBmXbHzhC1+oB2BVHDBGUqwc56Z7rkPDQV7NEyuLzTHoZ2y1OOBMaijc YiFoqGw/wDQ2swCGiQceeAA5oAdz5STrltTclgMAuOjLUgace+HuEhfMgMF0AMiOaclc3wV4 hUmUhY+cNU93PFCC4GIJ2rJCgAURVsU8MzI+chDbHcwztTHXWE10VJWvZlJDkfWQwCNMpA99 6EMMDYRxJ2Ao/N3f/Z21bEgRjBq42S07gwYm3uWzrAHwMGq87W1vs/uQXbod8E+8JVXVGYnh cyHGTgIDkHaJhKHTTnUJWEXbGZsLrFQTQK5lRkENnG2CCBqPDzwV8wUnKjDjGnv/+99P2zOi 8xPNT653v/vdgGFGvOtd78IawLvCqiBTTSdDnXgIQy3djsVGJil8dio46X/MUCDDJbsN7wxA gLWpxOYAAxl4fFp2sM6uO5XynJ3aRVsZbf1hxzcacPOL+cEFHTAdsYVx9CpPo6wCJ7nIjqQT oHmcVmEFJD/tsggDD4ut7UkWJKmYC6Cy+np1disGltkt5GQfrQglxNCQjM12c9bDY8eT0VrK Ii8ZrYYHFfFO/DZ8zQC54B5/XZa1amZslNqaSFYqBDWRrkdeXRxoRoFfXTVcp9aTA+tC4Mmi tQ+wLgRrv409a7guBJ4sWvsA60Kw9tvYs4brQuDJorUPsC4Ea7+NPWu4LgSeLFr7AOtCsPbb 2LOG60LgyaK1D7AuBGu/jT1ruC4Enixa+wDrQrD229izhv8fgycu8bow+TkAAAAASUVORK5C YII='! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 3/30/2013 21:56'! open "Open the easel. Public method" workspaceWindow := self getWindowOf: [ self createWorkspace ]. self openViewFor: self templateScript. self setCallbackWhenClosing. self adjustRoassalWindow: roassalWindow. self adjustWorkspaceWindow: workspaceWindow! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'VanessaPena 11/29/2012 18:03'! openViewFor: str | allWindows t | RoassalViewWindow ifNotNil: [ t := RoassalViewWindow. t delete ]. RoassalViewWindow := self getWindowOf: [ (Compiler evaluate: str) ]. (t notNil and: [ RoassalViewWindow notNil ]) ifTrue: [ RoassalViewWindow bounds: t bounds ]. workspaceWindow ifNotNil: [ workspaceWindow announcer on: WindowClosed do: [ :ann | RoassalViewWindow ifNotNil: [ RoassalViewWindow isDisplayed ifTrue: [ RoassalViewWindow delete. self postCloseOperations ] ] ] ]. roassalWindow := RoassalViewWindow. ^ RoassalViewWindow! ! !ROEaselMorphic methodsFor: 'populate menu' stamp: 'AlexandreBergel 7/4/2013 08:50'! populateMenuOn: view view stack serializeButton. view stack exportButton. view stack zoomInButton. view stack zoomOutButton. view stack findButton. self exampleButtonOn: view stack. self selectCanvasOn: view stack. self infoButtonOn: view stack. view stack moveFirstViewBelowButtons.! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 5/7/2013 18:38'! postCloseOperations ! ! !ROEaselMorphic methodsFor: 'script template' stamp: 'AlexandreBergel 5/4/2012 09:22'! postScript ^ ' "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view open'! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 7/14/2012 15:47'! postScriptForMethod: compiledMethod | cls | cls := compiledMethod methodClass. ^ cls postScript! ! !ROEaselMorphic methodsFor: 'string manipulation' stamp: 'AlexandreBergel 5/7/2013 13:53'! removeHeadingOf: sourceCode | lines i | lines := sourceCode lines. (lines second trimBoth isEmpty or: [ (lines second trimBoth first = $|)]) ifTrue: [ i := 2 ] ifFalse: [ i := 1 ]. ^ (lines copyFrom: (i + 1) to: lines size) inject: '' into: [ :str :l | str, l, String cr ]! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 11/16/2012 09:29'! roassalDescription ^ 'Roassal graphically renders objects using short and expressive Smalltalk expressions. A large set of interaction are offered for a better user experience. Painting, brushing, interconnecting, zooming, drag and dropping will just make you more intimate with any arbitrary object model. Information about Roassal may be found online: http://objectprofile.com/roassal-home.html Follow us on Twitter: @ObjectProfile Facebook page: http://facebook.com/ObjectProfile ' ! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 5/29/2012 09:12'! roassalIcon ^ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self roassalIconContents readStream)! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 5/29/2012 10:01'! roassalIconContents ^ 'iVBORw0KGgoAAAANSUhEUgAAAIIAAACDCAIAAADOPVQPAAAKl2lDQ1BJQ0MgUHJvZmlsZQAA SImVlgdQFGkWx7/uyQkYhhyHnHMGyXHIEgVRGWaGzDgODAJiQhZXYEURkaQIuiii4BoAWQMi ioFFUQHzDrIIKOtiwITKNXAMd1e3dXWv63X/+tWrf7/39fdVPQDIh5k8XiosAUAaN4Mf4u1G XxEVTcc9ARgghlxGwJLJSue5Bgf7g7+1D4MAmnveM5rT+vu8/2pUNiedBQAUjHAcO52VhvAZ xItZPH4GACgXJK65PoM3x2yEpfhIgQhnzXHCAhfPcdwCH5zPCQtxRxjRwZOZTH4CAKROJE7P ZCUgOiQhwqZcdhIXADLSOXBiJTIRbfJcDYZpaWvnOBdh3bh/0Un4N804kSaTmSDihV7mDe+R lM5LZWb/n8vxvy0tVbD4DRXEyekpoX5zPSNrlsVieoYuciKH4b/IvAy3kEVOymCEiXIEPuGL LEgJd13klLV+onxuXGCQSD/dPXqRcxLDIheZzfHwXGT+2hBRfnpmqOdSvnvgIiczfYMXmcmf 72WeOaneIUs1B4vq5KYGinqJ53uJcjjpS/1mJIb5iBjZAKL8JC+GqF++z5J+arBIky8IEa0D hxsu0mQzPURrC0JBNuACFggATJAOMgAH8DM4WRlzxbuv5WXzkxISM+iuyAngGNIZXJaxId3c 1MwczJ2nhd/17sH8OYFk8EsxHuJ2VGRfdS3F4mwAaKsCQJ66FNOsBUAcqbE1miXgZy7E0HM3 DCACcaRCeWQ3aABd5MSaA2vgAFyAJ/AFQSAMRIHVSNWJIA3wwXqQC7aCAlAEdoG9oArUgkPg KDgBToE2cB5cBtfALXAHDIDHQAhGwSswBT6AGQiCcBAFokHykCqkBRlA5pAt5AR5Qv5QCBQF xUIJEBcSQLnQNqgIKoWqoDqoEfoFOgddhm5A/dBDaBiagN5CX2AUTIalYGVYGzaBbWFX2A8O g1fBCfA6OAfOh3fCFXA9fBxuhS/Dt+ABWAi/gqdRAEVCyaDUUEYoW5Q7KggVjYpH8VGbUIWo clQ9qhnVgepB3UMJUZOoz2gsmoamo43QDmgfdDiahV6H3oQuRlehj6Jb0d3oe+hh9BT6O4aC UcIYYOwxDMwKTAJmPaYAU45pwJzFXMUMYEYxH7BYrAxWB2uD9cFGYZOxG7DF2P3YFmwnth87 gp3G4XDyOAOcIy4Ix8Rl4ApwlbjjuEu4u7hR3Cc8Ca+KN8d74aPxXHwevhx/DH8Rfxc/hp8h SBC0CPaEIAKbkE0oIRwmdBBuE0YJM0QqUYfoSAwjJhO3EiuIzcSrxCfEdyQSSZ1kR1pOSiJt IVWQTpKuk4ZJn8mSZH2yOzmGLCDvJB8hd5Ifkt9RKBRtigslmpJB2UlppFyhPKN8EqOJGYsx xNhim8WqxVrF7oq9FieIa4m7iq8WzxEvFz8tflt8UoIgoS3hLsGU2CRRLXFOYkhimkqjmlGD qGnUYuox6g3quCROUlvSU5ItmS95SPKK5AgNRdOgudNYtG20w7SrtFEprJSOFEMqWapI6oRU n9SUtKS0pXSEdJZ0tfQFaaEMSkZbhiGTKlMic0pmUOaLrLKsqyxHdodss+xd2Y9yinIuchy5 QrkWuQG5L/J0eU/5FPnd8m3yTxXQCvoKyxXWKxxQuKowqSil6KDIUixUPKX4SAlW0lcKUdqg dEipV2laWUXZW5mnXKl8RXlSRUbFRSVZpUzlosqEKk3VSTVJtUz1kupLujTdlZ5Kr6B306fU lNR81ARqdWp9ajPqOurh6nnqLepPNYgathrxGmUaXRpTmqqaAZq5mk2aj7QIWrZaiVr7tHq0 PmrraEdqb9du0x7XkdNh6OToNOk80aXoOuuu063Xva+H1bPVS9Hbr3dHH9a30k/Ur9a/bQAb WBskGew36DfEGNoZcg3rDYeMyEauRplGTUbDxjLG/sZ5xm3Gr000TaJNdpv0mHw3tTJNNT1s +thM0szXLM+sw+ytub45y7za/L4FxcLLYrNFu8UbSwNLjuUBywdWNKsAq+1WXVbfrG2s+dbN 1hM2mjaxNjU2Q7ZStsG2xbbX7TB2bnab7c7bfba3ts+wP2X/l4ORQ4rDMYfxZTrLOMsOLxtx VHdkOtY5Cp3oTrFOB52EzmrOTOd65+cuGi5slwaXMVc912TX466v3Uzd+G5n3T6627tvdO/0 QHl4exR69HlKeoZ7Vnk+81L3SvBq8prytvLe4N3pg/Hx89ntM8RQZrAYjYwpXxvfjb7dfmS/ UL8qv+f++v58/44AOMA3YE/Ak0CtQG5gWxAIYgTtCXoarBO8LvjX5djlwcurl78IMQvJDekJ pYWuCT0W+iHMLawk7HG4brggvCtCPCImojHiY6RHZGmkcIXJio0rbkUpRCVFtUfjoiOiG6Kn V3qu3LtyNMYqpiBmcJXOqqxVN1YrrE5dfWGN+BrmmtOxmNjI2GOxX5lBzHrmdBwjriZuiuXO 2sd6xXZhl7EnOI6cUs5YvGN8afx4gmPCnoSJROfE8sTJJPekqqQ3yT7JtckfU4JSjqTMpkam tqTh02LTznEluSnc7rUqa7PW9vMMeAU84Tr7dXvXTfH9+A3pUPqq9PYMKWRw6RXoCn4QDGc6 ZVZnflofsf50FjWLm9WbrZ+9I3ssxyvn5w3oDawNXblquVtzhze6bqzbBG2K29S1WWNz/ubR Ld5bjm4lbk3Z+lueaV5p3vttkds68pXzt+SP/OD9Q1OBWAG/YGi7w/baH9E/Jv3Yt8NiR+WO 74XswptFpkXlRV+LWcU3fzL7qeKn2Z3xO/tKrEsO7MLu4u4a3O28+2gptTSndGRPwJ7WMnpZ Ydn7vWv23ii3LK/dR9wn2Ces8K9or9Ss3FX5tSqxaqDarbqlRqlmR83H/ez9dw+4HGiuVa4t qv1yMOnggzrvutZ67fryQ9hDmYdeHI443POz7c+NDQoNRQ3fjnCPCI+GHO1utGlsPKZ0rKQJ bhI0TRyPOX7nhMeJ9maj5roWmZaik+Ck4OTLX2J/GTzld6rrtO3p5jNaZ2rO0s4WtkKt2a1T bYltwvao9v5zvue6Ohw6zv5q/OuR82rnqy9IXyi5SLyYf3H2Us6l6U5e5+TlhMsjXWu6Hl9Z ceV+9/Luvqt+V69f87p2pce159J1x+vnb9jfOHfT9mbbLetbrb1WvWd/s/rtbJ91X+ttm9vt d+zudPQv67941/nu5Xse967dZ9y/NRA40D8YPvhgKGZI+ID9YPxh6sM3jzIfzTze8gTzpPCp xNPyZ0rP6n/X+71FaC28MOwx3Ps89PnjEdbIqz/S//g6mv+C8qJ8THWscdx8/PyE18Sdlytf jr7ivZqZLPiT+mfNa93XZ/5y+at3asXU6Bv+m9m3xe/k3x15b/m+azp4+tmHtA8zHws/yX86 +tn2c8+XyC9jM+u/4r5WfNP71vHd7/uT2bTZWR6Tz5wfBVCIw/HxALw9AgAlCgDaHQCIYgvz 7rxBCzP6PIG/44WZeN6sATjUCUCYCwD+yLNyCwDaiIsj78Eu83HYwkLk/7T0eAvzBS1SGzKa lM/OvkNmRJweAN+GZmdn2mZnvzUgxT4CoPPDwpw9Z/5GSEwt2NPMrht9PAf8h/0Df/n0ii1B WMYAABMlSURBVHic7Z19cBTlHce/u/eS5I7kcpd3kpiEiAFBKr6gwAxFoNAKAzjVVuVlhpmi FB1stTjVWt5Sx1rbQTpTnSl9AbU6U2UEEQ1OxxlhNBUSIREjBQIBEnJJyNslucvlbu/pH89l 73K3u7d392yyOPeZm0zu2d1nf3vffX7P+/NwhBCkmGj4iTYgBZCSQSekZNAFKRl0QUoGXZCS QRekZNAFKRl0QUoGXZCSQRekZNAFxok2IBaEwOfDyEjwL8/DaAx9TKaJto8NepJhYACtrWhr Q2sr+vvh8cDjgdsd+ng84HmkpyMtLfixWJCfj/x8FBSgoADFxcjNnejHSIQJlcHvx1df4exZ nD+PCxfQ1YXr14MfrzeOeDIyYLfDbofDgcpKzJ+PBQtwyy2a2c0ebmIauj/8EIcO4Ysv0NeH oSG43fD5JE7jOCibJ3lCZibsdhQXY+NGbNjAzGZNIePG8DA5cIA8+CDJyiJpacRgIMCYD8dF hsT7iYjBaCQzZpCDB8fvGRNFexm8XtLYSH7yE2IysfzF1Ugi3mX5cnL9uuZPmgSaySAIpKOD 1NSQpUvV/vqJaRMzTnrCtGnk66+1etik0SBvIATffIPPPsP+/Th5Mhgo5+Wjw61W5OfDag0V h+hHLLl6POjpCebkCvFE3yU7G++/j4ULk35C9rCW4dQp/OtfOHwY586N3kHqB4oIrKxERQXK y1FWFvxrt8NqhdUKiwUWC3geAAiBx4PBQbS14coVtLSgvh61tbhwIRgnPUf6QTkQgunT8ckn KClh+chMYJauOjvJM8+QqVNjuIvwwOnTybPPkg8/JKdOkatXiccT900HBsjp02TfPnLHHWp9 1Nq1xOdj9tSMYCTD3r1kypRQJhz9W4RnmCUlZOtW8vnnxOlM5KeX5No18tprxG6PvFf0G5CX Rw4fVhmrb7wES9optbdj82YcORIs+Ee7oHBfcccdePFFLF4MnofBkNR9JfnyS6xdG/RR0Yi2 Pf00/vQnuTgEQXA6nX19fV6vl+M4QojZbM7Ozs7PzzebzextpqYlLkMggGPHsH49rl4FogQQ f32OQ1oabrsN1dVYtixpg2PhdOL738e5c0p50rx5ePNNTJkSfXVHR0draysAjtoP0N+Hfi0s LCwsLOR59u2hicbo8eBvf8OSJbh6VSJvpE9LCyeLFuHAAZw4MR4aACgsxFtvwW6Xzqtp4OnT aG6OOCIIwqVLl9ra2hCmAf2fpglCiNPpbGlp8UlW+JMjIRk8HuzciccfhyBIJAIx5N57sWcP /vMf3H8/G2NVcvfdeP75oDGSuN1wucIDAoFAe3t7b28vIYSTukoUo6+vr729PRAIsDU5fhm8 Xvzyl3j5ZWqddCKYPBm7duHAAaxfLx2Jz4eWFpw/j5GRhMyOxc9/DodDtqYCoK8vPMzlcnV2 dsppEHYpRwi5fv26y+VKNk8dS/wtrL/+Nf76V2qUhAYAHnoIW7firrskXsaLF1FTg9paXLqE gQEIAmw2bN+OpUsTfgBprFYsW4Z33pE9wemE3w+jEYDf7+/p6VEZMVWivb3dZrMxsZQSpwx7 9+Lvfw9mvJIa7N6NJ56I7I1xubBvH955BxcvBttTw69dtw7nzoHpUwHAzJnS4fTWYQb4/f6+ sYkjJh6Px+v1pqenJ27eWOKR4dw57N2LgQFAKkNOS8ORI1i8OPKqJ5/E669HPjy9hP7t7ERt LX74w8QfQhK5qjK9qcNBkwIhZHh4mLojZY8UFgFHCBkYGGAoQzx5wwcfhNqIRi0CAEIwdSqa miQ0ALB4MQKBYJ4hEqHK5cvx2KyO7m7pcHpTh0MMSKzkM8I0V1MtQ2srDh4Ewoof4hu9fDlq ayWL4QCwbJnsITG2ggK1Zqino0P2EM8jM1P8llhmyzaLVi1DWxtqa+n9gbDMYPVqvPEGcnJk LyQE06YpHQUwe7ZaM9TT0iJ7qLISRUXiN7PZTP1MXNGzrVGrk4EQtLQgEAglBWr0fffhz38O T+CJkJmpSWr49FOJQGr/rFm4+ebRAC4tLS2uiGlGMmnSpGQtDEOdDIIQbLGg0IeZMQP798du NBYEJf8ASBdtk+Tbb9HVJRFO355Zs5CVJYaZTKbMzEyo8zP0nLS0NIb5M9TKwHEhZ0rdUUEB ampQWhr72kAgRg58553sm/neeguIqkXTr+Xl+MEPwoONRmNOTg5Gi0DKEdPSVFFRkcpilUrU yWAwBMebiAWejz9W23kyODimmyyau+9mLIPHg1dfBaK6gAgBz2PRIsydG3GFzWZzOBzU28gp QZuVANjt9qysrImQAUBOTihBvPBCHJlqQwMg37wDYMYMxk6puhoej3RSKCzEs89GX2EwGIqL i7PCPFWEGGLFwmKxFBcXG42Mx3eplmHy5GBaFhvOVFJfD8j3TVZWhpcdGdDQgL17I6sp1JHy PB57DFVVkteZzeaKigq73W4ymcI1EBOBwWCw2+1TpkyJN0tXg2pVc3Px2GM4cwavvIKMjDju cOKE0tGZM8GwyHH9OrZsifSBYrL42c+wfbvC1UajsaKior+/v6+vz+12u91uAGaz2WQypaen Z2Vl2e12tr4oRBw9dYODpKGBuN3x9e85HEoDW37zG+L1xhehHENDZONGwvNjemHFDtFVq8jg oPrIent76+rq6urqurq6aGuHpsTj46xWzJoVn8hOJ+QaL2nCnzYNTOpBIyPYsgX79gUrNxF1 zJ/+FLt3w2pVH5/RaKQvfkZGhhZeKPJ22kb/3/8C8oOIMjPDa7OJ4/XikUfw/vtj7iX+88QT qK6G3Z5AxPRVZWBhLDSW4YsvAPn8uayMQf355EmsXo1r10KdTuI/aWl46im89BI06D1mi8b2 ff65dDjN6JKRQRDQ1YVt2zBnTkgDsQuW51FZif378fLL+tcAmqeG06elw2n6KCtDXl4i0TY3 o6YGf/xjsP0uvPcCgN2OFSvwyiuaNFVpg5YynD2L4WGl0asVFTFiGBiAxRKqY3u9qK3FsWM4 dAhffRWKh0LvsmABNm3CI48wsH8c0VKGL78E5DOGnBzpfginE0eO4OxZXL6Mvj6kpSEvD7ff juFhHD+OxkZcuRI8UxSY/q2qwi9+gZUrMXky+2fRGC1lOHFCaZR1Tg4qKyMDP/4Yzz2H5ma4 3QgfhGK1QhAwPBz8Gp7CaFa8cyfWrUNREfvG2nFB+9QQDf0Rc3LERn8ACASwYwd+9zuJsZeE YGhIIh6xPLp9O3JyboisWA7NZPB40NGhNHSusHBMferTT1FdDURVMiTHf9CG9zVrsGvXDTr1 MwLNZGhoCPmQaOioVpGeHjz8MBBrtgghMJlQWor778fzz7Op+ukDzWRobITHI3s0PX1Mu8jm zejujj3vE4DdjmPHUFzMxkjdoJk/VU4N4TL09+ODD1RpAKC3F+3tbCzUE5rJ0NwMQZA9arWG 8udDh5TODIfj4Pdj2zYG5ukMbWS4di3YIy9ZfOQ4TJ8e+vrvf8Pnk56LEAFtKTp5MkYfxg2I NjI0NwcHzcnVn+fMCf7v80HsUOR5VFVh82ZUV8Nmk/VRPT14/XXmJk8s2mTRFy/KdjPQ1rd7 7gl+NZmCgwF9vjEDkI8eDTYLRlcjAgHU1qKxMe7ODx2jWWqgI46joW1wYmoQiRgEvnWrtEOj qvzvf0HxvitoIIPXGxyYJNeukJ8fuxNm5UrcfLPSPJGDB3H+fDJm6goNZOjoCMog59znzVMV Dy0RSWbUAE6dwpEjYD35aaLQRgaxEVSS+fNVxfPQQyguVkoQf/kLnM747dMjGsjQ2Sk7mpr+ fCplMJvxq1+FrgqHanPhAt5777uRIDSQoaVF1h3R8DvvVBvV2rWYNEkpQezYAbc7ARv1BmsZ hobQ1KR0wm23xdEibbPh6aelD9ESV2+vwnz/G4hxl+Hee+OIzWTCo48Gu5TlXNPOnbh0KS4b dYgGMpw5I32I/o5Ro6ljUFERXC9PzjURgs2b44tTf7CWIWK1qXDo7yjWn1ViNmP1apSXAzIJ guPwySdKU6BvBJjKEAigsRGQr7glNkzvnnuC03Xlcv5AAH/4A3p7445ZNzCVQRBQVwfI/16z Zye4jvD69bKzWui9vv4aL72USMz6gHVqoDLIkbAMc+di4UKlIpYg4M03UVOTSOQ6gKkMPh9O nVI6IWEZALz4YnCIn1wfhtOJV1+9QfvmmMpAe9wURgpNm5b4MJabbsJTT8kepa7p6FH88583 Yr2aqQySPQQiN92E7Oyk4n/uOcycGSwdRUMDd+3Ce+8lEnl9Pa5dS8q8JGAqA11GQI6qqvDZ yAlC+93khj9xHLxebN6M48fji7ahAevXx6h4aokGqSEa+p5WVSWbGgDMn4+NG0NxRkCV6O7G o4/KLnwYjdOJDRvQ1ATW8zvVw04Gj0e2UYG+vLfcEt/cRUk4Dr/9LaZMkXVNNLy1FUuWxCi2 Ua5cwaJFOHUKhYWM56TGAzsZ5EasUiwWVUsKqKG0FLt3h+Y0REPDL1/GihU4elQpqs8+w/Tp +PZbALj11gmcD8FOBjrNTY7iYpZD7ZYuxZNPAoihREcHHngAO3agtTW0LwchwYT7zDNYuDDU Tv6jH03gotHsvKFCxkAIYxnS07FlC2prUVen1LfBccFFMt9+Gz/+Mb73PeTm4soV1NXh7bfR 3x86+fbbsXw5M/MSgNnU3qIipfnPa9Ywu5HI4cMkJ2fMLGjJu8sdFQ9lZJA33oiIe2BgoL6+ vq6ubmBggL3lUTBySu3t6O1V8g+0iZQtK1Zgz57QLSSJWLUBUZO0AGzahHXr2JsXD4xkOHlS 4oFFbDa5lSqSZc2a0Ag+lfN8IpZdfPxx/P73mtgWD4xkqKtTGg5ss2m479SmTaiuDk0/UYM4 b3fDBrz2GptlCpJjXGTIytJ2+68XXsCePaHkKCcG/fUx6qm2bcM//qGTqVqMjLh4UWl2At2U TVO2bMG77wb7lBS6S+mhoiLs34+dO7U1KR5YyNDUpDRKxWBQWnmSIQ8+iHffxapV0stgUgFy c/Hww/joI9nFwycIFvWGM2cwOCh71GQaM81NU+bPx5w5+OgjHDiAxka0tQU7xu12TJ2KuXNx 331YuVKHk3ZZyNDQIDt+G4DRGHs1AIaYTFi1CkuW4PJl9PSgry84bbSoCFOnjp8ZccJChnPn 4PfLHuV5FBYyuEtcWK249dbxvmkSJJ03OJ3B8bxyKZ3nldYsTgGAgQxXrgRXu5UrnwgCLl5U iIDW5gOj0K/JWpUcog3idjJa3zFppyRmgxGIBUSPB998g0WLJK/2+Xxut9vlcrndbkEQeJ5P T0+32WwWi4UunZ2seXHi9/u9Xq/L5eofbfhzOp3Z2dmZmZlms1mLzZUoScswODhmRRGM3RSg qgqzZ0uWlAghfX19HR0dbrc7/HUbGhrq7u5OS0srKChwOBwGLfYlk2FwcLCzs7N37LAzl8vl crl4ns/Pz8/NzdVo3b2k932rr8cDD4xZwRuAzYZ587BkCRYswF13RV9ECGlvb+/o6KB7FYW/ 9aI9HMfl5ORMnjzZNC471ff09LS2tvr9fiK1ww8NtFqtpaWlFouF+d2TlkEQcPw4amrQ0oKy MlRUoLQUDgcqKhQKSNHbq0VDn9xut5eXl2vtnVwu16VLl/x+v4JJohLl5eXM0wSjrVmHhzEy ArMZZnPMVprh4eGmpibJly4CQgjP8yUlJXmJrQWnDp/P19zcTH2jskn0hIKCgqKiIrb5BKO4 0tORlYX0dDUtZa2treq1DwQCPT09bHdwCYcQ4nK5hoaG1LwWtODU2dnJ3J7xbl8UBMHlckHR HYnQczwej0dhMZqkobuNqd9fKRAIDA4Osi3FjvfInP7+fjXvnQjHcVS5iBXMWUEIGVBoiZHB 5XI5HA6GOdZ4y5BAcuY4rrOzs7OzU4uMWqymxWWPVxznwYjxdkrMd9NkQlzpTIt69XinhgQq AYSQ3NxcuzYdR4SQCxcuxJvOmFdlxluGeDeIohlJZmZmVvLDkGXiz8jI8Hg8KpWg6cBqtU7Q pjKMyMjIMJvNKhM1PY35tlIRJLDJqs1mu7FlAFBSUoJ43HFWVpYW7QcUjuNyc3MNBkNMe2iW wHFcdnY281r0BMhgt9vp26T85PSZLRaLplVoAGazuUj1/FSDwZCfnz9xWywxpaysjGYScqUO 0R2VlJRo6pEwmiDy8vLEoYyS9nAcZzQaS0pKMjUYf8+oTSl+RkZG2tvbu0f3sSVj91zjOM5m sxUWFlrj2QkmGQRB6OrqcjqdgiBgtN0i3CSLxVJUVMQ8V6BMmAwABEEYGhrq7e3t7e2l/W50 b7XMzMy8vDyLxTI+TdwigUDA6/V2d3f39/cPj3ai0FZVh8Nhs9nYbscazkTKQBH7Pv1+P8/z BoOB47jx7O2Jtod2ytJkYTAYeJ7neV7TxvaJlyEFJiqLThFBSgZdkJJBF6Rk0AUpGXRBSgZd kJJBF6Rk0AUpGXRBSgZdkJJBF6Rk0AUpGXRBSgZdkJJBF6Rk0AUpGXRBSgZd8H/z5igvd0LG TQAAAABJRU5ErkJggg=='! ! !ROEaselMorphic methodsFor: 'accessing' stamp: 'AlexandreBergel 5/21/2012 21:20'! roassalViewWindow ^ roassalWindow! ! !ROEaselMorphic methodsFor: 'script template' stamp: 'AlexandreBergel 7/14/2012 10:24'! scriptPreambule ^ '"Preambule. It includes the initialization. " | rawView view | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "enter your script below" "-------------" "-------------" ' ! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 5/7/2013 13:56'! scriptPreambuleForMethod: compiledMethod "Return the header of the easel example with the temporary variables defined in the source code " "We assume that compiledMethod belongs to a class such as ROExample or ROMondrianExample" | temporaryVariables sourceCode cls variables | sourceCode := compiledMethod sourceCode. cls := compiledMethod methodClass. variables := cls preambleVariables. temporaryVariables := variables, (self getTempsOf: sourceCode). ^ '"Source code: ', compiledMethod methodClass name, '>>', compiledMethod selector , '"', String cr, '"Preambule. It includes the initialization. " | ', (temporaryVariables inject: '' into: [:s :e | s, e, ' ' ]), '| ', cls preamble, ' "-------------" "-------------" ' ! ! !ROEaselMorphic methodsFor: 'script template' stamp: 'AlexandreBergel 7/14/2012 14:57'! scriptPreambuleForSource: sourceCode "Return the header of the easel example with the temporary variables defined in the source code " | temporaryVariables | temporaryVariables := self getTempsOf: sourceCode. ^ '"Preambule. It includes the initialization. " | rawView view ', (temporaryVariables inject: '' into: [:s :e | s, e, ' ' ]), '| rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "enter your script below" "-------------" "-------------" ' ! ! !ROEaselMorphic methodsFor: 'buttons and menu' stamp: 'AlexandreBergel 7/4/2013 08:54'! selectCanvasOn: aStack (ROPlatform platforms size > 1) ifTrue: [ aStack addMenu: 'Select Canvas' callBack: [ :stack | | platforms index| platforms := SortedCollection sortBlock: [ :a1 :a2 | a1 key < a2 key ]. ROPlatform platforms associationsDo: [:cm | platforms add: cm key -> cm value] . index := UIManager default chooseFrom: (platforms collect: #key). index > 0 ifTrue: [ ROPlatform setCurrent: (platforms at: index) key ]. self openViewFor: CurrentWorkspace contents. ] ]! ! !ROEaselMorphic methodsFor: 'buttons and menu' stamp: 'AlexandreBergel 7/4/2013 08:54'! serializeButtonOn: aStack aStack addMenu: 'Save/Open' callBack: [ :stack | | commands index saveCommand loadCommand| commands := SortedCollection sortBlock: [ :a1 :a2 | a1 key < a2 key ]. saveCommand := ROSaveViewCommand on: aStack firstView. loadCommand := ROLoadViewCommand new. commands add: ('Save view as...' -> [ saveCommand execute ] ). commands add: ('Open...' -> [loadCommand execute. loadCommand view ifNil: [ ^ self ]. loadCommand view open ]). index := UIManager default chooseFrom: (commands collect: #key). index > 0 ifTrue: [ (commands at: index) value value ] ]! ! !ROEaselMorphic methodsFor: 'opening and closing' stamp: 'AlexandreBergel 3/30/2013 21:55'! setCallbackWhenClosing workspaceWindow announcer on: WindowClosed do: [ :ann | roassalWindow isDisplayed ifTrue: [ roassalWindow delete. self postCloseOperations ] ]! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'RobertoMinelli 10/17/2013 09:34'! showExamplesOnView: view | exampleClasses | exampleClasses := OrderedCollection with: ROMondrianExample with: ROExample. self extraPackageIsInstalled ifTrue: [ exampleClasses add: ROTreeMapBuilderExample ]. self showExamplesOnView: view forClasses: exampleClasses . ! ! !ROEaselMorphic methodsFor: 'examples' stamp: 'AlexandreBergel 10/22/2013 00:02'! showExamplesOnView: rawView forClasses: exampleClasses | view | view := ROMondrianViewBuilder view: rawView. view shape rectangle borderColor: RONIdentityNormalizer beginingAtBlue. view interaction forward. view nodes: exampleClasses forEach: [ :cls | "We give the name of the examples. Easy to distinguish the mondrian examples from the remaining" view shape label color: Color red. view node: cls name. "We iterate over the method categories" (cls organization categories copyWithout: #'--- all ---') do: [ :cat | view interaction forward. view shape rectangle borderColor: Color veryLightGray. view node: cat forIt: [ view shape label color: Color black. view node: cat. ((cls organization listAtCategoryNamed: cat) select: [ :aSym | aSym endsWith: #'On:' ]) do: [ :exampleName | | compiledMethod | compiledMethod := cls >> exampleName. view shape label text: [ :aMethod | | s | s := (aMethod perform: #selector). s copyFrom: 1 to: (s size - 'On:' size)]; color: Color gray. view interaction nodraggable; highlightWhenOver: [ :e | Array with: e ]; on: ROMouseClick do: [ :event | self changeView: rawView forExampleMethod: event element model ]. view node: compiledMethod. view verticalLineLayout gapSize: -3. ]. ]. ]. view gridLayout. ]. view gridLayout. view applyLayout. ! ! !ROEaselMorphic methodsFor: 'script template' stamp: 'AlexandreBergel 3/30/2013 21:57'! templateScript "Return the template script given in the workspace when opened" ^ self scriptPreambule, self postScript! ! !ROEaselMorphic methodsFor: 'license and info' stamp: 'AlexandreBergel 11/30/2012 17:05'! thanks ^ 'We thanks all the external contributors of Roassal. In no particular order: - Chris Thorgrimsson (Cairo integration on VisualWorks), - Emmanuel Pietriga (for all the good discussion and ideas!!) - Dennis Schenk (Tree map layout) - Juan Pablo Sandoval (integration in Spec on Pharo) - Ben (many bug fixes) - Santiago Vidal (quality check of Roassal) - Micea Lungu - Daan Smit - Tudor Girba (for all the inspiration and pair programming sessions) - Usman Bhatti - the Pleiad research group at the University of Chile We also thanks LAM Research, Cincom, Synectique, Instantiations, the Pharo Consortium, the Moose Association. Big thanks to the Pharo, VisualWorks, Moose and Amber communities for their encouragement and feedback'! ! !ROEaselMorphic methodsFor: 'accessing' stamp: 'AlexandreBergel 5/21/2012 21:44'! workspace ^ CurrentWorkspace! ! !ROEaselMorphic methodsFor: 'accessing' stamp: 'AlexandreBergel 5/21/2012 21:20'! workspaceWindow ^ workspaceWindow ! ! !ROFileOrganizer class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 12/6/2012 13:48'! current ^self allSubclasses first ! ! !ROFileOrganizer class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 12/6/2012 13:47'! deleteFile: aFilename self subclassResponsibility ! ! !ROFileOrganizerMorphic class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 12/19/2012 10:27'! deleteFile: aFilename (Smalltalk includesKey: #FileDirectory) ifTrue: [ (Smalltalk at: #FileDirectory) default deleteFileNamed: aFilename ] ifFalse: [ ((Smalltalk at: #FileSystem) disk resolve: aFilename) asFileReference delete ]! ! !ROFontOrganizer commentStamp: '' prior: 34308866! Abstract class that tells about what a font looks like! !ROFontOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 4/25/2012 15:47'! current ^ self subclasses first! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'VanessaPena 12/23/2012 21:22'! defaultFont self subclassResponsibility ! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'VanessaPena 12/23/2012 21:23'! defaultFontForSize: aNumber self subclassResponsibility ! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'VanessaPena 12/23/2012 21:22'! defaultFontSize self subclassResponsibility ! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 4/27/2012 18:02'! height self subclassResponsibility! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 5/3/2012 16:35'! offsetWhenDrawing ^ 0 @ 0! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 4/18/2012 15:50'! widthOfString: string self subclassResponsibility! ! !ROFontOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 5/6/2013 18:17'! widthOfString: string font: font "Return the length of a string" self subclassResponsibility! ! !ROFontOrganizerMorphic class methodsFor: 'public' stamp: 'VanessaPena 12/23/2012 12:42'! defaultFont ^TextStyle defaultFont. ! ! !ROFontOrganizerMorphic class methodsFor: 'public' stamp: 'AlexandreBergel 5/6/2013 18:32'! defaultFontForSize: aSize ^ StrikeFont familyName: 'Bitmap DejaVu Sans' size: aSize emphasized: 0! ! !ROFontOrganizerMorphic class methodsFor: 'public' stamp: 'VanessaPena 12/23/2012 13:45'! defaultFontSize ^14! ! !ROFontOrganizerMorphic class methodsFor: 'public' stamp: 'VanessaPena 12/22/2012 00:28'! height "Return the height of the font" ^ TextStyle defaultFont height! ! !ROFontOrganizerMorphic class methodsFor: 'public' stamp: 'AlexandreBergel 4/18/2012 14:56'! widthOfString: string "Return the length of a string" | font str | font := TextStyle defaultFont. ^ font widthOfString: string! ! !ROFontOrganizerMorphic class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 5/6/2013 18:17'! widthOfString: string font: font "Return the length of a string" ^ font widthOfString: string! ! !ROGraphTransformation commentStamp: '' prior: 34308984! A ROGraphTransformation performs some graph transformation. Really handing when you wish to transform an edge-based graph to a nesting-based one.! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 6/5/2012 10:02'! containsCycleIn: nodes with: edges "Broken so far" ^ self containsCycleIn: nodes with: edges alreadyPassedNodes: #() root: nodes first ! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 6/5/2012 10:00'! containsCycleIn: nodes with: edges alreadyPassedNodes: passedNodes root: rootNode | newNodes newPassedNode c res | nodes ifEmpty: [ ^ false ]. (passedNodes includes: rootNode) ifTrue: [ ^ true ]. newNodes := nodes. newPassedNode := passedNodes. res := false. nodes do: [ :node | (passedNodes contains: node) ifTrue: [ ^ true ]. newNodes := nodes copyWithout: rootNode. c := self getConnectedNodesFrom: node using: edges. newNodes := newNodes copyWithoutAll: c. newPassedNode := newPassedNode, (Array with: rootNode). res := res and: [self containsCycleIn: newNodes with: edges alreadyPassedNodes: passedNodes root: node] ]. ^ res ! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 6/5/2012 10:38'! containsCycleIn: rootNode with: edges passedNodes: passedNodes | c usedEdges | edges ifEmpty: [ ^ false ]. (passedNodes includes: rootNode) ifTrue: [ ^ true ]. c := self getConnectedNodesFrom: rootNode using: edges. usedEdges := edges select: [ :edge | edge from == rootNode ]. passedNodes add: rootNode. c do: [ :nr | (self containsCycleIn: nr with: (edges copyWithoutAll: usedEdges) passedNodes: passedNodes) ifTrue: [ ^ true ]. passedNodes add: nr. ]. ^ false! ! !ROGraphTransformation methodsFor: 'public' stamp: 'DennisSchenk 6/27/2012 13:39'! fromEdgesToNesting: nodes edges: edges ^ self fromEdgesToNesting: nodes edges: edges roots: (self rootNodesFor: nodes edges: edges).! ! !ROGraphTransformation methodsFor: 'public' stamp: 'DR 3/27/2013 16:49'! fromEdgesToNesting: nodes edges: edges root: root | children restOfNodes | "self assert: [ self containsCycleIn: nodes with: edges ] description: 'Cannot contain cycle'." children := self getConnectedNodesFrom: root using: edges. "Remove found children from rest of given nodes." restOfNodes := nodes copy asOrderedCollection. children do: [: n | restOfNodes remove: n ifAbsent: []]. "Recurse, do the same for all children." children := children collect: [ :child | self fromEdgesToNesting: restOfNodes edges: edges root: child ]. "Remove children from any previous parent there might be (?)." children do: [:e |e removeFromParent]. "Add children to given root, which is their new parent." children do: [ :child | root addChild: child ]. ^ root! ! !ROGraphTransformation methodsFor: 'public' stamp: 'AlexandreBergel 5/25/2013 18:51'! fromEdgesToNesting: nodes edges: edges roots: roots roots size > 1 ifTrue: [ | result | result := OrderedCollection new. roots do: [ :root | result add: (self fromEdgesToNesting: nodes edges: edges root: root) ]. ^ result ]. ^ self fromEdgesToNesting: nodes edges: edges root: roots first. ! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 6/5/2012 10:49'! getConnectedEdgesFrom: rootNode using: edges ^ (edges select: [ :edge | edge from == rootNode ])! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 6/5/2012 09:30'! getConnectedNodesFrom: rootNode using: edges ^ (edges select: [ :edge | edge from == rootNode ]) collect: #to! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'DR 1/15/2013 21:20'! hasCycleIn: nodes with: edges | connectedNodes connectedEdges runningNodes runningEdges | runningNodes := nodes. runningEdges := edges. nodes copy do: [ :n | runningNodes := runningNodes copyWithout: n. connectedNodes := self getConnectedNodesFrom: n using: runningEdges. connectedEdges := self getConnectedEdgesFrom: n using: runningEdges. (runningNodes includesAll: connectedNodes) ifFalse: [ ^ true ]. runningNodes := runningNodes copyWithoutAll: connectedNodes. runningEdges := runningEdges copyWithoutAll: connectedEdges. runningEdges ifEmpty: [ ^ false ]. runningNodes ifEmpty: [ ^ false ]. ]! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 5/25/2013 19:14'! hasIncomingEdges: node node view elementsDo: [ :element | (element isEdge and: [ element to == node ]) ifTrue: [ ^ true ] ]. ^ false! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 5/25/2013 19:15'! hasOutgoingEdges: node node view elementsDo: [ :element | (element isEdge and: [ element from == node ]) ifTrue: [ ^ true ] ]. ^ false! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 5/25/2013 19:18'! incomingEdgesOf: node ^ node view elementsSuchThat: [ :element | (element isEdge and: [ element to == node ]) ]! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'AlexandreBergel 5/25/2013 19:18'! outgoingEdgesOf: node ^ node view elementsSuchThat: [ :element | (element isEdge and: [ element from == node ]) ]! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'DennisSchenk 6/6/2012 12:41'! parentsFor: aNode edges: edges | nodes | nodes := OrderedCollection new. edges do: [ :edge | edge to == aNode ifTrue: [ nodes add: edge from ] ]. ^ nodes.! ! !ROGraphTransformation methodsFor: 'public - removing' stamp: 'AlexandreBergel 5/27/2013 08:57'! removeIntermediaryNodes: nodes "Transform a graph [A] -----> [B] ----> [C] into [A] ----> [C]" "Only works for a tree" | incomingEdges outgoingEdges | nodes do: [ :node | ((self hasIncomingEdges: node) and: [ self hasOutgoingEdges: node ]) ifTrue: [ incomingEdges := self incomingEdgesOf: node. outgoingEdges := self outgoingEdgesOf: node. self assert: [ incomingEdges size = 1 ]. self assert: [ outgoingEdges size = 1 ]. incomingEdges do: [ :edge | edge from: edge from to: outgoingEdges first to ]. outgoingEdges do: #remove. node remove ] ]! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'DennisSchenk 6/6/2012 12:44'! rootNodeFor: nodes edges: edges | rootNodes | rootNodes := self rootNodesFor: nodes edges: edges. rootNodes size > 1 ifTrue: [ self error: 'More than one root node found' ]. ^ rootNodes first.! ! !ROGraphTransformation methodsFor: 'utility' stamp: 'DennisSchenk 6/6/2012 12:43'! rootNodesFor: aNodeCollection edges: edges ^ aNodeCollection select: [:node | (self parentsFor: node edges: edges) isEmpty ].! ! !ROHTMLEdgeShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 18:00'! addToStream: aShape stream nextPutAll: '{ '; nextPutAll: ('sourceID: "<1p>"' expandMacrosWith: idNodeFrom); nextPutAll: ', '; nextPutAll: ('targetID: "<1p>"' expandMacrosWith: idNodeTo); nextPutAll: ', '; nextPutAll: ('edgeColor: "<1s>"' expandMacrosWith: (attributes at: #edgeColor)); nextPutAll: ', '; nextPutAll: ('edgeWidth: "<1p>"' expandMacrosWith: (attributes at: #edgeWidth)); nextPutAll: '},'. ! ! !ROHTMLEdgeShapeVisitor methodsFor: 'accessing' stamp: 'VanessaPena 1/31/2013 17:44'! edge: anObject edge := anObject! ! !ROHTMLEdgeShapeVisitor methodsFor: 'accessing' stamp: 'VanessaPena 1/31/2013 17:47'! idNodeFrom: anObject idNodeFrom := anObject! ! !ROHTMLEdgeShapeVisitor methodsFor: 'accessing' stamp: 'VanessaPena 1/31/2013 17:46'! idNodeTo: anObject idNodeTo := anObject! ! !ROHTMLEdgeShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 1/31/2013 18:00'! visitAbstractLine: aShape attributes at: #edgeColor put: (aShape color roValue: edge) asHTMLColor. attributes at: #edgeWidth put: (aShape widthFor: edge) . self addToStream: aShape. ! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addBorderColorToStream: aShape | nodeBorderColor | nodeBorderColor := attributes at: #borderColor. nodeBorderColor ifNotNil: [ stream nextPutAll: ', '; nextPutAll: ('nodeBorderColor: "<1s>"' expandMacrosWith: nodeBorderColor)]. ! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:36'! addBorderWidthToStream: aShape |borderWidth| borderWidth := attributes at: #borderWidth. borderWidth ifNotNil: [ stream nextPutAll: ', '; nextPutAll: ('nodeBorderWidth: "<1p>"' expandMacrosWith: borderWidth)].! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addBoundsToStream: aShape | nodeWidth nodeHeight | nodeWidth := aNode width. nodeHeight := aNode height. stream nextPutAll: ('nodeWidth: <1p>' expandMacrosWith: nodeWidth); nextPutAll: ', '; nextPutAll: ('nodeHeight: <1p>' expandMacrosWith: nodeHeight).! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addEndToStream stream nextPutAll: '},'.! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addFillColorToStream: aShape | nodeFillColor | nodeFillColor := attributes at: #fillColor. nodeFillColor ifNotNil: [ stream nextPutAll: ', '; nextPutAll: ('nodeFillColor: "<1s>"' expandMacrosWith: nodeFillColor)] .! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addInteractionToStream: aShape | draggable | draggable := aNode is: RODraggable. stream nextPutAll: ', '; nextPutAll: ('draggable: "<1p>"' expandMacrosWith: draggable).! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:07'! addNodeInfoToStream: aShape | nodeModel | nodeModel := attributes at: #text. stream nextPutAll: ('nodeID: <1p>' expandMacrosWith: nodeID); nextPutAll: ', '; nextPutAll: ('nodeParentID: <1s>' expandMacrosWith: nodeParentID). nodeModel ifNotNil: [ stream nextPutAll: ', '; nextPutAll: ('nodeModel: "<1s>"' expandMacrosWith: nodeModel)] . ! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addPositionToStream: aShape | position | position := attributes at: #position. stream nextPutAll: ('x: <1p>' expandMacrosWith: position x); nextPutAll: ', '; nextPutAll: ('y: <1p>' expandMacrosWith: position y). ! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addSeparationToStream stream nextPutAll: ', '.! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:26'! addShapeNameToStream: aShape |nodeShape| nodeShape := aShape class name asString. stream nextPutAll: ('nodeShape: "<1s>"' expandMacrosWith: nodeShape).! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:04'! addStartToStream stream nextPutAll: '{ '.! ! !ROHTMLElementShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 16:26'! addToStream: aShape self addStartToStream. self addNodeInfoToStream: aShape. self addSeparationToStream. self addShapeNameToStream: aShape. self addSeparationToStream. self addBoundsToStream: aShape. self addSeparationToStream. self addPositionToStream: aShape. self addFillColorToStream: aShape. self addBorderColorToStream: aShape. self addBorderWidthToStream: aShape. self addInteractionToStream: aShape. self addEndToStream. ! ! !ROHTMLElementShapeVisitor methodsFor: 'util' stamp: 'VanessaPena 1/31/2013 18:02'! labelOffset ^0@10! ! !ROHTMLElementShapeVisitor methodsFor: 'accesing' stamp: 'VanessaPena 1/3/2013 12:53'! node ^aNode! ! !ROHTMLElementShapeVisitor methodsFor: 'accesing' stamp: 'VanessaPena 1/3/2013 12:53'! node: node aNode := node! ! !ROHTMLElementShapeVisitor methodsFor: 'accesing' stamp: 'VanessaPena 1/31/2013 16:01'! nodeID: aNumber nodeID := aNumber ! ! !ROHTMLElementShapeVisitor methodsFor: 'accesing' stamp: 'VanessaPena 1/31/2013 16:01'! nodeParentID: aNumber nodeParentID := aNumber ! ! !ROHTMLElementShapeVisitor methodsFor: 'util' stamp: 'VanessaPena 1/31/2013 14:52'! setLabelPositionFor: aShape attributes at: #position put: ((aNode view camera virtualToRealPoint: aNode topLeft) + self labelOffset). ! ! !ROHTMLElementShapeVisitor methodsFor: 'util' stamp: 'VanessaPena 1/31/2013 14:53'! setPositionFor: aShape attributes at: #position put: (aNode view camera virtualToRealPoint: aNode topLeft). ! ! !ROHTMLElementShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 1/31/2013 16:24'! visitAbstractLabel: aShape attributes at: #borderColor put: (aShape color roValue: aNode) asHTMLColor. attributes at: #borderWidth put: nil. attributes at: #fillColor put: 'none'. attributes at: #text put: (aShape textAdaptedFor: aNode). self setLabelPositionFor: aShape. self addToStream: aShape.! ! !ROHTMLElementShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 1/31/2013 16:35'! visitBorder: aShape attributes at: #borderColor put: (aShape color roValue: aNode) asHTMLColor. attributes at: #borderWidth put: nil. attributes at: #fillColor put: 'none'. attributes at: #text put: nil. self setPositionFor: aShape. self addToStream: aShape.! ! !ROHTMLElementShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 1/31/2013 16:35'! visitBox: aShape attributes at: #borderColor put: (aShape borderColor roValue: aNode) asHTMLColor. attributes at: #borderWidth put: (aShape borderWidth roValue: aNode). attributes at: #fillColor put: (aShape colorFor: aNode) asHTMLColor. attributes at: #text put: nil. self setPositionFor: aShape. self addToStream: aShape.! ! !ROHTMLElementShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 1/31/2013 16:00'! visitCircle: aShape attributes at: #borderColor put: (aShape borderColor roValue: aNode) asHTMLColor. attributes at: #borderWidth put: (aShape borderWidth roValue: aNode). attributes at: #fillColor put: (aShape colorFor: aNode) asHTMLColor. attributes at: #text put: nil. self setPositionFor: aShape. self addToStream: aShape.! ! !ROHTMLElementShapeVisitor methodsFor: 'visit' stamp: 'VanessaPena 12/27/2012 12:52'! visitNullShape: aShape! ! !ROHTMLShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 18:05'! addToStream: aShape! ! !ROHTMLShapeVisitor methodsFor: 'accesing' stamp: 'VanessaPena 1/31/2013 18:04'! attributes ^attributes ifNil: [ attributes := Dictionary new ]! ! !ROHTMLShapeVisitor methodsFor: 'initialize-release' stamp: 'VanessaPena 1/31/2013 17:56'! initialize attributes := IdentityDictionary new.! ! !ROHTMLShapeVisitor methodsFor: 'stream' stamp: 'VanessaPena 1/31/2013 17:56'! stream: aStream stream := aStream! ! !ROIdentityMatrix commentStamp: '' prior: 34309188! A ROIdentityMatrix is essentially used by the sugiyama tree layout! !ROIdentityMatrix methodsFor: 'accessing' stamp: 'AlexandreBergel 4/18/2012 14:27'! at: u | row | row := rows at: u ifAbsentPut: [IdentityDictionary new]. ^row keys! ! !ROIdentityMatrix methodsFor: 'accessing' stamp: 'AlexandreBergel 4/18/2012 14:27'! at: u at: v | row | row := rows at: u ifAbsentPut: [IdentityDictionary new]. ^row at: v ifAbsent: [false]! ! !ROIdentityMatrix methodsFor: 'accessing' stamp: 'AlexandreBergel 4/18/2012 14:27'! at: u at: v put: aBoolean | row | "u -> v" row := rows at: u ifAbsentPut: [IdentityDictionary new]. row at: v put: aBoolean. "v -> u" row := rows at: v ifAbsentPut: [IdentityDictionary new]. row at: u put: aBoolean! ! !ROIdentityMatrix methodsFor: 'initialize-release' stamp: 'AlexandreBergel 4/18/2012 14:27'! initialize rows := IdentityDictionary new! ! !ROAbstractDynamicEdge class methodsFor: 'public' stamp: 'AlexandreBergel 5/19/2013 15:04'! fromAll: elements using: aLineShape ^ self new fromAll: elements using: aLineShape! ! !ROAbstractDynamicEdge class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 09:17'! to: element ^ self toAll: (Array with: element) using: ROLine black! ! !ROAbstractDynamicEdge class methodsFor: 'public' stamp: 'AlexandreBergel 4/7/2013 00:54'! toAll: elements using: aLineShape ^ self new toAll: elements using: aLineShape! ! !ROAbstractDynamicEdge methodsFor: 'util' stamp: 'miltonmamani 4/17/2013 14:45'! attributeKey ^ (#dynamicEdges, self hash printString) asSymbol! ! !ROAbstractDynamicEdge methodsFor: 'public' stamp: 'AlexandreBergel 5/17/2013 18:16'! edges "Return the edges that have been added" ^ edges! ! !ROAbstractDynamicEdge methodsFor: 'public' stamp: 'AlexandreBergel 5/19/2013 15:24'! fromAll: oneArgBlockOrValues using: aLineShape fromAllElements := oneArgBlockOrValues. lineShape := aLineShape! ! !ROAbstractDynamicEdge methodsFor: 'initialize-release' stamp: 'AlexandreBergel 5/19/2013 15:27'! initialize super initialize. fromAllElements := [ :el | Array with: el ]. toAllElements := [ :el | Array with: el ]! ! !ROAbstractDynamicEdge methodsFor: 'hooks' stamp: 'AlexandreBergel 5/19/2013 15:45'! initializeElement: element element on: ROMouseEnter do: [ :event | self removeEdgesFromView: event view. edges := OrderedCollection new. (toAllElements roValue: element) do: [ :toElement | (fromAllElements roValue: element) do: [ :fromElement | | l | event view add: (l := lineShape elementFrom: fromElement to: toElement). self processCreatedEdge: l. edges add: l. ]. ]. " edges := (toAllElements roValue: element) collect: [ :el | | l | event view add: (l := lineShape elementFrom: event element to: el). self processCreatedEdge: l. l ]. " event view attributes at: self attributeKey put: edges. event view signalUpdate ]. element on: ROMouseLeave do: [ :event | self removeEdgesFromView: event view. event view signalUpdate ]. ! ! !ROAbstractDynamicEdge methodsFor: 'hooks' stamp: 'AlexandreBergel 5/17/2013 18:25'! processCreatedEdge: element self subclassResponsibility! ! !ROAbstractDynamicEdge methodsFor: 'util' stamp: 'AlexandreBergel 4/10/2013 16:41'! removeEdgesFromView: view (view attributes includesKey: self attributeKey) ifTrue: [ (view attributes at: self attributeKey) do: #remove ]. view attributes removeKey: self attributeKey ifAbsent: [ ]! ! !ROAbstractDynamicEdge methodsFor: 'public' stamp: 'AlexandreBergel 5/19/2013 15:24'! toAll: oneArgBlockOrValues using: aLineShape toAllElements := oneArgBlockOrValues. lineShape := aLineShape! ! !RODynamicEdge methodsFor: 'hooks' stamp: 'AlexandreBergel 5/17/2013 18:25'! processCreatedEdge: element "Do nothing"! ! !RODynamicFadingEdge methodsFor: 'hooks' stamp: 'AlexandreBergel 5/17/2013 18:29'! processCreatedEdge: element ROColorAlphaFading new for: element nbCycles: 60! ! !ROAbstractExpandChildrenOnClick class methodsFor: 'instance creation' stamp: 'AlexandreBergel 6/21/2012 15:41'! childrenBlock: aBlock ^self new childrenBlock: aBlock; yourself.! ! !ROAbstractExpandChildrenOnClick class methodsFor: 'instance creation' stamp: 'AlexandreBergel 10/7/2012 13:10'! childrenForModel: aBlock ^ self childrenBlock: [ :el | | children | children := aBlock value: el model. children collect: [:c | (ROElement on: c) + ROLabel + ROBox] ]! ! !ROAbstractExpandChildrenOnClick methodsFor: 'initialization' stamp: 'AlexandreBergel 6/21/2012 15:41'! addChildren: newNode to: element | edge line | self adjustNode: newNode. element view add: newNode. line := ROLine new. edge := (ROEdge from: element to: newNode) + line. line attachPoint: ROVerticalAttachPoint new. element view add: edge. ^ newNode! ! !ROAbstractExpandChildrenOnClick methodsFor: 'initialization' stamp: 'AlexandreBergel 6/21/2012 15:40'! addChildrenFromModel: model to: element | newNode edge line | newNode := ROElement spriteOn: model. newNode + ROLabel @ (ROExpandChildrenOnClick childrenBlock: childrenBlock). element view add: newNode. line := ROLine new. edge := (ROEdge from: element to: newNode) + line. line attachPoint: ROVerticalAttachPoint new. element view add: edge. ^ newNode! ! !ROAbstractExpandChildrenOnClick methodsFor: 'hooks' stamp: 'AlexandreBergel 6/21/2012 15:41'! adjustNode: node self subclassResponsibility ! ! !ROAbstractExpandChildrenOnClick methodsFor: 'accessing' stamp: 'AlexandreBergel 6/21/2012 15:40'! childrenBlock ^ childrenBlock! ! !ROAbstractExpandChildrenOnClick methodsFor: 'accessing' stamp: 'AlexandreBergel 6/21/2012 15:40'! childrenBlock: anObject childrenBlock := anObject! ! !ROAbstractExpandChildrenOnClick methodsFor: 'accessing' stamp: 'AlexandreBergel 10/7/2012 12:57'! computeChildrenFor: element ^ childrenBlock value: element! ! !ROAbstractExpandChildrenOnClick methodsFor: 'initialization' stamp: 'AlexandreBergel 6/21/2012 15:40'! initializeElement: element element on: ROMouseClick do: [:event | | elements newElements roElements | newElements := childrenBlock value: element. roElements := newElements collect: [:children | self addChildren: children to: element ]. roElements do: [ :el | el translateTo: element position]. elements := element view elementsSuchThat: #notNil. ROTreeLayout new translator: ROSmoothLayoutTranslator new; applyOn: elements. element signalUpdate. ].! ! !ROExpandChildrenOnClick methodsFor: 'hooks' stamp: 'AlexandreBergel 6/21/2012 15:41'! adjustNode: node ! ! !RORecursiveExpandOnClick methodsFor: 'hooks' stamp: 'AlexandreBergel 6/21/2012 15:41'! adjustNode: node node @ (ROExpandChildrenOnClick childrenBlock: childrenBlock).! ! !ROAbstractPopup class methodsFor: 'configuration' stamp: 'AlexandreBergel 5/1/2012 10:46'! defaultPopupOffset ^ 10 @ 10! ! !ROAbstractPopup class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/17/2013 12:06'! popups ^ popups ifNil: [ popups := OrderedCollection new ]! ! !ROAbstractPopup class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/17/2013 12:04'! resetPopups popups := nil! ! !ROAbstractPopup methodsFor: 'accessing' stamp: 'AlexandreBergel 7/19/2013 19:57'! afterCreationBlock: aOneArgBlock "The parameter block is evaluated with the popup after being added in the view but before the view has been refreshed" afterCreationBlock := aOneArgBlock! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'AlexandreBergel 10/3/2013 18:22'! closestPositionOf: el from: realPosition in: aView "Return the closest position for el to realPosition to be entierely visible in the view" | idealVirtualPosition virtualPositionX virtualPositionY winSize | idealVirtualPosition := (aView camera realToVirtualPoint: realPosition). winSize := aView camera windowSize. "If the popup is larger than the window, then there is not much we can do" (el width > winSize x or: [ el height > winSize y ]) ifTrue: [ ^ idealVirtualPosition + self popupOffset ]. "Check if the element is within the width of the view" virtualPositionX := ((idealVirtualPosition x + el width + self popupOffset x) < winSize x) ifTrue: [ idealVirtualPosition x + self popupOffset x ] ifFalse: [ idealVirtualPosition x - el width - self popupOffset x ]. (aView camera realToVirtualPoint: virtualPositionX @ 0) x < 0 ifTrue: [ virtualPositionX := idealVirtualPosition x + self popupOffset x ]. virtualPositionY := ((idealVirtualPosition y + el height + self popupOffset y) < winSize y) ifTrue: [ idealVirtualPosition y + self popupOffset y ] ifFalse: [ idealVirtualPosition y - el height - self popupOffset y ]. (aView camera realToVirtualPoint: 0 @ virtualPositionY) y < 0 ifTrue: [ virtualPositionY := idealVirtualPosition y + self popupOffset y ]. ^ virtualPositionX @ virtualPositionY! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'AlexandreBergel 7/19/2013 19:56'! createAndShowPopupFor: element event: event | popupPosition el | self removeAllPopups. el := self createPopupFor: element. popupPosition := self closestPositionOf: el from: event realPosition in: (self receivingViewFor: element). el translateTo: popupPosition. afterCreationBlock roValue: el. ^ el signalUpdate! ! !ROAbstractPopup methodsFor: 'hooks'! createElementFor: element self subclassResponsibility! ! !ROAbstractPopup methodsFor: 'creation' stamp: 'AlexandreBergel 6/1/2012 18:32'! createPopupFor: element | el | el := self createElementFor: element. el on: ROMouseLeave do: [ :e | el view remove: el ifAbsent: [ ] ]. (self receivingViewFor: element) add: el. self popups add: el. ^ el! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'AlexandreBergel 7/19/2013 19:55'! initialize super initialize. afterCreationBlock := #yourself. receivingView := [ :element | element view ]. ! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'miltonMamani 6/25/2013 14:48'! initializeElement: element element on: ROMouseEnter do: [ :event | self createAndShowPopupFor: element event: event ]. element on: ROMouseLeave do: [ :event | self removePopupFor: element ]. element on: ROMouseDragging do: [ :event | self removeAllPopups ]! ! !ROAbstractPopup methodsFor: 'configuration' stamp: 'AlexandreBergel 1/2/2013 09:02'! popupOffset "Return a point representing the offset of the popup" ^ self class defaultPopupOffset! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'VanessaPena 1/17/2013 12:04'! popups ^ self class popups! ! !ROAbstractPopup methodsFor: 'accessing' stamp: 'AlexandreBergel 10/7/2013 19:10'! receivingView: roassalView "roassalView corresponds to the view in which the popup has to be added. For example, in case a view belongs to a stack, then the popup should probably be displayed in the stack." receivingView := roassalView! ! !ROAbstractPopup methodsFor: 'creation' stamp: 'AlexandreBergel 6/1/2012 18:30'! receivingViewFor: element "Return the view in which the popup has to be added. Per default this view is the view in which the element is contained. However, this may be different, especially when contained in a stack" ^ receivingView roValue: element! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'VanessaPena 1/17/2013 12:04'! removeAllPopups self popups do: [ :p | self removePopup: p ]. self class resetPopups! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'AlexandreBergel 12/11/2012 11:48'! removePopup: el el ifNotNil: [ el remove ].! ! !ROAbstractPopup methodsFor: 'initialization' stamp: 'miltonMamani 6/25/2013 14:48'! removePopupFor: element self removeAllPopups. ^ element signalUpdate! ! !ROPopup class methodsFor: 'public'! text: txtBlock ^ self new text: txtBlock; yourself! ! !ROPopup methodsFor: 'accessing' stamp: 'DennisSchenk 10/2/2012 13:02'! box ^ box! ! !ROPopup methodsFor: 'accessing' stamp: 'DennisSchenk 10/2/2012 13:03'! box: aROBox box := aROBox.! ! !ROPopup methodsFor: 'creation' stamp: 'DennisSchenk 10/2/2012 16:39'! createElementFor: element ^ ROElement new add: (ROElement new + ((ROLabel text: (text roValue: element model)) color: textColor)) + box copy; yourself! ! !ROPopup methodsFor: 'initialization' stamp: 'DennisSchenk 10/2/2012 16:35'! initialize super initialize. text := #yourself. textColor := Color white. box := ROBox new.! ! !ROPopup methodsFor: 'accessing'! text ^ text! ! !ROPopup methodsFor: 'accessing'! text: anObject text := anObject! ! !ROPopup methodsFor: 'accessing'! textColor ^ textColor! ! !ROPopup methodsFor: 'accessing'! textColor: anObject textColor := anObject! ! !ROPopupView class methodsFor: 'public' stamp: 'AlexandreBergel 7/6/2012 13:51'! view: v ^ self new view: v! ! !ROPopupView methodsFor: 'hooks' stamp: 'AlexandreBergel 5/18/2013 07:00'! createElementFor: element | v extent encompassingRectangle | "We need here to have a proper extent here." v := (view roValue: element) view. encompassingRectangle := v encompassingRectangle. extent := encompassingRectangle corner asIntegerPoint + (1 @ 1). ^ (ROElement new extent: extent) + (ROViewDisplayer new view: v; yourself). ! ! !ROPopupView methodsFor: 'initialization' stamp: 'AlexandreBergel 4/5/2013 14:56'! initialize super initialize. view := ROView nullView.! ! !ROPopupView methodsFor: 'accessing'! view ^ view! ! !ROPopupView methodsFor: 'accessing'! view: aView view := aView! ! !ROAddName class methodsFor: 'public' stamp: 'AlexandreBergel 5/19/2013 13:57'! hasName: anElement ^ self new hasName: anElement! ! !ROAddName class methodsFor: 'public' stamp: 'AlexandreBergel 5/7/2013 19:02'! removeFrom: anElement (anElement attributes includesKey: #addedName) ifTrue: [ (anElement attributes at: #addedName) do: #remove. anElement attributes removeKey: #addedName ]! ! !ROAddName class methodsFor: 'public' stamp: 'AlexandreBergel 5/19/2013 13:56'! toElement: anElement ^ self new toElement: anElement! ! !ROAddName methodsFor: 'accessing' stamp: 'AlexandreBergel 7/17/2013 10:20'! block ^ block! ! !ROAddName methodsFor: 'accessing' stamp: 'AlexandreBergel 7/17/2013 10:24'! block: aOneArgBlock "The block is used to get the name of the element to add. It is initialized with the value defaultBlock" block := aOneArgBlock! ! !ROAddName methodsFor: 'accessing' stamp: 'AlexandreBergel 5/19/2013 13:55'! color: aColor color := aColor! ! !ROAddName methodsFor: 'configuration' stamp: 'AlexandreBergel 7/17/2013 10:18'! defaultBlock ^ [ :el | el model printString ]! ! !ROAddName methodsFor: 'configuration' stamp: 'AlexandreBergel 7/17/2013 10:18'! defaultColor ^ Color black! ! !ROAddName methodsFor: 'util' stamp: 'AlexandreBergel 7/17/2013 10:19'! getNewLabelFor: anElement | label | label := ROElement on: (block roValue: anElement). label + self getNewLabelShape + ROBox white. ^ label! ! !ROAddName methodsFor: 'util' stamp: 'AlexandreBergel 5/19/2013 13:58'! getNewLabelShape ^ ROLabel new color: color! ! !ROAddName methodsFor: 'testing' stamp: 'AlexandreBergel 5/19/2013 13:57'! hasName: anElement ^ anElement attributes includesKey: #addedName! ! !ROAddName methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/17/2013 10:18'! initialize super initialize. color := self defaultColor. block := self defaultBlock! ! !ROAddName methodsFor: 'public' stamp: 'AlexandreBergel 7/17/2013 10:19'! toElement: anElement | label | "Do nothing if it has already a name" (self hasName: anElement) ifTrue: [ ^ self ]. label := self getNewLabelFor: anElement. (anElement attributes includesKey: #addedName) ifFalse: [ anElement attributes at: #addedName put: OrderedCollection new ]. (anElement attributes at: #addedName) add: label. anElement view add: label. ROConstraint stick: label below: anElement! ! !ROAllConnectedNodeDraggable methodsFor: 'hooks' stamp: 'AlexandreBergel 10/21/2013 14:29'! initializeElement: element element on: ROElementTranslated do: [ :event | event element allEdgesFrom do: [ :edge | edge to translateBy: event step ] ]! ! !ROAllRecursivelyConnectedNodeDraggable methodsFor: 'utils' stamp: 'AlexandreBergel 10/21/2013 21:25'! computeAllRecursivelyConnectedNodesOf: element "Return all the list of connected nodes. Take care to not fall into recursive loops. The element provided as argument is not part of the result" | t | t := self computeWithAllRecursivelyConnectedNodesOf: element. t := t copyWithout: element. ^ t ! ! !ROAllRecursivelyConnectedNodeDraggable methodsFor: 'utils' stamp: 'AlexandreBergel 10/21/2013 21:25'! computeWithAllRecursivelyConnectedNodesOf: element "Return all the list of connected nodes. Take care to not fall into recursive loops. The element provided as argument is part of the result" | res | res := OrderedCollection new. self computeWithAllRecursivelyConnectedNodesOf: element visitedNodes: res. ^ res! ! !ROAllRecursivelyConnectedNodeDraggable methodsFor: 'utils' stamp: 'AlexandreBergel 10/21/2013 21:23'! computeWithAllRecursivelyConnectedNodesOf: element visitedNodes: visitedNodes (visitedNodes includes: element) ifTrue: [ ^ self ]. visitedNodes add: element. element allEdgesFrom do: [ :edge | self computeWithAllRecursivelyConnectedNodesOf: edge to visitedNodes: visitedNodes ]! ! !ROAllRecursivelyConnectedNodeDraggable methodsFor: 'hooks' stamp: 'AlexandreBergel 10/21/2013 21:20'! initializeElement: element element on: ROElementTranslated do: [ :event | (event element hasAttribute: #allRecursivelyConnectedNodes) ifFalse: [ | t | t := self computeAllRecursivelyConnectedNodesOf: event element. t := t copyWithout: event element. event element attributeAt: #allRecursivelyConnectedNodes put: t ]. (event element attributeAt: #allRecursivelyConnectedNodes) do: [ :ele | ele translateBy: event step ] ]! ! !ROAnimatedResizing class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:16'! for: aROElement resize: aPoint ^ self for: aROElement resizeAndFixTopLeft: aPoint! ! !ROAnimatedResizing class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:16'! for: aROElement resizeAndFixBottomLeft: aPoint ROLinearMove for: aROElement to: (aROElement position + (0 @ aROElement extent y)- (0 @ aPoint y)). ^ self new for: aROElement newSize: aPoint! ! !ROAnimatedResizing class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:14'! for: aROElement resizeAndFixBottomRight: aPoint ROLinearMove for: aROElement to: (aROElement position + aROElement extent - aPoint). ^ self new for: aROElement newSize: aPoint! ! !ROAnimatedResizing class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:34'! for: aROElement resizeAndFixTopLeft: aPoint ^ self new for: aROElement resize: aPoint! ! !ROAnimatedResizing class methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:15'! for: aROElement resizeAndFixTopRight: aPoint ROLinearMove for: aROElement to: (aROElement position + (aROElement extent x @ 0) - (aPoint x @ 0)). ^ self new for: aROElement newSize: aPoint! ! !ROAnimatedResizing methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:00'! after element extent: finalSize! ! !ROAnimatedResizing methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:01'! doStep element extent: (element extent + increment). element signalUpdate.! ! !ROAnimatedResizing methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:01'! element ^ element! ! !ROAnimatedResizing methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:00'! for: aROElement newSize: finalSizeAsPoint | p | element := aROElement. p := finalSizeAsPoint - element extent. increment := (p x / nbCycles) @ (p y / nbCycles). remainingCycles := nbCycles. finalSize := finalSizeAsPoint. aROElement view addAnimation: self! ! !ROAnimatedResizing methodsFor: 'public' stamp: 'AlexandreBergel 8/28/2013 18:34'! for: aROElement resize: finalSizeAsPoint | p | element := aROElement. p := finalSizeAsPoint - element extent. increment := (p x / nbCycles) @ (p y / nbCycles). remainingCycles := nbCycles. finalSize := finalSizeAsPoint. aROElement view addAnimation: self! ! !ROAnimation methodsFor: 'action' stamp: 'AlexandreBergel 5/2/2013 19:15'! addedIn: aView "I m added in a view" strategy added: self in: aView! ! !ROAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 5/7/2013 14:50'! after: aBlock "The after block is used to do something after the animation has completed" afterBlock := aBlock! ! !ROAnimation methodsFor: 'hooks'! defaultNumberOfCycles ^ 10! ! !ROAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 11/30/2012 17:54'! doAfter afterBlock value! ! !ROAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 11/30/2012 19:07'! doCycle self hasCompleted ifFalse: [ remainingCycles := remainingCycles - 1. self doStep. self hasCompleted ifTrue: [ self doAfter ] ]! ! !ROAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 12/1/2012 11:35'! doStep "To be overriden"! ! !ROAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:16'! elapsedCycles ^ nbCycles - remainingCycles! ! !ROAnimation methodsFor: 'testing'! hasCompleted ^ remainingCycles = 0! ! !ROAnimation methodsFor: 'initialization' stamp: 'AlexandreBergel 5/2/2013 19:00'! initialize super initialize. self nbCycles: self defaultNumberOfCycles. afterBlock := #yourself. strategy := ROAnimationAppend instance! ! !ROAnimation methodsFor: 'accessing'! nbCycles ^ nbCycles! ! !ROAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 11/30/2012 19:06'! nbCycles: integer nbCycles := integer. remainingCycles := integer! ! !ROAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 5/2/2013 18:58'! strategy "Return the merging strategy associated to this animation" ^ strategy! ! !ROAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 5/2/2013 19:04'! strategy: anAnimationStrategy "Set a new strategy when merging animations" strategy := anAnimationStrategy ! ! !ROColorAlphaFading methodsFor: 'hooks' stamp: 'AlexandreBergel 5/18/2013 08:07'! doStep (alpha < 0.0 and: [ alpha > 1.0 ]) ifTrue: [ ^ self ]. self setAlpha: alpha to: element. alpha := alpha + increment. ! ! !ROColorAlphaFading methodsFor: 'public' stamp: 'AlexandreBergel 5/18/2013 08:05'! for: anElement nbCycles: integer self nbCycles: integer. element := anElement. increment := (1 / nbCycles) asFloat. alpha := 0. self setAlpha: 0.0 to: anElement. anElement view addAnimation: self. ! ! !ROColorAlphaFading methodsFor: 'hooks' stamp: 'AlexandreBergel 5/18/2013 08:07'! setAlpha: alphaValue to: anElement "alphaValue is a float between 0.0 and 1.0. 1.0 there is no alpha, the color is not transparent. With 0.0 the color is completely transparent" | shape | shape := element getShape: ROShape. shape color: ((shape color roValue: element) alpha: alpha). element signalUpdate ! ! !ROFunctionMove methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:28'! blockX ^ blockX! ! !ROFunctionMove methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:29'! blockX: aBlock blockX := aBlock! ! !ROFunctionMove methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:29'! blockY ^ blockY! ! !ROFunctionMove methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:29'! blockY: aBlock blockY := aBlock! ! !ROFunctionMove methodsFor: 'hooks' stamp: 'AlexandreBergel 12/1/2012 16:31'! doStep element translateTo: ((blockX roValue: self elapsedCycles) @ (blockY roValue: self elapsedCycles))! ! !ROFunctionMove methodsFor: 'initialization' stamp: 'AlexandreBergel 12/1/2012 16:32'! initialize super initialize. blockX := [ :elapsed | elapsed ]. blockY := [ :elapsed | elapsed ].! ! !ROFunctionMove methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:22'! on: anElement element := anElement. element view addAnimation: self.! ! !ROIncrementalZoomMove methodsFor: 'public' stamp: 'VanessaPena 1/8/2013 11:53'! on: view | v | v := view camera bounds. v := (v origin + self step) corner: (v corner - self step). ROZoomMove new nbCycles: nbCycles; on: view to: v! ! !ROIncrementalZoomMove methodsFor: 'stepping and presenter' stamp: 'AlexandreBergel 8/27/2013 21:41'! step self subclassResponsibility ! ! !ROZoomInMove methodsFor: 'config'! step ^ 40 @ 40! ! !ROZoomOutMove methodsFor: 'config'! step ^ -40 @ -40! ! !ROLinearMove commentStamp: 'AlexandreBergel 11/28/2011 10:50' prior: 34309329! ROLinearMove moves an element in a number of cycles. Example of usage: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | view el | view := ROView new. el := ROElement sprite. view add: el. view on: ROMouseLeftClick do: [ :event | ROLinearMove new nbCycles: 180; for: el until: event position. ]. view open. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=! !ROLinearMove class methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 21:22'! for: element by: position ^ self new for: element by: position! ! !ROLinearMove class methodsFor: 'public' stamp: 'AlexandreBergel 11/30/2012 17:36'! for: element to: position ^ self new for: element to: position! ! !ROLinearMove methodsFor: 'hooks' stamp: 'AlexandreBergel 5/7/2013 14:52'! after element translateTo: finalPosition.! ! !ROLinearMove methodsFor: 'hooks' stamp: 'AlexandreBergel 11/30/2012 17:54'! doStep element translateBy: increment. element signalUpdate.! ! !ROLinearMove methodsFor: 'accessing' stamp: 'AlexandreBergel 11/30/2012 17:56'! element ^ element! ! !ROLinearMove methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 21:22'! for: anElement by: aPoint self for: anElement to: (anElement position + aPoint)! ! !ROLinearMove methodsFor: 'public' stamp: 'miltonmamani 4/17/2013 15:31'! for: anElement to: aFinalPosition | p | element := anElement. p := aFinalPosition - anElement position. increment := (p x / nbCycles) @ (p y / nbCycles). remainingCycles := nbCycles. finalPosition := aFinalPosition. anElement view addAnimation: self! ! !ROMotionMove methodsFor: 'hooks' stamp: 'AlexandreBergel 12/1/2012 11:34'! doStep element translateBy: (speedPoint / increment) asIntegerPoint. increment := increment + 1.! ! !ROMotionMove methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 10:59'! for: anElement initialSpeed: aSpeedPoint "Apparently problem may occur" aSpeedPoint isNil ifTrue: [ ^self]. element := anElement. speedPoint := aSpeedPoint. increment := 1. anElement view addAnimation: self.! ! !ROMotionMove methodsFor: 'testing' stamp: 'AlexandreBergel 8/8/2013 18:22'! hasCompleted ^ (speedPoint / increment) r <= 2 or: [ self isTakingTooLong ]! ! !ROMotionMove methodsFor: 'initialization' stamp: 'AlexandreBergel 8/8/2013 18:21'! initialize super initialize. initialTime := Time millisecondClockValue! ! !ROMotionMove methodsFor: 'testing' stamp: 'AlexandreBergel 8/8/2013 18:22'! isTakingTooLong ^ (Time millisecondClockValue - initialTime) > 80 ! ! !RONopAnimation commentStamp: 'AlexandreBergel 12/1/2012 15:49' prior: 34309742! RONopAnimation is a do nothing animation. Useful to simulate a pause between two animations! !RONopAnimation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:01'! on: aView aView addAnimation: self! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:06'! block ^ block! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 12/1/2012 16:06'! block: anObject block := anObject! ! !ROPluggableAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 1/23/2013 16:47'! doStep nbIterations := nbIterations + 1. nbIterations >= nbIterationsBeforeRefresh ifTrue: [ block value. nbIterations := 0 ]! ! !ROPluggableAnimation methodsFor: 'initialization' stamp: 'AlexandreBergel 1/23/2013 16:46'! initialize super initialize. nbIterations := 0. nbIterationsBeforeRefresh := 0! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:46'! nbIterations ^ nbIterations! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:46'! nbIterations: anObject nbIterations := anObject! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:46'! nbIterationsBeforeRefresh ^ nbIterationsBeforeRefresh! ! !ROPluggableAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:46'! nbIterationsBeforeRefresh: anObject nbIterationsBeforeRefresh := anObject! ! !ROPluggableAnimation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:08'! on: aView aView addAnimation: self! ! !ROTranslation commentStamp: 'VanessaPena 8/26/2012 09:44' prior: 34309904! A ROFunctionMove is just a test, is not a complete interaction yet :) ! !ROTranslation methodsFor: 'hooks' stamp: 'VanessaPena 8/23/2012 16:21'! defaultNumberOfCycles ^ 100! ! !ROTranslation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:22'! for: element function: aBlock intervalIni: ini IntervalEnd: end | xIncrement yIncrement position | [ xIncrement := ((end - ini)/ nbCycles) asFloat . yIncrement := (aBlock value: ini). remainingCycles := nbCycles + 1. (1 to: nbCycles) do: [ :i | yIncrement := ((aBlock value: xIncrement * i)) - yIncrement. element translateBy: xIncrement @ yIncrement. element signalUpdate. remainingCycles := remainingCycles - 1. (Delay forMilliseconds: 30) wait. ]. remainingCycles := remainingCycles - 1. ] fork ! ! !ROTranslation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:27'! for: element function: aBlock intervalIni: ini IntervalEnd: end XFactor: factor |xIncrement yIncrement position| [ xIncrement := ((end - ini)/ nbCycles) asFloat. "xIncrement inspect ." yIncrement := (aBlock value: ini). remainingCycles := nbCycles + 1. (1 to: nbCycles) do: [ :i | yIncrement := ((aBlock value: xIncrement * i)) - yIncrement. element translateBy: (xIncrement * factor)@ yIncrement. element signalUpdate. remainingCycles := remainingCycles - 1. (Delay forMilliseconds: 30) wait. ]. remainingCycles := remainingCycles - 1. ] fork ! ! !ROTranslation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:27'! for: element functionX: aXBlock Y: aYBlock intervalIni: ini IntervalEnd: end |xIncrement yIncrement position increment| [ increment := ((end - ini)/ nbCycles) asFloat. yIncrement := (aYBlock value: ini). xIncrement := (aXBlock value: ini). remainingCycles := nbCycles + 1. (1 to: nbCycles) do: [ :i | yIncrement := ((aYBlock value: (increment * i)) - yIncrement) asFloat. xIncrement := ((aXBlock value: (increment * i)) - xIncrement) asFloat. element translateBy: (xIncrement@ yIncrement). element signalUpdate. remainingCycles := remainingCycles - 1. (Delay forMilliseconds: 30) wait. ]. remainingCycles := remainingCycles - 1. ] fork ! ! !ROTranslation methodsFor: 'public' stamp: 'AlexandreBergel 12/1/2012 16:27'! for: element functionXY: aBlock intervalIni: ini IntervalEnd: end XFactor: factor |xIncrement yIncrement position| [ xIncrement := ((end - ini)/ nbCycles) asFloat. "xIncrement inspect ." yIncrement := (aBlock value: ini). remainingCycles := nbCycles + 1. (1 to: nbCycles) do: [ :i | yIncrement := ((aBlock value: xIncrement * i)) - yIncrement. element translateBy: (xIncrement * factor)@ 0. element signalUpdate. remainingCycles := remainingCycles - 1. (Delay forMilliseconds: 30) wait. ]. remainingCycles := remainingCycles - 1. ] fork ! ! !ROTranslation methodsFor: 'public' stamp: 'AlexandreBergel 11/30/2012 17:34'! for: element to: endPosition ! ! !ROWiggle class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 09:56'! on: element ^ self new on: element! ! !ROWiggle class methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 10:13'! onAll: anArray anArray do: [ :el | self on: el ]! ! !ROWiggle methodsFor: 'hooks' stamp: 'AlexandreBergel 5/22/2013 09:59'! doStep remainingCycles odd ifTrue: [ element translateBy: (3 @ 0) ] ifFalse: [ element translateBy: (-3 @ 0) ]. element signalUpdate.! ! !ROWiggle methodsFor: 'public' stamp: 'AlexandreBergel 5/22/2013 09:57'! on: anElement element := anElement. anElement view addAnimation: self! ! !ROZoomMove methodsFor: 'hooks' stamp: 'VanessaPena 12/23/2012 20:21'! doStep |oldBounds| oldBounds := camera bounds. topLeft := topLeft + incrementX1Y1. bottomRight := bottomRight + incrementX2Y2. camera bounds: (topLeft asIntegerPoint corner: bottomRight asIntegerPoint). view announce: (ROCameraResized new oldBounds: oldBounds; newBounds: camera bounds) ! ! !ROZoomMove methodsFor: 'initialization'! initialize super initialize. nbCycles := 50.! ! !ROZoomMove methodsFor: 'public' stamp: 'DR 1/16/2013 19:11'! on: aView to: finalRealBounds | initialRealBounds animBlock | camera := aView camera. view := aView. initialRealBounds := camera bounds. incrementX1Y1 := ((finalRealBounds topLeft - initialRealBounds topLeft) / nbCycles). incrementX2Y2 := ((finalRealBounds bottomRight - initialRealBounds bottomRight) / nbCycles). topLeft := initialRealBounds topLeft. bottomRight := initialRealBounds bottomRight. aView addAnimation: self.! ! !RODraggable class methodsFor: 'public' stamp: 'AlexandreBergel 6/21/2013 16:44'! elementToBeAdded instance ifNil: [ instance := self new ]. ^ instance! ! !RODraggable methodsFor: 'hooks' stamp: 'AlexandreBergel 6/21/2013 16:36'! initializeElement: element element on: ROMouseDragging do: [ :event | element translateByRealPoint: event step. element signalUpdate ]! ! !RODraggableWithVelocity class methodsFor: 'public' stamp: 'AlexandreBergel 8/8/2013 17:50'! elementToBeAdded instance ifNil: [ instance := self new ]. ^ instance! ! !RODraggableWithVelocity methodsFor: 'initialization' stamp: 'AlexandreBergel 5/3/2013 08:51'! initializeElement: element | lastStep | element on: ROMouseDragging do: [:event | lastStep := event step. "lastTimeStamp := ROPlatform current timeOrganizerClass milliseconds "]. element on: ROMouseDragged do: [ :event | ROMotionMove new strategy: ROAnimationExclusive instance; for: element initialSpeed: lastStep ]. element on: ROMouseClick do: [ :event | ROMotionMove new strategy: ROAnimationExclusive instance; for: element initialSpeed: 0 @ 0 ]! ! !ROGrowable commentStamp: '' prior: 34310027! A ROGrowable makes the object grow when clicking on it. ! !ROGrowable methodsFor: 'initialization'! initializeElement: element element on: ROMouseClick do: [ :event | ROGrow on: element by: 10. element signalUpdate ].! ! !ROInteraction class methodsFor: 'public'! elementToBeAdded ^ self new ! ! !ROInteraction class methodsFor: 'public'! initializeElement: element ^ self elementToBeAdded initializeElement: element; yourself! ! !ROInteraction class methodsFor: 'public' stamp: 'BenComan 10/14/2012 23:08'! key "Used in the dictionary each element has" ^ self ! ! !ROInteraction methodsFor: 'accessing'! elementToBeAdded ^ self ! ! !ROInteraction methodsFor: 'hooks'! initializeElement: element self subclassResponsibility ! ! !ROInteraction methodsFor: 'hooks' stamp: 'BenComan 10/14/2012 23:09'! key "Used in the dictionary each element has" ^ self class ! ! !ROLightlyHighlightable commentStamp: '' prior: 34310148! A ROLightlyHighlightable is a decorator that highlights the element when the mouse is over it.! !ROLightlyHighlightable class methodsFor: 'configuration' stamp: 'AlexandreBergel 5/1/2012 10:02'! highlightedColor ^ Color blue! ! !ROLightlyHighlightable class methodsFor: 'public' stamp: 'AlexandreBergel 9/24/2012 12:11'! lightBlue ^ self new highlightColor: Color lightBlue; yourself! ! !ROLightlyHighlightable class methodsFor: 'public' stamp: 'AlexandreBergel 9/24/2012 12:13'! lightGray ^ self new highlightColor: Color lightGray; yourself! ! !ROLightlyHighlightable class methodsFor: 'configuration' stamp: 'AlexandreBergel 5/1/2012 09:59'! unhighlightedColor ^ Color gray! ! !ROLightlyHighlightable class methodsFor: 'public' stamp: 'AlexandreBergel 9/24/2012 12:13'! veryVeryLightGray ^ self new highlightColor: Color veryVeryLightGray; yourself! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 9/24/2012 11:11'! cacheKey "Key used as attribute" ^ #previousColorBeforeHighlighting! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 9/24/2012 12:07'! defaultHighlightColor ^ self class highlightedColor ! ! !ROLightlyHighlightable methodsFor: 'accessing' stamp: 'AlexandreBergel 9/24/2012 12:09'! highlightColor ^ highlightColor! ! !ROLightlyHighlightable methodsFor: 'accessing' stamp: 'AlexandreBergel 9/24/2012 12:09'! highlightColor: aColor highlightColor := aColor! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 5/22/2013 18:14'! highlightElement: element ROBlink highlight: element color: highlightColor ! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 9/24/2012 12:09'! initialize super initialize. self highlightColor: self defaultHighlightColor! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 9/24/2012 11:04'! initializeElement: element element on: ROMouseEnter do: [ self highlightElement: element. element signalUpdate ]. element on: ROMouseLeave do: [ self unhighlightElement: element. element signalUpdate ].! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 5/22/2013 18:08'! unhighlightElement: element ROBlink unhighlight: element ! ! !ROLightlyHighlightable methodsFor: 'initialization' stamp: 'AlexandreBergel 5/1/2012 09:59'! unhighlightedColor ^ self class unhighlightedColor ! ! !ROMenuActivable class methodsFor: 'public' stamp: 'AlexandreBergel 4/11/2013 11:14'! item: titleAsString action: aBlockOrSymbol ^ self new item: titleAsString action: aBlockOrSymbol! ! !ROMenuActivable methodsFor: 'accessing' stamp: 'AlexandreBergel 12/17/2012 21:24'! actionNamed: aName "Return the block corresponding to the action name" ^ actions detect: [ :assoc | assoc key = aName ]! ! !ROMenuActivable methodsFor: 'accessing'! addActions: someActions actions addAll: someActions! ! !ROMenuActivable methodsFor: 'initialization'! initialize super initialize. actions := OrderedCollection new. ! ! !ROMenuActivable methodsFor: 'hooks'! initializeElement: element ^ (element is: self class) ifTrue: [ self installOnExistingInteractionOn: element ] ifFalse: [ self installHandlerOn: element]! ! !ROMenuActivable methodsFor: 'hooks' stamp: 'AlexandreBergel 7/25/2012 16:14'! installHandlerOn: element element on: ROMouseRightClick do: [ :event | ROPlatform current widgetFactory menuForAssociations: actions on: element ]! ! !ROMenuActivable methodsFor: 'hooks' stamp: 'AlexandreBergel 12/17/2012 21:28'! installOnExistingInteractionOn: element | el | el := (element getInteraction: ROMenuActivable). el addActions: actions. ^ el! ! !ROMenuActivable methodsFor: 'public'! item: titleAsString action: aBlockOrSymbol actions add: (titleAsString -> aBlockOrSymbol)! ! !ROMenuActivable methodsFor: 'accessing'! numberOfEntries ^ actions size! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/5/2013 15:52'! camera ^miniMapDisplayer camera! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/5/2013 12:56'! container ^miniMapContainer! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/4/2013 12:49'! containerSize ^containerSize! ! !ROMiniMap methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 20:07'! defaultWindowSize "Default size of the mini map when opened" ^ 200 @ 200! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/4/2013 11:29'! factor ^0.2! ! !ROMiniMap methodsFor: 'minimap' stamp: 'AlexandreBergel 9/14/2013 20:02'! getEncompassingRectangleOfView: view "Return the encompassing rectangle of the view. This methods makes sure this is not too small" | encompassingRectangle enRect | encompassingRectangle := view encompassingRectangle. "Make sure we are dealing with a meaningful size" enRect := encompassingRectangle origin extent: (self minimumViewExtent max: encompassingRectangle extent). ^ enRect ! ! !ROMiniMap methodsFor: 'hooks' stamp: 'AlexandreBergel 9/15/2013 00:45'! initializeElement: view "TODO: remove targetView and make the ROKeyEvent work without help " targetView isNil ifTrue: [ targetView := view ]. containerSize := self defaultWindowSize. self setupMiniMapFor: view. self setupLupaFor: view. self setupMiniMapContainerForView: view. self setupStackFor: view. self setViewAnnouncementsFor: view. view attributeAt: #miniMap put: self! ! !ROMiniMap methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 20:17'! lupa ^ lupa! ! !ROMiniMap methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 20:06'! miniMap ^ miniMap! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/5/2013 13:06'! miniMapDisplayer ^miniMapDisplayer! ! !ROMiniMap methodsFor: 'configuration' stamp: 'AlexandreBergel 9/14/2013 20:02'! minimumViewExtent "Return the minimum size of a view. This is particularly useful if the minimap is open on an empty view for example" ^ 50 @ 50! ! !ROMiniMap methodsFor: 'configuration' stamp: 'AlexandreBergel 9/14/2013 20:03'! minimumViewRectangle ^ (0 @ 0) extent: self minimumViewExtent ! ! !ROMiniMap methodsFor: 'opening' stamp: 'VanessaPena 1/7/2013 15:12'! openMiniMapFor: view (miniMapWindow isNil or:[miniMapWindow owner isNil]) ifTrue: [ miniMapWindow := miniMapStack openInWindowSized: self defaultWindowSize ] ifFalse: [ miniMapWindow delete. miniMapWindow := nil.]! ! !ROMiniMap methodsFor: 'container' stamp: 'AlexandreBergel 9/15/2013 00:24'! resizeContainer: extent for: view containerSize := extent. self setMiniMapPositionAndSizeFor: view. miniMapDisplayer setCameraRealExtentFor: miniMap. self setLupaPositionAndSizeFor: view.! ! !ROMiniMap methodsFor: 'events' stamp: 'MathieuDehouck 7/3/2013 13:35'! setLupaAnnouncementsFor: view lupa on: ROMouseDragging do: [ :event | lupa translateByRealPoint: (event step). lupaBack translateByRealPoint: (event step). view camera translateBy: event step * (view camera realExtent / self camera realExtent). lupa signalUpdate. lupaBack signalUpdate. view signalUpdate. view updateElementsToRender. ]. lupa on: ROMouseLeftClick do:[:event | self translateLupaTo: event position for: view ].! ! !ROMiniMap methodsFor: 'lupa' stamp: 'AlexandreBergel 9/14/2013 20:25'! setLupaPositionAndSizeFor: view self setLupaSizeFor: view. self setLupaPositionFor: view. ! ! !ROMiniMap methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:25'! setLupaPositionFor: view | position | position := (view camera position * (self camera realExtent / view camera realExtent) + miniMap position) asIntegerPoint. lupa translateToRealPoint: position. lupaBack translateToRealPoint: position. ! ! !ROMiniMap methodsFor: 'lupa' stamp: 'AlexandreBergel 9/15/2013 00:26'! setLupaSizeFor: aView |extent| extent := self camera virtualToRealPoint: (aView camera windowSize * (aView camera extent/ aView camera realExtent)) asIntegerPoint. lupa extent: extent. lupaBack extent: extent. ! ! !ROMiniMap methodsFor: 'events' stamp: 'VanessaPena 1/5/2013 21:07'! setMiniMapAnnouncementsFor: view miniMap on: ROMouseLeftClick do:[:event | self translateLupaTo: event position for: view ].! ! !ROMiniMap methodsFor: 'events' stamp: 'VanessaPena 1/5/2013 21:07'! setMiniMapContainerAnnouncementsFor: view miniMapContainer on: ROKeyDown do: [:event | (event keyValue = self symbolValueForOpen) ifTrue: [ self openMiniMapFor: view ] ]. miniMapContainer on: ROWindowResized do:[:event | self resizeContainer: event extent for: view ]. miniMapContainer on: ROMouseLeftClick do: [:event | self translateLupaTo: event position for: view ].! ! !ROMiniMap methodsFor: 'minimap' stamp: 'AlexandreBergel 9/14/2013 20:09'! setMiniMapPosition | position | position := (0 @ 0 corner: containerSize) center - (miniMap extent / 2). miniMap translateToRealPoint: position. ! ! !ROMiniMap methodsFor: 'minimap' stamp: 'VanessaPena 1/5/2013 15:31'! setMiniMapPositionAndSizeFor: view self setMiniMapSizeFor: view. self setMiniMapPosition.! ! !ROMiniMap methodsFor: 'minimap' stamp: 'AlexandreBergel 9/14/2013 20:14'! setMiniMapSizeFor: view | enRect extent e | (view encompassingRectangle extent <= (1 @ 1)) ifTrue: [ ^ self ]. enRect := self getEncompassingRectangleOfView: view. extent := self camera virtualToRealPoint: enRect extent. extent y * (containerSize x / extent x) < containerSize y ifTrue: [ e := containerSize x @ (extent y * (containerSize x / extent x)) ] ifFalse: [ e := (extent x * (containerSize y / extent y)) @ containerSize y ]. miniMap extent: e! ! !ROMiniMap methodsFor: 'events' stamp: 'AlexandreBergel 9/15/2013 00:28'! setViewAnnouncementsFor: view view on: ROCameraTranslated do: [:event | |trans| trans := (event step * (self camera realExtent / view camera realExtent)) asIntegerPoint. lupa translateBy: trans. lupaBack translateBy: trans. miniMapContainer signalUpdate. ]. view on: ROCameraResized do: [:event | self setLupaPositionAndSizeFor: view. lupa signalUpdate. ]. targetView on: ROKeyDown do: [:event | (event keyValue = self symbolValueForOpen) ifTrue: [ self openMiniMapFor: view. ] ]. view on: ROWindowResized do: [:event | self setLupaSizeFor: view. lupa signalUpdate. ].! ! !ROMiniMap methodsFor: 'lupa' stamp: 'AlexandreBergel 9/14/2013 20:16'! setupLupaFor: aView lupa := ROElement new. lupa + (ROBorder new color: Color black). lupaBack := ROElement new. lupaBack + (ROBox new color: Color white). self setLupaAnnouncementsFor: aView. lupa resizeStrategy: ROFixedSizedParent instance.! ! !ROMiniMap methodsFor: 'container' stamp: 'AlexandreBergel 9/14/2013 20:23'! setupMiniMapContainerForView: view miniMapContainer := ROView new title: (view title , ' miniMap'). miniMapContainer backgroundColor: Color lightGray. miniMapContainer add: lupaBack. miniMapContainer add: miniMap. miniMapContainer add: lupa. self setMiniMapContainerAnnouncementsFor: view.! ! !ROMiniMap methodsFor: 'minimap' stamp: 'AlexandreBergel 9/15/2013 00:22'! setupMiniMapFor: view miniMap := ROElement new. miniMap extent: 5 @ 5. " miniMap extent: self defaultWindowSize." miniMapDisplayer := ROMiniMapDisplayer new view: view; factor: self factor. miniMap + miniMapDisplayer. self setMiniMapPositionAndSizeFor: view. miniMap resizeStrategy: ROFixedSizedParent instance. self setMiniMapAnnouncementsFor: view.! ! !ROMiniMap methodsFor: 'hooks' stamp: 'VanessaPena 1/7/2013 16:03'! setupStackFor: view | zoomIn zoomOut | miniMapStack := ROViewStack new. zoomIn := ROElement new model: 'zoom in'; +(ROLabel new color: Color red ); + (ROBorder new color: Color red ); yourself. zoomOut := ROElement new model: 'zoom out'; +(ROLabel new color: Color red ); + (ROBorder new color: Color red ); yourself. zoomIn on: ROMouseLeftClick do:[:event | ROZoomInMove new on: view. ]. zoomOut on: ROMouseLeftClick do:[:event | ROZoomOutMove new on: view. ]. miniMapStack add: zoomIn; add: zoomOut; addView: miniMapContainer. ROHorizontalLineLayout new on: miniMapStack elements.! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/2/2013 09:49'! symbolValueForOpen ^$m asInteger! ! !ROMiniMap methodsFor: 'accessing' stamp: 'VanessaPena 1/2/2013 10:14'! targetView: aView targetView := aView! ! !ROMiniMap methodsFor: 'lupa' stamp: 'MathieuDehouck 7/3/2013 13:33'! translateLupaTo: position for: view |step| step := position - lupa position. lupa translateByRealPoint: step. lupaBack translateByRealPoint: step. view camera translateBy: step * (view camera realExtent / self camera realExtent). lupa signalUpdate. lupaBack signalUpdate. view signalUpdate. view updateElementsToRender.! ! !RORubberBand methodsFor: 'hooks' stamp: 'BenComan 11/25/2012 11:28'! initializeElement: sourceElement " ROExample new rubberBanding " sourceElement on: ROMouseDragging do: [ :event | | relativePosition | tmpLine ifNil: [ tmpElement := ROElement new. tmpLine := (ROEdge from: event element to: tmpElement) + ROLine; yourself. sourceElement view add: tmpLine. sourceElement view add: tmpElement. sourceElement view allElementsDo: [ :candidateTarget | candidateTarget getInteraction: self ifPresent: [ :interaction | targetSelection source: sourceElement target: candidateTarget. ]. ]. ]. relativePosition := sourceElement view camera realToVirtualPoint: (event position). tmpElement translateTo: relativePosition. sourceElement view signalUpdate. ]. sourceElement on: ROMouseDragged do: [ :event | | targetElement newEdgeRaw | tmpElement remove. tmpLine remove. tmpLine := nil. tmpElement := nil. targetElement := (sourceElement view elementAtRealPosition: event position). (targetSelection contains: targetElement) ifTrue: [ dropAction ifNotNil: [ dropAction value: event element value: targetElement ] ]. targetSelection clear. sourceElement view signalUpdate. ]. ! ! !RORubberBand methodsFor: 'hooks' stamp: 'BenComan 10/14/2012 23:16'! key "Used in the dictionary each element has" "Key on instance rather than class" ^ self ! ! !RORubberBand methodsFor: 'accessing' stamp: 'BenComan 10/14/2012 23:16'! onDrop: aBlock dropAction := aBlock! ! !RORubberBand methodsFor: 'accessing' stamp: 'BenComan 10/15/2012 22:10'! targeting: aBlock targetSelection := aBlock! ! !ROScrollbable methodsFor: 'hooks' stamp: 'AlexandreBergel 6/5/2012 23:17'! horizontalScrollbarFor: aStack | scrollbar view | view := aStack firstView. scrollbar := ROElement new. scrollbar width: 80. scrollbar height: 15. scrollbar + ROBox. scrollbar on: ROMouseDragging do: [ :event | scrollbar translateByRealPoint: (event step * (1@0)). scrollbar translateTo: (scrollbar position max: 0@0). scrollbar translateTo: (scrollbar position min: (aStack camera width - scrollbar width) @ 0). (scrollbar position x >= 0 and: [ scrollbar position x <= (aStack camera extent x - scrollbar width)]) ifTrue: [ | xView | xView := view encompassingRectangle width * scrollbar position x / view camera width negated. view translateTo: (xView @ view camera position y negated) asIntegerPoint ]. scrollbar signalUpdate. ]. " view on: ROMouseDragging do: [ :event | | xView | xScroll := view encompassingRectangle width * scrollbar position x / view camera width negated. scrollbar translateTo: (xScroll @ 0). scrollbar translateTo: (scrollbar position max: 0@0). scrollbar translateTo: (scrollbar position min: (aStack camera extent x - scrollbar width) @ 0). ]." ^ scrollbar! ! !ROScrollbable methodsFor: 'hooks' stamp: 'AlexandreBergel 6/5/2012 17:58'! initializeElement: aStack | view horizontalScrollbar verticalScrollbar | self assert: [ aStack isKindOf: ROViewStack ]. view := aStack firstView. horizontalScrollbar := self horizontalScrollbarFor: aStack. verticalScrollbar := self verticalScrollbarFor: aStack. aStack add: horizontalScrollbar. aStack add: verticalScrollbar.! ! !ROScrollbable methodsFor: 'hooks' stamp: 'AlexandreBergel 6/5/2012 23:18'! verticalScrollbarFor: aStack | scrollbar view | view := aStack firstView. scrollbar := ROElement new. scrollbar width: 15. scrollbar height: 80. scrollbar + ROBox. scrollbar on: ROMouseDragging do: [ :event | scrollbar translateByRealPoint: (event step * (0@1)). scrollbar translateTo: (scrollbar position max: 0@0). scrollbar translateTo: (scrollbar position min: 0 @ (aStack camera extent y - scrollbar height)). (scrollbar position y >= 0 and: [ scrollbar position y <= (aStack camera extent y - scrollbar height)]) ifTrue: [ | yView | yView := view encompassingRectangle height * scrollbar position y / view camera extent y negated. view translateTo: (view camera position x negated @ yView) asIntegerPoint ]. scrollbar signalUpdate. ]. view on: ROMouseDragging do: [ :event | scrollbar translateBy: (event step negated * (0 @ 1)). scrollbar translateTo: (scrollbar position max: 0@0). scrollbar translateTo: (scrollbar position min: 0 @ aStack camera extent y - scrollbar height). ]. ^ scrollbar! ! !ROSelection methodsFor: 'events-triggering' stamp: 'BenComan 12/9/2012 13:19'! add: targetElement targetElement ifNotNil: [ selectedElements add: targetElement . inclusionAction ifNotNil: [ inclusionAction value: targetElement ]. ]. ! ! !ROSelection methodsFor: 'events-triggering' stamp: 'BenComan 10/15/2012 22:08'! clear exclusionAction ifNotNil: [ selectedElements do: [ :element | exclusionAction value: element ] ]. selectedElements := OrderedCollection new. ! ! !ROSelection methodsFor: 'comparing' stamp: 'BenComan 10/15/2012 22:23'! contains: aROElement selectedElements do: [ :element | (element = aROElement) ifTrue: [ ^true] ]. ^false.! ! !ROSelection methodsFor: 'events-registering' stamp: 'BenComan 10/15/2012 22:05'! for: aBlock filter := aBlock. ! ! !ROSelection methodsFor: 'initialize-release' stamp: 'BenComan 10/15/2012 22:12'! initialize super initialize. filter := [ :source :target | false ]. selectedElements := OrderedCollection new. ! ! !ROSelection methodsFor: 'events-registering' stamp: 'BenComan 10/15/2012 22:09'! onExclusion: aBlock exclusionAction := aBlock. ! ! !ROSelection methodsFor: 'events-registering' stamp: 'BenComan 10/15/2012 22:09'! onInclusion: aBlock inclusionAction := aBlock. ! ! !ROSelection methodsFor: 'printing' stamp: 'BenComan 12/9/2012 11:38'! printOn: aStream super printOn: aStream. aStream nextPutAll: '[' . selectedElements do: [ :el | aStream nextPutAll: el model asString. aStream nextPutAll: ' '. ]. aStream nextPutAll: ']' . ! ! !ROSelection methodsFor: 'events-triggering' stamp: 'BenComan 12/9/2012 12:05'! source: sourceElement target: targetElement (filter value: sourceElement value: targetElement) ifTrue: [ self add: targetElement. ]! ! !ROLinearMoveT methodsFor: 'action' stamp: 'AlexandreBergel 10/16/2013 11:43'! doAfter element translateTo: finalPosition. super doAfter. ! ! !ROLinearMoveT methodsFor: 'hooks' stamp: 'AlexandreBergel 10/16/2013 11:34'! doStep newPosition := initialPosition + ((finalPosition - initialPosition) * self elapsedTimeNormalized). element translateTo: newPosition asIntegerPoint. element signalUpdate.! ! !ROLinearMoveT methodsFor: 'public' stamp: 'AlexandreBergel 10/16/2013 11:37'! for: anElement to: aFinalPosition during: milliseconds element := anElement. duration := milliseconds. initialPosition := element position. finalPosition := aFinalPosition. anElement view addAnimation: self! ! !ROPluggableAnimationT methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/16/2013 11:54'! block ^ block! ! !ROPluggableAnimationT methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/16/2013 11:54'! block: aOneArgBlock block := aOneArgBlock! ! !ROPluggableAnimationT methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/16/2013 11:57'! doStep block cull: self! ! !ROPluggableAnimationT methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 10/16/2013 11:57'! on: aView aView addAnimation: self! ! !ROTimelyAnimation methodsFor: 'action' stamp: 'AlexandreBergel 10/16/2013 11:28'! addedIn: aView "I m added in a view" "After this method, the animation is starting" strategy added: self in: aView. startedTime := self currentTime! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 11:24'! after: aBlock "The after block is used to do something after the animation has completed" afterBlock := aBlock! ! !ROTimelyAnimation methodsFor: 'utility' stamp: 'AlexandreBergel 10/16/2013 11:23'! currentTime ^ Time millisecondClockValue ! ! !ROTimelyAnimation methodsFor: 'configuration' stamp: 'AlexandreBergel 10/16/2013 11:22'! defaultDuration ^ 500! ! !ROTimelyAnimation methodsFor: 'action' stamp: 'AlexandreBergel 10/16/2013 11:24'! doAfter afterBlock value! ! !ROTimelyAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 10/16/2013 11:24'! doCycle self hasCompleted ifFalse: [ self doStep. self hasCompleted ifTrue: [ self doAfter ] ]! ! !ROTimelyAnimation methodsFor: 'hooks' stamp: 'AlexandreBergel 10/16/2013 11:24'! doStep "To be overriden"! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 12:06'! duration: milliseconds "Set the duration of the animation in milliseconds" duration := milliseconds! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 11:28'! elapsedTime ^ self currentTime - startedTime! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 11:31'! elapsedTimeNormalized "Return a value between 0 and 1" ^ self elapsedTime / duration! ! !ROTimelyAnimation methodsFor: 'testing' stamp: 'AlexandreBergel 10/16/2013 11:41'! hasCompleted ^ duration <= self elapsedTime! ! !ROTimelyAnimation methodsFor: 'initialize-release' stamp: 'AlexandreBergel 10/16/2013 11:30'! initialize super initialize. duration := self defaultDuration. afterBlock := #yourself. strategy := ROAnimationAppend instance! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 11:30'! strategy "Return the merging strategy associated to this animation" ^ strategy! ! !ROTimelyAnimation methodsFor: 'accessing' stamp: 'AlexandreBergel 10/16/2013 11:30'! strategy: anAnimationStrategy "Set a new strategy when merging animations" strategy := anAnimationStrategy ! ! !ROZoomIntoElementOnClick methodsFor: 'view to add' stamp: 'VanessaPena 1/17/2013 12:47'! addInteractionsToReturnFor: viewToAdd | oldBounds rect | oldBounds := (stack firstView camera bounds). viewToAdd on: ROMouseRightClick do: [:event | | move original | stack removeFirst. rect := viewToAdd encompassingRectangle. "stack firstView translateBy: ((0@0 corner: stack camera windowSize) center - ((rect width / 2) @ (rect height / 2)))." move := ROZoomMove new. move nbCycles: 10. move on: stack firstView to: oldBounds] .! ! !ROZoomIntoElementOnClick methodsFor: 'view to add' stamp: 'VanessaPena 1/8/2013 12:42'! addRecursivelyOn: aView recursive ifTrue: [aView elementsDo: [:el | el @self ]]. ! ! !ROZoomIntoElementOnClick methodsFor: 'view to add' stamp: 'VanessaPena 1/17/2013 12:38'! createViewToAddFor: element |viewToAdd rect| viewToAdd := (view roValue: element ). self addInteractionsToReturnFor: viewToAdd. self addRecursivelyOn: viewToAdd. rect := viewToAdd encompassingRectangle. viewToAdd translateBy: ((0@0 corner: stack camera windowSize) center - ((rect width / 2) @ (rect height / 2))) - viewToAdd position . ^viewToAdd ! ! !ROZoomIntoElementOnClick methodsFor: 'initialization' stamp: 'VanessaPena 1/8/2013 12:30'! initialize recursive := false.! ! !ROZoomIntoElementOnClick methodsFor: 'initialization' stamp: 'VanessaPena 1/8/2013 14:51'! initializeElement: element element on: ROMouseLeftClick do: [:event | | move viewToAdd| viewToAdd := (self createViewToAddFor: element). move := ROZoomMove new. move after: [ stack addFirst: viewToAdd ]. move on: element view to: element bounds ]. ! ! !ROZoomIntoElementOnClick methodsFor: 'initialization' stamp: 'VanessaPena 1/8/2013 12:31'! recursive: aBoolean recursive := aBoolean.! ! !ROZoomIntoElementOnClick methodsFor: 'accessing'! stack ^ stack! ! !ROZoomIntoElementOnClick methodsFor: 'accessing' stamp: 'VanessaPena 1/8/2013 11:31'! stack: aStack stack := aStack. ! ! !ROZoomIntoElementOnClick methodsFor: 'initialization' stamp: 'VanessaPena 1/8/2013 10:11'! view: aROViewOrBlock view := aROViewOrBlock ! ! !ROZoomOnClick methodsFor: 'initialization'! initializeElement: element | el isZoomed originalBounds | isZoomed := false. element on: ROMouseClick do: [:event | isZoomed ifTrue: [ ROZoomMove new on: element view to: originalBounds ] ifFalse: [ originalBounds := element view camera bounds. ROZoomMove new on: element view to: element bounds ]. isZoomed := isZoomed not ]. ! ! !ROLayout commentStamp: '' prior: 34310293! A ROLayout is the superclass of all. Instance Variables affectedNodes: currentIteraction: eventHandler: maxInterations: translator: affectedNodes - xxxxx currentIteraction - xxxxx eventHandler - xxxxx maxInterations - xxxxx translator - xxxxx ! !ROAbstractGridLayout class methodsFor: 'public' stamp: 'JurajKubelka 5/8/2013 13:43'! isAbstract ^ self name = #ROAbstractGridLayout! ! !ROAbstractGridLayout class methodsFor: 'public' stamp: 'JurajKubelka 5/8/2013 13:45'! on: aCollectionOfElements withGap: anInteger withLineItemsCount: aBlock "place the elements in a grid with (aBlock roValue: aCollectionOfElements) as the amount of elements horizontally" | myLayout | myLayout := self new gapSize: anInteger; lineItemsCount: aBlock; yourself. myLayout applyOn: aCollectionOfElements. ^ aCollectionOfElements! ! !ROAbstractGridLayout class methodsFor: 'public' stamp: 'JurajKubelka 5/8/2013 13:43'! on: aCollectionOfElements withLineItemsCount: aBlock "place the elements in a grid with (aBlock roValue: aCollectionOfElements) as the amount of elements horizontally For example: self on: (ROElement forCollection: (1 to: 20)) withLineItemsCount: 5 => place the 20 elements on a grid 5 x 4 self on: (ROElement forCollection: (1 to: 20)) withLineItemsCount: [ :elements | elements size // 3 ] => place the 20 elements on a grid 3 x 7 " | myLayout | myLayout := self new lineItemsCount: aBlock; yourself. myLayout applyOn: aCollectionOfElements. ^ aCollectionOfElements! ! !ROAbstractGridLayout class methodsFor: 'instance creation' stamp: 'JurajKubelka 5/8/2013 13:43'! withGap: anInteger ^ self new gapSize: anInteger; yourself! ! !ROAbstractGridLayout class methodsFor: 'instance creation' stamp: 'JurajKubelka 5/8/2013 13:43'! withGap: anInteger withLineItemsCount: aBlock ^self new gapSize: anInteger; lineItemsCount: aBlock; yourself! ! !ROAbstractGridLayout class methodsFor: 'instance creation' stamp: 'JurajKubelka 5/8/2013 13:43'! withLineItemsCount: aBlock ^self new lineItemsCount: aBlock; yourself! ! !ROAbstractGridLayout methodsFor: 'initialize-release' stamp: 'JurajKubelka 5/8/2013 13:47'! defaultGapSize ^ 5! ! !ROAbstractGridLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/8/2013 13:47'! defaultLineItemsCount ^ [ :elements | | height width | (elements size < 3 ifTrue: [ (elements size max: 1) @ 1 ] ifFalse: [ height := (elements size * 0.618034) sqrt ceiling truncated. width := (elements size / height) ceiling truncated. width @ height ]) x ]! ! !ROAbstractGridLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/8/2013 13:47'! gapSize ^gapSize! ! !ROAbstractGridLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/8/2013 13:47'! gapSize: anInteger gapSize := anInteger! ! !ROAbstractGridLayout methodsFor: 'initialize-release' stamp: 'JurajKubelka 5/8/2013 13:47'! initialize super initialize. gapSize := self defaultGapSize. lineItemsCountBlock := self defaultLineItemsCount.! ! !ROAbstractGridLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/8/2013 13:47'! lineItemsCount: aBlock lineItemsCountBlock := aBlock! ! !ROAbstractGridLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/8/2013 13:47'! lineItemsCountBlock ^ lineItemsCountBlock! ! !ROCellLayout commentStamp: '' prior: 34310657! A ROCellLayout is like ROGridLayout. Elements of each column are centered along the same vertical line. And elements of each row are centered along the same horizontal line. Instance Variables inCellPosition: inCellPosition - Object which computes position of each element inside a cell. The cell is the space allocated for an element. Its height is maximum of heights of elements on the row. Its width is maximum of widths of elements on the column. By default elements are in the middle of their cell.! !ROCellLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/16/2013 22:42'! doExecute: elements | pointer lineItemCount lineItemSize cell | lineItemSize := self lineItemsCountBlock roValue: elements. cell := ROCell elements: elements columns: lineItemSize. pointer := self gapSize @ self gapSize. lineItemCount := 0. elements withIndexDo: [ :element :index | | inCellPointer | cell element: element; number: index. inCellPointer := inCellPosition roValue: cell. translator translate: element to: pointer + inCellPointer. pointer := (pointer x + cell extent x + (self gapSize * 2)) @ pointer y. lineItemCount := lineItemCount + 1. lineItemCount >= lineItemSize ifTrue: [ pointer := self gapSize @ (pointer y + (self gapSize * 2) + cell extent y). lineItemCount := 0 ]. self step ]! ! !ROCellLayout methodsFor: 'accessing' stamp: 'JurajKubelka 5/16/2013 12:24'! inCellPosition: anObjectOrOneArgBlock inCellPosition := anObjectOrOneArgBlock! ! !ROCellLayout methodsFor: 'initialize-release' stamp: 'JurajKubelka 5/16/2013 12:17'! initialize super initialize. inCellPosition := [ :cell | ((cell extent x - cell element width) / 2) @ ((cell extent y - cell element height) / 2)]! ! !ROCellLayout methodsFor: 'accessing' stamp: 'JurajKubelka 6/3/2013 21:16'! leftCentred self inCellPosition: [ :cell | 0 @ ((cell extent y - cell element height) / 2) ]! ! !ROGridLayout commentStamp: '' prior: 34311237! A ROGridLayout places elements as a grid. Instance Variables gapSize: lineItemsCountBlock: gapSize - number of pixels between each elements, horizontally and vertically lineItemsCountBlock - tells the amount of item per line should be used ! !ROGridLayout methodsFor: 'hook' stamp: 'AlexandreBergel 5/7/2013 13:47'! doExecute: elements | pointer lineItemCount lineItemSize maxLastLineHeight originalGapLeft originalGapTop parent oldParentStrategy | originalGapLeft := self paddingLeftFor: elements. originalGapTop := self paddingTopFor: elements. pointer := originalGapLeft @ originalGapTop. lineItemSize := self lineItemsCountBlock roValue: elements. lineItemCount := 0. maxLastLineHeight := 0. "We are here assuming all the elements have the same parent" parent := elements anyOne parent. parent isView ifFalse: [oldParentStrategy := elements anyOne parent resizeStrategy. parent resizeStrategy: (ROPermissiveParent new padding: oldParentStrategy padding)]. elements do: [ :element | translator translate: element to: pointer. pointer := (pointer x + element width + (self gapSize * 2)) @ pointer y. lineItemCount := lineItemCount + 1. maxLastLineHeight := maxLastLineHeight max: element height. lineItemCount >= lineItemSize ifTrue: [ pointer := originalGapLeft @ (pointer y + (self gapSize * 2) + maxLastLineHeight). maxLastLineHeight := 0. lineItemCount := 0 ]. self step ]. "We set the old strategy and adjust the size of the parent" parent isView ifFalse: [parent resizeStrategy: oldParentStrategy. parent adjustSizeIfNecessary].! ! !ROAbstractLineLayout class methodsFor: 'testing' stamp: 'AlexandreBergel 11/15/2012 13:24'! isAbstract ^ self name = #ROAbstractLineLayout! ! !ROAbstractLineLayout class methodsFor: 'instance creation'! withGap: anInteger ^(self new) gapSize: anInteger; yourself! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignBottom alignment := #bottom! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignCenter alignment := #center! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignLeft alignment := #left! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignRight alignment := #right! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignTop alignment := #top! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignment ^alignment! ! !ROAbstractLineLayout methodsFor: 'accessing'! alignment: anObject alignment := anObject! ! !ROAbstractLineLayout methodsFor: 'configuration'! center self alignment: #center! ! !ROAbstractLineLayout methodsFor: 'hook'! deltaFor: aNodeFigure ^self subclassResponsibility! ! !ROAbstractLineLayout methodsFor: 'hook'! doCenter: aGraph self subclassResponsibility ! ! !ROAbstractLineLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/22/2013 16:19'! doExecute: elements | pointer delta | horizontallyStretchable ifTrue: [ self doStretchHorizontal: elements ]. verticallyStretchable ifTrue: [ self doStretchVertical: elements ]. pointer := self positionOriginalPointer: elements. elements do: [ :element | delta := self deltaFor: element. translator translate: element to: pointer - delta. pointer := self movePointer: pointer accordingToFigure: element. self step ].! ! !ROAbstractLineLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/22/2013 18:08'! doStretchHorizontal: aCollectionOfElements self subclassResponsibility! ! !ROAbstractLineLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/22/2013 18:09'! doStretchVertical: aCollectionOfElements self subclassResponsibility! ! !ROAbstractLineLayout methodsFor: 'accessing'! gapSize ^gapSize! ! !ROAbstractLineLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 8/11/2013 17:22'! gapSize: aNumber gapSize := aNumber. " This value is never used actually " verticalGap := 2 * aNumber. horizontalGap := 2 * aNumber! ! !ROAbstractLineLayout methodsFor: 'accessing'! horizontalGap ^horizontalGap! ! !ROAbstractLineLayout methodsFor: 'accessing'! horizontalGap: anObject horizontalGap := anObject! ! !ROAbstractLineLayout methodsFor: 'testing'! horizontallyStretchable ^ horizontallyStretchable! ! !ROAbstractLineLayout methodsFor: 'initialize-release' stamp: 'AlexandreBergel 8/11/2013 17:22'! initialize super initialize. verticalGap := 10. horizontalGap := 10. horizontallyStretchable := false. verticallyStretchable := false! ! !ROAbstractLineLayout methodsFor: 'testing'! isLineLayout ^ true! ! !ROAbstractLineLayout methodsFor: 'hook'! movePointer: pointer accordingToFigure: aNodeFigure self subclassResponsibility! ! !ROAbstractLineLayout methodsFor: 'hook'! positionOriginalPointer: aGraph ^self subclassResponsibility! ! !ROAbstractLineLayout methodsFor: 'configuration'! stretch horizontallyStretchable := verticallyStretchable := true! ! !ROAbstractLineLayout methodsFor: 'configuration'! stretchHorizontally horizontallyStretchable := true! ! !ROAbstractLineLayout methodsFor: 'configuration'! stretchVertically verticallyStretchable := true! ! !ROAbstractLineLayout methodsFor: 'accessing'! verticalGap ^verticalGap! ! !ROAbstractLineLayout methodsFor: 'accessing'! verticalGap: anObject verticalGap := anObject! ! !ROAbstractLineLayout methodsFor: 'testing'! verticallyStretchable ^ verticallyStretchable! ! !ROHorizontalLineLayout commentStamp: '' prior: 34311581! A ROHorizontalLineLayout locates all the elements horizontally! !ROHorizontalLineLayout methodsFor: 'hook'! deltaFor: aNodeFigure | delta | delta := 0. self alignment == #bottom ifTrue: [delta := aNodeFigure height]. self alignment == #center ifTrue: [delta := aNodeFigure height / 2.0]. ^0 @ delta! ! !ROHorizontalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/23/2013 15:34'! doCenter: elements | midTallest step | midTallest := 0. midTallest := elements nodes inject: 0 into: [ :m :el | m max: (el bounds height )]. midTallest := midTallest / 2. elements nodes do: [ :node | step := 0 @ (midTallest - (node bounds height / 2)) asInteger. node bounds origin: (node bounds origin + step). node bounds corner: (node bounds corner + step). ] ! ! !ROHorizontalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 8/11/2013 17:22'! doStretchHorizontal: aCollectionOfElements | parent parentBounds addedWidth parentBoundsWidth runningIndex newWidth | aCollectionOfElements isEmpty ifTrue: [ ^ self "nothing to do" ]. parent := aCollectionOfElements anyOne parent. parent isView ifTrue: [ ^ self "ROView does not have bounds" ]. parentBounds := parent bounds. addedWidth := aCollectionOfElements inject: 0 into: [ :m :el | m + el width ]. parentBoundsWidth := parentBounds width. " parentBoundsWidth := parentBoundsWidth - ((aCollectionOfElements size - 1) * horizontalGap) - (2 * horizontalOutGap)." runningIndex := 0. parentBounds width > addedWidth ifTrue: [ aCollectionOfElements do: [ :element | newWidth := (element width * parentBoundsWidth / addedWidth) asInteger. element width: newWidth. runningIndex := runningIndex + newWidth + horizontalGap ] ]! ! !ROHorizontalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 8/11/2013 17:24'! doStretchVertical: aCollectionOfElements | parent parentBounds | aCollectionOfElements isEmpty ifTrue: [ ^ self "nothing to do" ]. parent := aCollectionOfElements anyOne parent. parent isView ifTrue: [ ^ self "ROView does not have bounds" ]. parentBounds := parent bounds. aCollectionOfElements do: [ :element | element height: (parentBounds height) ]! ! !ROHorizontalLineLayout methodsFor: 'initialize-release'! initialize super initialize. self alignTop! ! !ROHorizontalLineLayout methodsFor: 'hook'! movePointer: pointer accordingToFigure: element ^ (pointer x + element width + self horizontalGap) @ pointer y! ! !ROHorizontalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/24/2013 09:22'! positionOriginalPointer: elements | maxHeight delta | delta := 0. self alignment == #bottom ifTrue: [ maxHeight := elements maxValue: #height. delta := maxHeight ]. self alignment == #center ifTrue: [ maxHeight := elements maxValue: #height. delta := maxHeight / 2.0 ]. ^ (self paddingLeftFor: elements) @ ((self paddingTopFor: elements) + delta)! ! !ROVerticalLineLayout commentStamp: '' prior: 34311706! A ROVerticalLineLayout locates all the elements vertically! !ROVerticalLineLayout methodsFor: 'hook'! deltaFor: aNodeFigure | delta | delta := 0. self alignment == #right ifTrue: [delta := aNodeFigure width]. self alignment == #center ifTrue: [delta := aNodeFigure width / 2.0]. ^delta @ 0! ! !ROVerticalLineLayout methodsFor: 'hook'! doCenter: aGraph | midWidest step | midWidest := aGraph nodes inject: 0 into: [ :m :el | m max: (el bounds width )]. midWidest := midWidest / 2. aGraph nodes do: [ :node | step := (midWidest - (node bounds width /2)) asInteger @ 0. node bounds origin: (node bounds origin + step). node bounds corner: (node bounds corner + step). ] ! ! !ROVerticalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 8/11/2013 17:23'! doStretchHorizontal: aCollectionOfElements | parent parentBounds | aCollectionOfElements isNil ifTrue: [ ^ self "nothing to do" ]. parent := aCollectionOfElements anyOne parent. parent isView ifTrue: [ ^ self "ROView does not have bounds" ]. parentBounds := parent bounds. aCollectionOfElements do: [ :element | element width: parentBounds width ]! ! !ROVerticalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 8/11/2013 17:23'! doStretchVertical: aCollectionOfElements | parent parentBounds addedHeight parentBoundsHeight runningIndex newHeight | aCollectionOfElements isEmpty ifTrue: [ ^ self "nothing to do" ]. parent := aCollectionOfElements anyOne parent. parent isView ifTrue: [ ^ self "ROView does not have bounds" ]. parentBounds := parent bounds. addedHeight := aCollectionOfElements inject: 0 into: [ :m :el | m + el height ]. parentBoundsHeight := parentBounds height. "parentBoundsHeight := parentBoundsHeight - ((aCollectionOfElements size - 1) * verticalGap) - (2 * verticalOutGap)." runningIndex := 0. parentBounds height > addedHeight ifTrue: [ aCollectionOfElements do: [ :element | newHeight := (element height * parentBoundsHeight / addedHeight) asInteger. element height: newHeight. runningIndex := runningIndex + newHeight + verticalGap ] ] ! ! !ROVerticalLineLayout methodsFor: 'initialize-release'! initialize super initialize. self alignLeft! ! !ROVerticalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/23/2013 15:44'! movePointer: pointer accordingToFigure: aNodeFigure ^ pointer setX: pointer x setY: pointer y + aNodeFigure height + self verticalGap! ! !ROVerticalLineLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/24/2013 09:22'! positionOriginalPointer: elements | maxWidth delta | delta := 0. self alignment == #right ifTrue: [ maxWidth := elements maxValue: #width. delta := maxWidth ]. self alignment == #center ifTrue: [ maxWidth := elements maxValue: #width. delta := maxWidth / 2.0 ]. ^ ((self paddingLeftFor: elements) + delta) @ (self paddingTopFor: elements) ! ! !ROCircleLayout class methodsFor: 'instance creation'! scaleBy: aNumber ^self new scaleBy: aNumber! ! !ROCircleLayout methodsFor: 'hook' stamp: 'AlexandreBergel 1/23/2013 16:03'! computeIncrementalAngleFor: elements "Return the value _in radian_ of the incremental angle" ^ initialIncrementalAngle = 0 ifTrue: [ 2 * Float pi / elements size ] ifFalse: [ initialIncrementalAngle ]! ! !ROCircleLayout methodsFor: 'hook' stamp: 'AlexandreBergel 1/23/2013 15:54'! computeRadiusFor: elements "Return the radius of the circle. If none has been set (i.e., initialRadius = 0), then it is computed as the scale factor times the number of elements" ^ initialRadius = 0 ifTrue: [ elements size * self scaleFactor ] ifFalse: [ initialRadius ]! ! !ROCircleLayout methodsFor: 'hook' stamp: 'AlexandreBergel 1/23/2013 15:58'! doExecute: elements | angleIncrement angle rad center | rad := self computeRadiusFor: elements. center := Point x: rad y: rad. angleIncrement := self computeIncrementalAngleFor: elements. angle := self initialAngle. elements do: [ :each | | point | point := center + (Point radius: rad theta: angle). angle := angle + angleIncrement. translator translate: each to: point. self step ]! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:04'! initialAngle "Return the initial angle, in radian" ^ initialAngle! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:01'! initialAngle: anObject initialAngle := anObject! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:06'! initialAngleInDegree "Return the initial angle in degree" ^ self initialAngle * 180 / Float pi! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:03'! initialAngleInDegree: aNumber self initialAngle: aNumber * Float pi / 180! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:00'! initialIncrementalAngle "Return the initial incremental angle" ^ initialIncrementalAngle! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:59'! initialIncrementalAngle: aNumberInRadian initialIncrementalAngle := aNumberInRadian! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 16:06'! initialIncrementalAngleInDegree: aNumberInDegree self initialIncrementalAngle: aNumberInDegree * Float pi / 180! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:55'! initialRadius "Return the radius in pixels of the circle" ^ initialRadius! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:55'! initialRadius: aNumber "Set the radius of the circle" initialRadius := aNumber! ! !ROCircleLayout methodsFor: 'initialize-release' stamp: 'AlexandreBergel 1/23/2013 16:04'! initialize "Initialize a newly created instance. This method must answer the receiver." super initialize. self scaleBy: 11. "Represent the initial angle to place the elements" initialAngle := 0. "Distance of the circle. If it is 0 when entering doExecute, then it is computed" initialRadius := 0. "0 means that it is computed, and not set by the user" initialIncrementalAngle := 0.! ! !ROCircleLayout methodsFor: 'accessing'! scaleBy: aNumber factor := aNumber! ! !ROCircleLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 1/23/2013 15:47'! scaleFactor ^ factor! ! !ROAbstractFlowLayout class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 11/15/2012 13:25'! isAbstract ^ self name = #ROAbstractFlowLayout! ! !ROAbstractFlowLayout class methodsFor: 'instance creation'! withMaxWidth: anInteger ^(self new) maxWidth: anInteger; yourself! ! !ROAbstractFlowLayout class methodsFor: 'instance creation'! withMaxWidth: anInteger withGap: anotherInteger ^(self new) maxWidth: anInteger; gapSize: anotherInteger; yourself! ! !ROAbstractFlowLayout methodsFor: 'accessing'! gapSize ^gapSize! ! !ROAbstractFlowLayout methodsFor: 'accessing'! gapSize: anObject gapSize := anObject! ! !ROAbstractFlowLayout methodsFor: 'initialize-release'! initialize super initialize. maxWidth := 100. gapSize := 5! ! !ROAbstractFlowLayout methodsFor: 'private'! maxWidth ^maxWidth! ! !ROAbstractFlowLayout methodsFor: 'accessing'! maxWidth: anObject maxWidth := anObject! ! !ROBottomFlowLayout methodsFor: 'hook' stamp: 'AlexandreBergel 11/16/2012 08:59'! doExecute: nodeElements | x y maxLastLineHeight lineHeights lineNumber | x := self gapSize. y := self gapSize. maxLastLineHeight := 0. lineHeights := OrderedCollection new. lineNumber := 1. nodeElements do: [ :aNodeFigure | x := x + aNodeFigure width + (2 * self gapSize). maxLastLineHeight := maxLastLineHeight max: aNodeFigure height. x > self maxWidth ifTrue: [ lineHeights addLast: maxLastLineHeight. x := self gapSize. maxLastLineHeight := 0 ] ]. lineHeights addLast: maxLastLineHeight. x := self gapSize. nodeElements do: [ :aNodeFigure | | lineHeight | lineHeight := lineHeights at: lineNumber. translator translate: aNodeFigure to: x @ (y + lineHeight - aNodeFigure height). x := x + aNodeFigure width + (2 * self gapSize). x > self maxWidth ifTrue: [ x := self gapSize. y := y + (2 * self gapSize) + lineHeight. lineNumber := lineNumber + 1 ]. self step ]! ! !ROFlowLayout methodsFor: 'hook' stamp: 'AlexandreBergel 11/16/2012 08:59'! doExecute: nodeElements | x y maxLastLineHeight | x := self gapSize. y := self gapSize. maxLastLineHeight := 0. nodeElements do: [ :aNodeFigure | translator translate: aNodeFigure to: x @ y. x := x + aNodeFigure width + (2 * self gapSize). maxLastLineHeight := maxLastLineHeight max: aNodeFigure height. x > self maxWidth ifTrue: [ x := self gapSize. y := y + (2 * self gapSize) + maxLastLineHeight. maxLastLineHeight := 0 ]. self step ]! ! !ROAbstractCompactTree class methodsFor: 'testing' stamp: 'MathieuDehouck 6/3/2013 10:32'! horizontalGap: anInt | new | new := self new. new horizontalGap: anInt. ^ new ! ! !ROAbstractCompactTree class methodsFor: 'testing' stamp: 'MathieuDehouck 6/3/2013 10:33'! horizontalGap: anInt verticalGap: another | new | new := self new. new horizontalGap: anInt. new verticalGap: another. ^ new ! ! !ROAbstractCompactTree class methodsFor: 'testing' stamp: 'AlexandreBergel 4/18/2013 09:03'! isAbstract ^ self name = #ROAbstractCompactTree ! ! !ROAbstractCompactTree class methodsFor: 'testing' stamp: 'MathieuDehouck 6/3/2013 10:32'! verticalGap: anInt | new | new := self new. new verticalGap: anInt. ^ new ! ! !ROAbstractCompactTree methodsFor: 'private' stamp: 'AlexandreBergel 8/27/2013 21:48'! childrenFor: aNode sonsDictionary isEmpty ifTrue: [ ^ super childrenFor: aNode ] ifFalse: [ ^sonsDictionary at: aNode ifAbsent: [ ^ OrderedCollection new ] ]! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/11/2013 10:26'! compareContourOf: aNode with: another "return the number of radians the subtree induced by aNode must be displaced to be separated by a predefined distance (horizontalGap) from the one induced by anotherNode" | difference max nodeA nodeB | nodeB := aNode. "the right one" nodeA := another. "the left one" max := aNode = another ifTrue: [ 0 ] ifFalse: [ horizontalGap / 2 - (nodeB x - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)) ]. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1. [ nodeB isNil not & nodeA isNil not ] whileTrue: [ difference := horizontalGap - ((self getAbcissaOf: nodeB inSubtreeFromLayer: aNode layer - 1) - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)). max := max max: difference. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1 ]. ^ max! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 5/6/2013 12:38'! computePosition: aNode "compute the position of the given node and of his sons recursively" | children neighbor nodeA | children := self childrenFor: aNode. neighbor := self leftSiblingOf: aNode. children isEmpty ifTrue: [ neighbor isNil ifTrue: [ aNode x: 0; mod: 0.] ifFalse: [ aNode x: (neighbor x + (horizontalGap /2)); mod: (neighbor mod); pointer: (self followRightContour: neighbor toLayer: (aNode layer + 1)) ] ] ifFalse: [aNode leftContour: children first; rightContour: children last. children do: [:e | self computePosition: e ]. aNode x: (aNode leftContour x + aNode rightContour x + aNode rightContour mod ) /2; mod: 0. neighbor isNil ifFalse: [ aNode mod: (self compareContourOf: aNode with: neighbor). nodeA := (self followLeftContour: (aNode father) toLayer: (aNode layer)). [(self followLeftContour: nodeA toLayer: (nodeA layer + 1)) isNil ] whileFalse: [ nodeA := self followLeftContour: nodeA toLayer: (nodeA layer + 1) ]. nodeA pointer: (self followLeftContour: aNode toLayer: (nodeA layer + 1)). nodeA := self followRightContour: aNode toLayer: (aNode layer + 1). [(self followRightContour: nodeA toLayer: (nodeA layer +1)) isNil ] whileFalse: [ nodeA := self followRightContour: nodeA toLayer: (nodeA layer +1) ]. nodeA pointer: (self followRightContour: neighbor toLayer: (nodeA layer +1) ) ] ] ! ! !ROAbstractCompactTree methodsFor: 'hook' stamp: 'MathieuDehouck 5/31/2013 16:40'! coordinate: aNode withMod: aFloat self subclassResponsibility! ! !ROAbstractCompactTree methodsFor: 'hook' stamp: 'AlexandreBergel 8/27/2013 21:33'! doExecute: nodeElements | rootNodes | initialLayout isNil ifFalse: [ initialLayout new executeOnElements: nodeElements. ]. rootNodes := self rootNodesFor: nodeElements. " root isNil ifTrue: [ rootNodes := self rootNodesFor: nodeElements. ] ifFalse: [ rootNodes := Array with: root. self coveringTreeFor: nodeElements from: root ]. " rootNodes do: [:e | self initialize: e whoseFatherIs: nil ]; do: [:e | self computePosition:e]. rootNodes do: [:e | self draw:e withMod: 0 ]! ! !ROAbstractCompactTree methodsFor: 'hook' stamp: 'AlexandreBergel 5/7/2013 14:45'! draw: aNode withMod: aFloat self subclassResponsibility! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/9/2013 11:19'! followLeftContour: aNode toLayer: anInteger "return the last node in the left contour begining at anode" (aNode layer = anInteger ) ifTrue: [^ aNode ]. (aNode layer > anInteger ) ifTrue: [^ nil ]. aNode leftContour isNil ifTrue: [ aNode pointer isNil ifTrue: [ ^ nil ] ifFalse: [ ^ ( self followLeftContour: aNode pointer toLayer: anInteger ) ] ] ifFalse: [ ^ (self followLeftContour: aNode leftContour toLayer: anInteger ) ]! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/9/2013 11:19'! followRightContour: aNode toLayer: anInteger "return the node in the right contour begining at anode in layer anInteger" (aNode layer = anInteger ) ifTrue: [^ aNode ]. (aNode layer > anInteger ) ifTrue: [^ nil ]. aNode rightContour isNil ifTrue: [ aNode pointer isNil ifTrue: [ ^ nil ] ifFalse: [ ^ ( self followRightContour: aNode pointer toLayer: anInteger ) ] ] ifFalse: [ ^ (self followRightContour: aNode rightContour toLayer: anInteger ) ]! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/9/2013 11:20'! getAbcissaOf: aNode inSubtreeFromLayer: anInteger | node x | (anInteger < 0) ifTrue: [^ self getAbcissaOf: aNode inSubtreeFromLayer: 0 ]. (aNode layer = anInteger ) ifTrue: [ ^ aNode x ]. (aNode layer < anInteger ) ifTrue: [ ^ nil ]. x := aNode x + aNode mod. node := aNode father. [node layer = anInteger ] whileFalse: [ x := x + node mod. node := node father]. ^ x! ! !ROAbstractCompactTree methodsFor: 'initialize-release' stamp: 'MathieuDehouck 7/22/2013 13:12'! greedyCycleRemoval: aGraph! ! !ROAbstractCompactTree methodsFor: 'initialize-release' stamp: 'MathieuDehouck 5/2/2013 15:15'! initialLayout: aLayout initialLayout := aLayout ! ! !ROAbstractCompactTree methodsFor: 'initialize-release' stamp: 'AlexandreBergel 8/27/2013 21:48'! initialize super initialize. verticalGap := 20. horizontalGap := 30. margin := 40. sonsDictionary := Dictionary new! ! !ROAbstractCompactTree methodsFor: 'initialize-release' stamp: 'MathieuDehouck 5/6/2013 12:43'! initialize: aNode whoseFatherIs: another aNode father: another. another isNil ifTrue: [ aNode layer: 0 ] ifFalse: [ aNode layer: another layer + 1 ] . ( self childrenFor: aNode ) do: [ :e | self initialize: e whoseFatherIs: aNode ]! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 5/6/2013 12:39'! leftSiblingOf: aNode "return the left sibling of the given node " | children | aNode father isNil ifTrue: ["has no sibling" ^ nil] ifFalse: [ children := self childrenFor: aNode father. (children first) = aNode ifTrue: ["as no left sibling" ^ nil ] ifFalse: [^ children at: ((children indexOf: aNode)-1) ] ]! ! !ROAbstractCompactTree methodsFor: 'algorithm' stamp: 'MathieuDehouck 5/30/2013 10:36'! nodeAbcissaWithNeighbor: aNode self subclassResponsibility ! ! !ROAbstractCompactTree methodsFor: 'initialize-release' stamp: 'MathieuDehouck 5/2/2013 14:37'! root: aNode root := aNode ! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/11/2013 10:11'! compareContourOf: aNode with: another "return the number of radians the subtree induced by aNode must be displaced to be separated by a predefined distance (horizontalGap) from the one induced by anotherNode" | difference max nodeA nodeB | nodeB := aNode. "the right one" nodeA := another. "the left one" max := aNode = another ifTrue: [ 0 ] ifFalse: [ horizontalGap / nodeB layer / 2 - (nodeB x - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)) ]. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1. [ nodeB isNil not & nodeA isNil not ] whileTrue: [ difference := horizontalGap / nodeA layer - ((self getAbcissaOf: nodeB inSubtreeFromLayer: aNode layer - 1) - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)). max := max max: difference. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1 ]. ^ max! ! !RORadialTreeLayout methodsFor: 'hook' stamp: 'AlexandreBergel 5/29/2013 09:09'! computeGap: aNode " compute the vertical gap needed for drawing the radial tree " | gap maxAbcissa i abc nodeL nodeR layer | gap := 0. maxAbcissa := 0. layer := 1. i := 1. [ nodeL :=(self followLeftContour: aNode toLayer: i). nodeR := (self followRightContour: aNode toLayer: i). nodeL isNil not & nodeR isNil not ] whileTrue: [ abc := (((self getAbcissaOf: nodeR inSubtreeFromLayer: 0) - (self getAbcissaOf: nodeL inSubtreeFromLayer: 0 ) + (horizontalGap / layer/2)) / layer). (abc > maxAbcissa) ifTrue: [ maxAbcissa := abc. layer := layer ]. i := i + 1 ]. gap:= (maxAbcissa / 2 /Float pi ) floor +1. ((verticalGap isNil) or: [gap > verticalGap]) ifTrue: [ self verticalGap: gap ]! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'AlexandreBergel 5/29/2013 08:59'! computePosition: aNode "compute the position of the given node and of his sons recursively" | children neighbor nodeA | children :=self childrenFor: aNode. neighbor := self leftSiblingOf: aNode. children isEmpty ifTrue: [ neighbor isNil ifTrue: [ aNode x: 0; mod: 0. ] ifFalse: [ aNode x: (neighbor x + (horizontalGap /aNode layer /2)); mod: (neighbor mod); pointer: (self followRightContour: neighbor toLayer: (aNode layer + 1)) ] ] ifFalse: [aNode leftContour: children first; rightContour: children last. children do: [:e | self computePosition: e ]. aNode x: (aNode leftContour x + aNode rightContour x + aNode rightContour mod ) /2; mod: 0. neighbor isNil ifFalse: [ aNode mod: (self compareContourOf: aNode with: neighbor). nodeA := (self followLeftContour: (aNode father) toLayer: (aNode layer)). [(self followLeftContour: nodeA toLayer: (nodeA layer + 1)) isNil ] whileFalse: [ nodeA := self followLeftContour: nodeA toLayer: (nodeA layer + 1) ]. nodeA pointer: (self followLeftContour: aNode toLayer: (nodeA layer + 1)). nodeA := self followRightContour: aNode toLayer: (aNode layer + 1). [(self followRightContour: nodeA toLayer: (nodeA layer +1)) isNil ] whileFalse: [ nodeA := self followRightContour: nodeA toLayer: (nodeA layer +1) ]. nodeA pointer: (self followRightContour: neighbor toLayer: (nodeA layer +1) ) ] ]. ! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 7/25/2013 13:46'! diameterOf: aNode |diam| (aNode shapes first isKindOf: ROEllipse) ifTrue: [ diam := aNode width max: aNode height ] ifFalse: [ diam := (aNode width * aNode width + (aNode height * aNode height)) sqrt floor ]. ^ diam! ! !RORadialTreeLayout methodsFor: 'hook' stamp: 'AlexandreBergel 10/21/2013 15:11'! doExecute: nodeElements | rootNodes | initialLayout isNil ifFalse: [ initialLayout new executeOnElements: nodeElements ]. rootNodes := self rootNodesFor: nodeElements. " root isNil ifTrue: [ rootNodes := self rootNodesFor: nodeElements ] ifFalse: [ rootNodes := Array with: root. self coveringTreeFor: nodeElements from: root ]. " rootNodes do: [ :e | self initialize: e whoseFatherIs: nil ]; do: [ :e | self computePosition: e. self step ]; do: [ :e | self computeGap: e ]; do: [ :e | self toRadialTree: e withMod: 0 ]. rootNodes do: [ :e | self radialDraw: e ]. self moveAllElementsToTopLeft: nodeElements! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/29/2013 09:00'! gap ^ self verticalGap! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 7/25/2013 13:46'! halfDiameterOf: aNode |diam| (aNode shapes first isKindOf: ROEllipse) ifTrue: [ diam := aNode width max: aNode height ] ifFalse: [ diam := (aNode width * aNode width + (aNode height * aNode height)) sqrt floor ]. ^ diam / 2! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 10/21/2013 15:01'! layoutLayer: aCollection radius: oldRadius from: aFromAngle to: aToAngle | delta childRadius maximumRadius myRadius fromAngle toAngle | "Initialize with default value" maximumRadius := oldRadius. aCollection isEmpty ifFalse: [myRadius := oldRadius + self gap + (self maximumRadius: aCollection). childRadius := oldRadius + self gap + (self maximumDiameter: aCollection). "This is a purely optical tweak" (aCollection size = 1 and: [aToAngle - aFromAngle = (2 * Float pi)]) ifTrue: [delta := 0.4 * Float pi. fromAngle := 0.8 * Float pi. toAngle := fromAngle + delta] ifFalse: [delta := (aToAngle - aFromAngle) / aCollection size. fromAngle := aFromAngle. toAngle := aFromAngle + delta]. aCollection do: [:child | translator translate: child to: (Point radius: myRadius theta: toAngle - (delta / 2.0)). "child translateTo: (Point radius: myRadius theta: toAngle - (delta / 2.0))." maximumRadius := maximumRadius max: (self layoutLayer: (self childrenFor: child) radius: childRadius from: fromAngle to: toAngle). fromAngle := toAngle. toAngle := toAngle + delta]]. ^maximumRadius! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:23'! maximumDiameter: aCollection ^aCollection inject: 0 into: [:max :node | max max: (node radius * 2) ] ! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:07'! maximumRadius: aCollection ^aCollection inject: 0 into: [:max :node | max max: node radius]! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 10/21/2013 15:13'! moveAllElementsToTopLeft: elements | pos min | pos := elements collect: #position. min := pos inject: 0 @ 0 into: [ :minimum :p | minimum min: p ]. elements do: [ :e | e translateBy: min negated ] ! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 6/3/2013 14:18'! nodeAbcissaWithNeighbor: aNode ^ aNode x + (horizontalGap / aNode layer /2) + ((self halfDiameterOf: aNode) / aNode layer)! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'AlexandreBergel 10/21/2013 15:02'! radialDraw: aNode "draw the subtree induced by the given node" | children | translator translate: aNode to: (Point radius: (aNode r) theta: (aNode theta)). "aNode translateTo: (Point radius: (aNode r) theta: (aNode theta))." children := self childrenFor: aNode. children do: [ :e | self radialDraw: e ]! ! !RORadialTreeLayout methodsFor: 'hook' stamp: 'MathieuDehouck 6/18/2013 11:13'! rotateSubtreeFrom: aNode by: aFloat aNode theta: aNode theta + aFloat. (self childrenFor: aNode) do: [ :e | self rotateSubtreeFrom: e by: aFloat ]! ! !RORadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:07'! shiftTree: aNode by: aPoint aNode translateBy: aPoint. (self childrenFor: aNode) do: [:child | self shiftTree: child by: aPoint]! ! !RORadialTreeLayout methodsFor: 'hook' stamp: 'MathieuDehouck 6/18/2013 12:45'! spreadNodes: nodeElements around: aNode |nodeL nodeR i angle beta lay1 | i := 1. angle := 0. [ nodeL :=(self followLeftContour: aNode toLayer: i). nodeR := (self followRightContour: aNode toLayer: i). nodeL isNil not & nodeR isNil not ] whileTrue: [ angle := angle max: ((nodeR theta - nodeL theta) + ((self halfDiameterOf: nodeR) + (self halfDiameterOf: nodeL) + horizontalGap /i /verticalGap )). i := i+1. ]. lay1 := nodeElements select: [ :e | e layer = 1 ]. beta := Float pi * 2 - angle / lay1 size. lay1 do: [ :e | self rotateSubtreeFrom: e by: (lay1 indexOf: e) - 1 * beta ].! ! !RORadialTreeLayout methodsFor: 'algorithm' stamp: 'AlexandreBergel 5/29/2013 09:01'! toRadialTree: aNode withMod: aFloat "compute polar coordinates of the subtree induced by anode from its cartesian coordinates " | children | aNode r: (aNode layer * verticalGap ). (aNode r = 0) ifTrue: [ aNode theta: 0 ] ifFalse: [aNode theta: (aNode x + aFloat + aNode mod) / verticalGap ]. children := self childrenFor: aNode. children do: [ :e | self toRadialTree: e withMod: ( aNode mod + aFloat) ]! ! !ROVerticalLaggeredTree methodsFor: 'positioning' stamp: 'MathieuDehouck 4/30/2013 14:49'! compareContourOf: aNode with: another "return the number of pixel the subtree induced by aNode must be displaced to be separated by a predefined distance (horizontalGap) from the one induced by anotherNode" | difference max nodeA nodeB | nodeB := aNode. "the right one" nodeA := another. "the left one" max := aNode = another ifTrue: [ 0 ] ifFalse: [ horizontalGap / 4 - (nodeB x - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)) ]. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1. [ nodeB isNil not & nodeA isNil not ] whileTrue: [ difference := horizontalGap - ((self getAbcissaOf: nodeB inSubtreeFromLayer: aNode layer - 1) - (self getAbcissaOf: nodeA inSubtreeFromLayer: aNode layer - 1)). max := max max: difference. nodeB := self followLeftContour: nodeB toLayer: nodeB layer + 1. nodeA := self followRightContour: nodeA toLayer: nodeA layer + 1 ]. ^ max! ! !ROVerticalLaggeredTree methodsFor: 'positioning' stamp: 'MathieuDehouck 5/6/2013 12:48'! computePosition: aNode "compute the position of the given node and of his sons recursively" | children neighbor nodeA | children := self childrenFor: aNode. neighbor := self leftSiblingOf: aNode. children isEmpty ifTrue: [ neighbor isNil ifTrue: [ aNode x: 0; mod: 0.] ifFalse: [ aNode x: (neighbor x + (horizontalGap /4)); mod: (neighbor mod); top: neighbor top not; pointer: (self followRightContour: neighbor toLayer: (aNode layer + 1)) ] ] ifFalse: [aNode leftContour: children first; rightContour: children last. children do: [:e | self computePosition: e]. aNode x: (aNode leftContour x + aNode rightContour x + aNode rightContour mod ) /2; mod: 0. neighbor isNil ifFalse: [ aNode mod: (self compareContourOf: aNode with: neighbor); top: neighbor top not. nodeA := (self followLeftContour: (aNode father) toLayer: (aNode layer)). [(self followLeftContour: nodeA toLayer: (nodeA layer + 1)) isNil ] whileFalse: [ nodeA := self followLeftContour: nodeA toLayer: (nodeA layer + 1) ]. nodeA pointer: (self followLeftContour: aNode toLayer: (nodeA layer + 1)). nodeA := self followRightContour: aNode toLayer: (aNode layer + 1). [(self followRightContour: nodeA toLayer: (nodeA layer +1)) isNil ] whileFalse: [ nodeA := self followRightContour: nodeA toLayer: (nodeA layer +1) ]. nodeA pointer: (self followRightContour: neighbor toLayer: (nodeA layer +1) ) ] ] ! ! !ROVerticalLaggeredTree methodsFor: 'positioning' stamp: 'AlexandreBergel 5/29/2013 09:40'! draw: aNode withMod: aFloat "draw the subtree induced by the given node, translating it with the given modifier" | children height | height := aNode top ifTrue: [ verticalGap / 4 ] ifFalse: [ 0 ]. aNode translateTo: (Point x: (aNode x + aFloat + aNode mod) y: (aNode layer * verticalGap - height ) ). children := self childrenFor: aNode. children do: [:e | self draw: e withMod: (aNode mod + aFloat). self step ]! ! !ROVerticalLaggeredTree methodsFor: 'positioning' stamp: 'MathieuDehouck 4/30/2013 14:48'! initialize super initialize. verticalGap := 80.! ! !ROAbstractGraphLayout class methodsFor: 'constants'! horizontalGap ^3.0! ! !ROAbstractGraphLayout class methodsFor: 'testing' stamp: 'AlexandreBergel 11/15/2012 13:25'! isAbstract ^ self name = #ROAbstractGraphLayout! ! !ROAbstractGraphLayout class methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2013 18:58'! on: elements edges: edges "Do the layout of the elements tacking into account the provided edges" ^ self new userDefinedEdges: edges; applyOn: elements.! ! !ROAbstractGraphLayout class methodsFor: 'constants'! verticalGap ^20.0! ! !ROAbstractGraphLayout methodsFor: 'private'! cachedChildren cachedChildren ifNil: [cachedChildren := IdentityDictionary new: 1000]. ^cachedChildren! ! !ROAbstractGraphLayout methodsFor: 'private'! cachedParents cachedParents ifNil: [cachedParents := IdentityDictionary new: 1000]. ^cachedParents! ! !ROAbstractGraphLayout methodsFor: 'private'! cachedParentsWithHighestNestings cachedParentsWithHighestNestings ifNil: [cachedParentsWithHighestNestings := IdentityDictionary new: 1000]. ^cachedParentsWithHighestNestings! ! !ROAbstractGraphLayout methodsFor: 'private'! childrenFor: aNode ^self cachedChildren at: aNode ifAbsentPut: [| nodes | nodes := OrderedCollection new. self edgesDo: [:edge | (edge from == aNode and: [edge to ~= aNode]) ifTrue: [(nodes includes: edge from) ifFalse: [nodes add: edge to]]]. nodes]! ! !ROAbstractGraphLayout methodsFor: 'private' stamp: 'TudorGirba 7/29/2012 20:20'! childrenFor: aNode except: aNodeCollection ^(self childrenFor: aNode) reject: [:each | aNodeCollection includes: each] "we are explicitly not using the default Collection>>difference: behavior here because we want to preserve the order of the collection"! ! !ROAbstractGraphLayout methodsFor: 'private'! childrenWithHighestNestingLevelFor: aNode ^(self childrenFor: aNode) select: [:eachChild | (self highestNestingParentFor: eachChild) == aNode]! ! !ROAbstractGraphLayout methodsFor: 'private'! clear cachedParents := nil. cachedChildren := nil. cachedParentsWithHighestNestings := nil! ! !ROAbstractGraphLayout methodsFor: 'default values'! defaultFromPositions ^#(#bottomCenter)! ! !ROAbstractGraphLayout methodsFor: 'default values'! defaultToPositions ^#(#topCenter)! ! !ROAbstractGraphLayout methodsFor: 'hook'! doInitialize: elements super doInitialize: elements. self clear. self greedyCycleRemoval: elements! ! !ROAbstractGraphLayout methodsFor: 'battista' stamp: 'AlexandreBergel 8/27/2013 21:48'! greedyCycleRemoval: aCollection "Di Battista Greedy-Cycle-Removal algorithm. Chapter 9.4, page 297. The last part is not like in the book. The original algorithm only takes local optimas into account. This will break ordinary trees sometimes. This version also takes global optimas into account." | g sl sr s indeg outdeg degrees vertex | g := aCollection copy asOrderedCollection. sl := OrderedCollection new. sr := OrderedCollection new. "While g contains a sink (aka leaf)" g copy do: [:node | (self childrenFor: node) isEmpty ifTrue: [sr addFirst: node. g remove: node] "self edges detect: [:edge | edge fromFigure == node] ifNone: [sr addFirst: node. g remove: node]"]. "While g contains a source (aka root)" g copy do: [:node | (self parentsFor: node) isEmpty ifTrue: [sl addLast: node. g remove: node] "self edges detect: [:edge | edge toFigure == node] ifNone: [sl addLast: node. g remove: node]"]. "Calculate deg for all remaining vertices" degrees := IdentityDictionary new. g do: [:node | indeg := (self parentsFor: node) size. outdeg := (self childrenFor: node) size. "indeg := self edges inject: 0 into: [:sum :edge | (edge toFigure == node) ifTrue: [sum + 1] ifFalse: [sum]]. outdeg := self edges inject: 0 into: [:sum :edge | (edge fromFigure == node) ifTrue: [sum + 1] ifFalse: [sum]]." degrees at: node put: outdeg - indeg]. "While g not empty" g := g asSortedCollection: [:a :b | (degrees at: a) >= (degrees at: b)]. [g isEmpty] whileFalse: [vertex := g detect: [:v | (self parentsFor: v) anySatisfy: [:w | sl includes: w]] ifNone: [g first]. "Corner case: Closed cycle with not root at all. Eg 1 -> 2 -> 3 -> 1" sl addLast: vertex. g remove: vertex]. "Remove all leftward edges" s := sl , sr. self edges notNil ifTrue: [ self edges copy do: [:edge | (s indexOf: edge source) > (s indexOf: edge target) ifTrue: [self edges remove: edge ] ] ]. "Reset the cache" self clear! ! !ROAbstractGraphLayout methodsFor: 'private'! highestNestingParentFor: aNodeFigure | parents | ^self cachedParentsWithHighestNestings at: aNodeFigure ifAbsentPut: [parents := self parentsFor: aNodeFigure. parents isEmpty ifTrue: [0] ifFalse: [parents detectMax: [:eachParent | self nestingLevelFor: eachParent]]]! ! !ROAbstractGraphLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 00:10'! horizontalGap ^horizontalGap ifNil: [ self class horizontalGap ]! ! !ROAbstractGraphLayout methodsFor: 'accessing'! horizontalGap: anInteger horizontalGap := anInteger! ! !ROAbstractGraphLayout methodsFor: 'private'! nestingLevelFor: aNodeFigure | parents parentsNesting | parents := self parentsFor: aNodeFigure. parentsNesting := parents collect: [:eachParent | self nestingLevelFor: eachParent]. ^parentsNesting isEmpty ifTrue: [0] ifFalse: [parentsNesting max + 1] ! ! !ROAbstractGraphLayout methodsFor: 'actions' stamp: 'AlexandreBergel 9/1/2013 20:45'! on: el edges: edgs "Do the layout of the elements tacking into account the provided edges" self userDefinedEdges ifNil: [ self userDefinedEdges: edgs ]. ^ self applyOn: el.! ! !ROAbstractGraphLayout methodsFor: 'private'! parentsFor: aNode ^ self cachedParents at: aNode ifAbsentPut: [ | nodes | nodes := OrderedCollection new. self edgesDo: [:edge | edge to == aNode ifTrue: [ nodes add: edge from ] ]. nodes ]! ! !ROAbstractGraphLayout methodsFor: 'private' stamp: 'AlexandreBergel 8/19/2012 13:18'! rootNodesFor: aCollection ^ aCollection select: [:node | node isNotEdge and: [ (self parentsFor: node) isEmpty ] ]. ! ! !ROAbstractGraphLayout methodsFor: 'accessing'! verticalGap ^verticalGap ifNil: [self class verticalGap]! ! !ROAbstractGraphLayout methodsFor: 'accessing'! verticalGap: anInteger verticalGap := anInteger! ! !ROAbstractHorizontalTreeLayout class methodsFor: 'testing' stamp: 'AlexandreBergel 11/15/2012 13:26'! isAbstract ^ self name = #ROAbstractHorizontalTreeLayout! ! !ROAbstractHorizontalTreeLayout methodsFor: 'hook-private' stamp: 'BenComan 7/28/2012 13:43'! computeChildrenFor: aNode self subclassResponsibility! ! !ROAbstractHorizontalTreeLayout methodsFor: 'hook-private' stamp: 'BenComan 8/5/2012 15:53'! defaultFromPositions ^#(#rightCenter) "BTC-2012-08-05 Not sure what effect this has or if this is a valid symbol - its just pattern matching."! ! !ROAbstractHorizontalTreeLayout methodsFor: 'hook-private' stamp: 'BenComan 8/5/2012 15:53'! defaultToPositions ^#(#leftCenter) "BTC-2012-08-05 Not sure what effect this has or if this is a valid symbol - its just pattern matching."! ! !ROAbstractHorizontalTreeLayout methodsFor: 'initialize-release' stamp: 'BenComan 7/28/2012 13:43'! initialize super initialize. verticalGap := 3. horizontalGap := 20! ! !ROAbstractHorizontalTreeLayout methodsFor: 'hook-private' stamp: 'AlexandreBergel 11/16/2012 09:04'! layout: aNodeCollection atPoint: aPoint atLayer: aNumber | treeSize childrenPosition x y middleOfTree | aNodeCollection isEmpty ifTrue: [ ^ 0 ]. x := aPoint x. y := aPoint y. alreadyLayoutedNodes addAll: aNodeCollection. self atLayer: aNumber add: aNodeCollection. aNodeCollection do: [ :each | childrenPosition := x + each width + self horizontalGap. treeSize := each height max: (self layout: (self computeChildrenFor: each) atPoint: childrenPosition @ y atLayer: aNumber + 1). middleOfTree := y + (treeSize / 2.0) - (each height / 2.0). translator translate: each to: (x @ middleOfTree). y := y + treeSize + self verticalGap. self step ]. ^ y - aPoint y - self verticalGap! ! !ROAbstractHorizontalTreeLayout methodsFor: 'private' stamp: 'TudorGirba 10/1/2012 14:10'! rearrangeByLayers: aGraph | cursor layerDepthSize | cursor := self leftGap. nodesByLayer do: [:eachSetOfNodes | layerDepthSize := eachSetOfNodes inject: 0 into: [:max :eachNode | translator translate: eachNode to: (cursor @ eachNode bounds top). max max: eachNode width ]. cursor := cursor + layerDepthSize + self horizontalGap ]! ! !ROHorizontalDominanceTreeLayout commentStamp: 'TudorGirba 10/1/2012 14:06' prior: 34311852! The dominance tree layout is similar to a regular tree layout, only it poses a stronger condition in the way it places a node: a child is placed under the deepest parent. This layout is for example useful when identifying layers of dependencies. Note: the layout is slower than the tree layout because of the more complex lookup! !ROHorizontalDominanceTreeLayout methodsFor: 'hook-private' stamp: 'TudorGirba 9/27/2012 23:07'! computeChildrenFor: aNode ^ self childrenWithHighestNestingLevelFor: aNode! ! !ROHorizontalTreeLayout methodsFor: 'hook-private' stamp: 'BenComan 7/28/2012 13:50'! computeChildrenFor: aNode ^ self childrenFor: aNode except: alreadyLayoutedNodes! ! !ROAbstractRegularTreeLayout class methodsFor: 'testing' stamp: 'AlexandreBergel 11/15/2012 13:26'! isAbstract ^ self name = #ROAbstractRegularTreeLayout! ! !ROAbstractRegularTreeLayout methodsFor: 'private'! atLayer: aNumber add: aNodeCollection | collection | collection := nodesByLayer at: aNumber ifAbsentPut: [OrderedCollection new]. collection addAll: aNodeCollection! ! !ROAbstractRegularTreeLayout methodsFor: 'hook'! doExecute: elements | rootNodes | alreadyLayoutedNodes := OrderedCollection new. rootNodes := self rootNodesFor: elements. nodesByLayer := OrderedCollection new. self layout: rootNodes atPoint: self leftGap @ self topGap atLayer: 1. self isLayered ifTrue: [ self rearrangeByLayers: elements ]! ! !ROAbstractRegularTreeLayout methodsFor: 'initialize-release'! initialize super initialize. topGap := 5. leftGap := 5. isLayered := false! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! isLayered "Is the layout layered" ^ isLayered! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! isLayered: boolean "Is the layout layered" isLayered := boolean! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! layered self isLayered: true! ! !ROAbstractRegularTreeLayout methodsFor: 'hook-private'! layout: aNodeCollection atPoint: aPoint atLayer: anObject self subclassResponsibility! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! leftGap ^ leftGap! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! leftGap: anInteger leftGap := anInteger! ! !ROAbstractRegularTreeLayout methodsFor: 'private'! rearrangeByLayers: aGraph self subclassResponsibility! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! topGap ^ topGap! ! !ROAbstractRegularTreeLayout methodsFor: 'accessing'! topGap: anInteger topGap := anInteger! ! !ROAbstractVerticalTreeLayout class methodsFor: 'testing' stamp: 'AlexandreBergel 11/15/2012 13:26'! isAbstract ^ self name = #ROAbstractVerticalTreeLayout! ! !ROAbstractVerticalTreeLayout methodsFor: 'hook-private'! computeChildrenFor: aNode self subclassResponsibility! ! !ROAbstractVerticalTreeLayout methodsFor: 'initialize-release'! initialize super initialize. verticalGap := 20. horizontalGap := 3! ! !ROAbstractVerticalTreeLayout methodsFor: 'hook-private' stamp: 'AlexandreBergel 11/16/2012 09:05'! layout: aNodeCollection atPoint: aPoint atLayer: aNumber | treeSize childrenPosition x y middleOfTree | aNodeCollection isEmpty ifTrue: [ ^ 0 ]. x := aPoint x. y := aPoint y. alreadyLayoutedNodes addAll: aNodeCollection. self atLayer: aNumber add: aNodeCollection. aNodeCollection do: [ :each | childrenPosition := y + each height + self verticalGap. treeSize := each width max: (self layout: (self computeChildrenFor: each) atPoint: x @ childrenPosition atLayer: aNumber + 1). middleOfTree := x + (treeSize / 2.0) - (each width / 2.0). translator translate: each to: middleOfTree @ y. x := x + treeSize + self horizontalGap. self step ]. ^ x - aPoint x - self horizontalGap! ! !ROAbstractVerticalTreeLayout methodsFor: 'private' stamp: 'TudorGirba 10/1/2012 14:09'! rearrangeByLayers: aGraph | cursor layerDepthSize | cursor := self topGap. nodesByLayer do: [:eachSetOfNodes | layerDepthSize := eachSetOfNodes inject: 0 into: [:max :eachNode | eachNode translateTo: (eachNode bounds left @ cursor ). max max: eachNode height ]. cursor := cursor + layerDepthSize + self verticalGap ]! ! !RODominanceTreeLayout commentStamp: 'TudorGirba 10/1/2012 14:06' prior: 34312259! The dominance tree layout is similar to a regular tree layout, only it poses a stronger condition in the way it places a node: a child is placed under the deepest parent. This layout is for example useful when identifying layers of dependencies. Note: the layout is slower than the tree layout because of the more complex lookup! !RODominanceTreeLayout methodsFor: 'hook-private' stamp: 'TudorGirba 10/1/2012 13:59'! computeChildrenFor: aNode ^ self childrenWithHighestNestingLevelFor: aNode! ! !ROTreeLayout methodsFor: 'hook-private'! computeChildrenFor: aNode ^ self childrenFor: aNode except: alreadyLayoutedNodes! ! !ROClusterLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/7/2013 12:53'! computePosition: aNode |children previous| children := self childrenFor: aNode. children do: [ :e | self computePosition: e ]. children isEmpty ifTrue: [ externalLayer first = aNode ifFalse: [ previous := externalLayer at: ( externalLayer indexOf: aNode) - 1. (previous father = aNode father) ifTrue: [ aNode x: previous x + (horizontalGap / 2) ] ifFalse: [ aNode x: previous x + horizontalGap] ] ] ifFalse: [ aNode x: aNode leftContour x + aNode rightContour x / 2 ]! ! !ROClusterLayout methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 5/29/2013 09:07'! doExecute: nodeElements | root gap | root := self rootNodesFor: nodeElements . root do: [ :e | self initializeNode: e ]. root do: [ :e | self computePosition: e ]. maxLayer := (root collect: [ :e | e layer ]) max. (root size > 1) ifTrue: [ maxLayer := maxLayer + 1 ]. maxAbcissa := externalLayer last x + horizontalGap . gap := maxAbcissa "+ horizontalGap "/ 2 / Float pi / maxLayer. verticalGap := verticalGap max: gap. root do: [ :e | self draw: e. self step ]. ! ! !ROClusterLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/7/2013 11:47'! draw: aNode (self childrenFor: aNode) do: [ :e | self draw: e ]. aNode translateTo: (Point radius: maxLayer - aNode layer * verticalGap theta: (maxAbcissa - aNode x / maxAbcissa) * 2 * Float pi )! ! !ROClusterLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/7/2013 11:49'! initialize super initialize. verticalGap := 30. horizontalGap := 20. externalLayer := OrderedCollection new! ! !ROClusterLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/7/2013 11:13'! initializeNode: aNode |children| children := self childrenFor: aNode. children do: [ :e | self initializeNode: e. e father: aNode ]. children isEmpty ifTrue: [ aNode layer: 0. externalLayer add: aNode ] ifFalse: [ aNode layer: ((children collect: [ :e | e layer ]) max + 1). aNode leftContour: children first; rightContour: children last ]. ! ! !RONarrowRadialTreeLayout methodsFor: 'hook' stamp: 'AlexandreBergel 7/29/2012 08:48'! doExecute: nodeElements | rootNodes maximumRadius xOffset | rootNodes := self rootNodesFor: nodeElements. xOffset := 0. rootNodes do: [ :node | node translateTo: 0 @ 0. "Move the node to the origin of the coordinate system" maximumRadius := self layoutLayer: (self childrenFor: node) radius: node radius from: 0 to: 2 * Float pi. self shiftTree: node by: (maximumRadius + xOffset) @ maximumRadius. xOffset := xOffset + (2 * maximumRadius) ]! ! !RONarrowRadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:07'! gap ^self verticalGap! ! !RONarrowRadialTreeLayout methodsFor: 'private' stamp: 'VanessaPena 12/2/2012 19:08'! layoutLayer: aCollection radius: oldRadius from: aFromAngle to: aToAngle | delta childRadius maximumRadius myRadius fromAngle toAngle | "Initialize with default value" maximumRadius := oldRadius. aCollection isEmpty ifFalse: [myRadius := oldRadius + self gap + (self maximumRadius: aCollection). childRadius := oldRadius + self gap + (self maximumDiameter: aCollection). "This is a purely optical tweak" (aCollection size = 1 and: [aToAngle - aFromAngle = (2 * Float pi)]) ifTrue: [delta := 0.4 * Float pi. fromAngle := 0.8 * Float pi. toAngle := fromAngle + delta] ifFalse: [delta := (aToAngle - aFromAngle) / aCollection size. fromAngle := aFromAngle. toAngle := aFromAngle + delta]. aCollection do: [:child | child translateTo: (Point radius: myRadius theta: toAngle - (delta / 2.0)). maximumRadius := maximumRadius max: (self layoutLayer: (self childrenFor: child) radius: childRadius from: fromAngle to: toAngle). fromAngle := toAngle. toAngle := toAngle + delta]]. ^maximumRadius! ! !RONarrowRadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:23'! maximumDiameter: aCollection ^aCollection inject: 0 into: [:max :node | max max: (node radius * 2) ] ! ! !RONarrowRadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:07'! maximumRadius: aCollection ^aCollection inject: 0 into: [:max :node | max max: node radius]! ! !RONarrowRadialTreeLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/17/2012 20:07'! shiftTree: aNode by: aPoint aNode translateBy: aPoint. (self childrenFor: aNode) do: [:child | self shiftTree: child by: aPoint]! ! !ROHorizontalNarrowTreeLayout methodsFor: 'default values' stamp: 'JurajKubelka 4/2/2013 10:17'! defaultFromPositions ^#(#rightCenter)! ! !ROHorizontalNarrowTreeLayout methodsFor: 'default values' stamp: 'JurajKubelka 4/2/2013 10:17'! defaultToPositions ^#(#leftCenter)! ! !ROHorizontalNarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:17'! shapeTree: aRoot position: xOffset | treeHeight layerKeys layer layerHeight horizontalPosition verticalPosition | self buildLayers: aRoot. treeHeight := self currentTreeSize. horizontalPosition := self horizontalGap. "For visual reasons NOT: self class verticalGap" layerKeys := layers keys asSortedCollection. layerKeys do: [:aKey | layer := layers at: aKey. layerHeight := layer width: self horizontalGap. verticalPosition := treeHeight / 2.0 + xOffset - (layerHeight / 2.0). layer do: [:aFigure | aFigure translateTo: horizontalPosition @ verticalPosition. verticalPosition := verticalPosition + aFigure width + self horizontalGap]. horizontalPosition := horizontalPosition + layer height + self verticalGap]. ^treeHeight! ! !RONarrowTreeLayout class methodsFor: 'testing' stamp: 'JurajKubelka 4/2/2013 11:30'! isAbstract ^ self name = #RONarrowTreeLayout! ! !RONarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 17:28'! atLayer: aLayer add: aFigure "Associates the figure aFigure with the layer aLayer" | layer | layer := layers at: aLayer ifAbsent: [layers at: aLayer put: ROTreeLayerWrapper new. layers at: aLayer]. layer add: aFigure! ! !RONarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:16'! buildLayers: aRoot layers := Dictionary new. self buildLayers: aRoot layer: 0! ! !RONarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:16'! buildLayers: aRoot layer: aLayer self atLayer: aLayer add: aRoot. (self childrenFor: aRoot) do: [:aChild | self buildLayers: aChild layer: aLayer + 1 ]! ! !RONarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:16'! currentTreeSize | maximum | maximum := 0. layers values do: [:aLayer | maximum := maximum max: (aLayer width: self horizontalGap)]. ^maximum! ! !RONarrowTreeLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/2/2013 11:59'! doExecute: elements | roots offset treeWidth | roots := self rootNodesFor: elements. offset := self horizontalGap. roots do: [ :aRoot | treeWidth := self shapeTree: aRoot position: offset. offset := offset + treeWidth + (2 * self horizontalGap). self step]! ! !RONarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:16'! shapeTree: aRoot position: xOffset self subclassResponsibility! ! !ROVerticalNarrowTreeLayout methodsFor: 'private' stamp: 'JurajKubelka 4/2/2013 10:17'! shapeTree: aRoot position: xOffset | treeWidth layerKeys layer layerWidth horizontalPosition verticalPosition | self buildLayers: aRoot. treeWidth := self currentTreeSize. verticalPosition := self horizontalGap. "For visual reasons NOT: self class verticalGap" layerKeys := layers keys asSortedCollection. layerKeys do: [:aKey | layer := layers at: aKey. layerWidth := layer width: self horizontalGap. horizontalPosition := treeWidth / 2.0 + xOffset - (layerWidth / 2.0). layer do: [:aFigure | aFigure translateTo: horizontalPosition @ verticalPosition. horizontalPosition := horizontalPosition + aFigure width + self horizontalGap]. verticalPosition := verticalPosition + layer height + self verticalGap]. ^treeWidth! ! !ROReversedRadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 6/18/2013 12:55'! computePosition: aNode |children previous| children := self childrenFor: aNode. children do: [ :e | self computePosition: e ]. children isEmpty ifTrue: [ externalLayer first = aNode ifFalse: [ previous := externalLayer at: ( externalLayer indexOf: aNode) - 1. (previous father = aNode father) ifTrue: [ aNode x: previous x + (self halfDiameterOf: previous) + (self halfDiameterOf: aNode) + (horizontalGap / 2) ] ifFalse: [ aNode x: previous x + (self halfDiameterOf: previous) + (self halfDiameterOf: aNode) + horizontalGap] ] ] ifFalse: [ aNode x: aNode leftContour x + aNode rightContour x / 2 ]! ! !ROReversedRadialTreeLayout methodsFor: 'hook' stamp: 'MathieuDehouck 7/25/2013 15:53'! doExecute: nodeElements | root gap min | root := self rootNodesFor: nodeElements . root do: [ :e | self initializeNode: e ]. root do: [ :e | self computePosition: e ]. maxLayer := (root collect: [ :e | e layer ]) max. (root size > 1) ifTrue: [ maxLayer := maxLayer + 1 ]. maxAbcissa := externalLayer last x + (self halfDiameterOf: externalLayer last) + horizontalGap + (self halfDiameterOf: externalLayer first) . gap := maxAbcissa / 2 / Float pi / maxLayer. gap := gap max: ( nodeElements collect: [ :e | self halfDiameterOf: e ] ) max * 2 . verticalGap := verticalGap max: gap. root do: [ :e | self draw: e. self step ]. min := (nodeElements collect: [ :e | e position x] ) min @ (nodeElements collect: [ :e | e position y]) min. nodeElements do: [ :e | e translateBy: min negated ]! ! !ROReversedRadialTreeLayout methodsFor: 'drawing-general' stamp: 'MathieuDehouck 6/18/2013 13:03'! draw: aNode | a | (self childrenFor: aNode) do: [ :e | self draw: e ]. aNode translateTo: (Point radius: maxLayer - aNode layer * verticalGap theta: (maxAbcissa - aNode x / maxAbcissa) * 2 * Float pi ). a := (self halfDiameterOf: aNode ) / 2 sqrt negated. aNode translateBy: ( a @ a ).! ! !ROReversedRadialTreeLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 6/18/2013 12:53'! halfDiameterOf: aNode |diam| (aNode shapes first isKindOf: ROEllipse) ifTrue: [ diam := aNode width max: aNode height ] ifFalse: [ diam := (aNode width * aNode width + (aNode height * aNode height)) sqrtFloor ]. ^ diam / 2! ! !ROReversedRadialTreeLayout methodsFor: 'initialize-release' stamp: 'MathieuDehouck 5/7/2013 11:49'! initialize super initialize. verticalGap := 30. horizontalGap := 20. externalLayer := OrderedCollection new! ! !ROReversedRadialTreeLayout methodsFor: 'initialize-release' stamp: 'MathieuDehouck 5/7/2013 11:13'! initializeNode: aNode |children| children := self childrenFor: aNode. children do: [ :e | self initializeNode: e. e father: aNode ]. children isEmpty ifTrue: [ aNode layer: 0. externalLayer add: aNode ] ifFalse: [ aNode layer: ((children collect: [ :e | e layer ]) max + 1). aNode leftContour: children first; rightContour: children last ]. ! ! !ROSugiyamaLayout class methodsFor: 'utils'! sortBlock ^ ROSortBlock new! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/3/2012 19:38'! addDummyNodes | layer layerNr | connections := ROIdentityMatrix new. self edgesDo: [:edge | | a b span fromNode toNode | "edge hints removeAll." a := layerNrs at: edge source. b := layerNrs at: edge target. span := (a - b) abs. span = 1 ifTrue: [connections at: edge source at: edge target put: true]. "Normal case where nodes are in adjacent layers" fromNode := edge source. [span > 1] whileTrue: [span := span - 1. layerNr := b + span. layer := layers at: layerNr. toNode := RODummyNode on: edge slot: a - span. layer add: toNode. layerNrs at: toNode put: layerNr. connections at: fromNode at: toNode put: true. fromNode := toNode]. (a - b) abs > 1 ifTrue: [connections at: fromNode at: edge target put: true]]! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 4/19/2012 08:45'! assignLabels: aNodeCollection "Initialize label dictionary" | label vertices parentLabels | labels := IdentityDictionary new. label := 1. "Assign labels to the roots" (self rootNodesFor: aNodeCollection) do: [ :node | labels at: node put: label. label := label + 1 ]. "Assign labels to the rest" [ labels keys size < aNodeCollection size ] whileTrue: [ vertices := SortedCollection sortBlock: self sortBlock. aNodeCollection do: [ :node | (labels includesKey: node) ifFalse: [ parentLabels := ((self parentsFor: node) collect: [ :pn | labels at: pn ifAbsent: [ self maxFloat ] ]) asSortedCollection. parentLabels last ~= self maxFloat ifTrue: [ vertices add: node -> parentLabels ] ] ]. labels at: vertices first key put: label. label := label + 1 ]! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 4/19/2012 08:45'! buildLayers: g | w layerNr u vertices vertex layer done | w := self maxFloat. u := OrderedCollection new. layers := IdentityDictionary new. layerNrs := IdentityDictionary new. "Assign all nodes to layers" [g isEmpty] whileFalse: [vertices := g select: [:e | (self childrenFor: e) allSatisfy: [:node | u includes: node]]. vertex := vertices detectMax: [:e | labels at: e]. done := false. layerNr := 1. [done] whileFalse: [layer := layers at: layerNr ifAbsentPut: [OrderedCollection new]. (layer size >= w or: [(self childrenFor: vertex) anySatisfy: [:n | (layerNrs at: n) >= layerNr]]) ifTrue: [layerNr := layerNr + 1] ifFalse: [done := true]]. layer add: vertex. layerNrs at: vertex put: layerNr. u add: vertex. g remove: vertex]! ! !ROSugiyamaLayout methodsFor: 'private'! cl: layer u: u v: v "Calculates cuv. Di Battista, chapter 9.2.2, page 283" | partnersOfU partnersOfV c partnersOfUIndex partnersOfVIndex layerNr | layerNr := layerNrs at: u. ":= layerNrs at: v" partnersOfU := (connections at: u) select: [:each | (layerNrs at: each) = (layerNr - 1)]. partnersOfV := (connections at: v) select: [:each | (layerNrs at: each) = (layerNr - 1)]. c := 0. partnersOfUIndex := partnersOfU collect: [:node | layer indexOf: node]. partnersOfVIndex := partnersOfV collect: [:node | layer indexOf: node]. partnersOfUIndex do: [:uIndex | partnersOfVIndex do: [:vIndex | vIndex < uIndex ifTrue: [c := c + 1]]]. ^c! ! !ROSugiyamaLayout methodsFor: 'hook'! doExecute: aNodeCollection "Coffman-Graham-Layering. Di Battista Book, page 275, chapter, 9.2.1" self assignLabels: aNodeCollection. self buildLayers: aNodeCollection copy. self addDummyNodes. self reduceCrossing. self layoutAt: self verticalGap @ self horizontalGap! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/20/2012 19:15'! layoutAt: aPoint | treeWidth layerKeys layer layerWidth horizontalPosition verticalPosition layerHeight | treeWidth := layers values inject: self maxFloat negated into: [:max :e | max max: (e sum: #width) + ((e size - 1) * self horizontalGap)]. verticalPosition := self horizontalGap. "For visual reasons NOT: self class verticalGap" layerKeys := layers keys asSortedCollection reverse. layerKeys do: [:aKey | layer := layers at: aKey. layerWidth := (layer sum: #width) + ((layer size - 1) * self horizontalGap). layerHeight := (layer detectMax: #height) height. horizontalPosition := treeWidth / 2.0 + aPoint x - (layerWidth / 2.0). layer do: [:node | translator translate: node to: horizontalPosition @ verticalPosition. horizontalPosition := horizontalPosition + node width + self horizontalGap]. verticalPosition := verticalPosition + layerHeight + self verticalGap]! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 4/19/2012 08:44'! maxFloat ^ 1e10! ! !ROSugiyamaLayout methodsFor: 'private' stamp: 'AlexandreBergel 5/3/2012 19:16'! reduceCrossing "Crossing reduction" | layer2 u v c1 c2 layer1 done | 2 to: layers keys size do: [:index | layer1 := layers at: index - 1. layer2 := layers at: index. done := false. [done] whileFalse: [done := true. 2 to: layer2 size do: [:i | u := layer2 at: i - 1. v := layer2 at: i. c1 := self cl: layer1 u: u v: v. c2 := self cl: layer1 u: v v: u. c1 > c2 ifTrue: [layer2 roSwapElement: u withElement: v. done := false]]]]! ! !ROSugiyamaLayout methodsFor: 'private'! sortBlock sortBlock isNil ifTrue: [ sortBlock := self class sortBlock ]. ^sortBlock! ! !ROEdgeDrivenLayout class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 11/15/2012 13:25'! isAbstract ^ self name = #ROEdgeDrivenLayout! ! !ROEdgeDrivenLayout class methodsFor: 'instance creation'! withEdges: aCollection ^self new initialize userDefinedEdges: aCollection! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! affectedNodes ^affectedNodes! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! affectedNodes: anObject affectedNodes := anObject! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! affectedNodesOf: aNode ^ affectedNodes ifNil: [ aNode nodes ]! ! !ROEdgeDrivenLayout methodsFor: 'default values'! defaultFromPositions ^ #() ! ! !ROEdgeDrivenLayout methodsFor: 'default values'! defaultToPositions ^ #() ! ! !ROEdgeDrivenLayout methodsFor: 'hook'! doExecute: aGraphElement self subclassResponsibility! ! !ROEdgeDrivenLayout methodsFor: 'hook'! doIncrementallyExecute: anElementNode "called by refreshLayoutEvery: ms. It is used to convey a feeling of incremental execution." self doExecute: anElementNode! ! !ROEdgeDrivenLayout methodsFor: 'private'! edges ^edges! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! edges: aCollection edges := aCollection! ! !ROEdgeDrivenLayout methodsFor: 'iterator'! edgesDo: aBlock "Iterates over all the edges of the receiver." edges ifNil: [ ^ self ]. edges do: aBlock ! ! !ROEdgeDrivenLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/18/2012 16:03'! executeOnElements: elements "Execute the layout, myself, on the elements" self userDefinedEdges isNil ifTrue: [ self setEdgesFromElements: elements ] ifFalse: [ | flat | flat := OrderedCollection new. self userDefinedEdges do: [ :each | each isCollection ifTrue: [ flat addAll: each ] ifFalse: [ flat add: each ] ]. self edges: flat ]. super executeOnElements: elements! ! !ROEdgeDrivenLayout methodsFor: 'private'! fromPositions ^fromPositions ifNil: [fromPositions := self defaultFromPositions]! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! fromPositions: anArray fromPositions := anArray! ! !ROEdgeDrivenLayout methodsFor: 'initialize-release'! initialize "Initialization" super initialize. edges := nil! ! !ROEdgeDrivenLayout methodsFor: 'testing'! isLineLayout ^ false! ! !ROEdgeDrivenLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 7/20/2012 18:17'! setEdgesFromElements: elements | view | elements isEmpty ifTrue: [ ^ self ]. self assert: [ (elements collect: #view) asSet size = 1 ]. elements isEmpty ifTrue: [ ^ self ]. view := elements anyOne view. self edges: (view elementsSuchThat: [ :el | ((el isKindOf: ROEdge) and: [ elements includes: el from ]) and: [ elements includes: el to ] ]). ! ! !ROEdgeDrivenLayout methodsFor: 'private'! toPositions ^toPositions ifNil: [toPositions := self defaultToPositions]! ! !ROEdgeDrivenLayout methodsFor: 'accessing'! toPositions: anArray toPositions := anArray! ! !ROEdgeDrivenLayout methodsFor: 'private'! userDefinedEdges ^userDefinedEdges! ! !ROEdgeDrivenLayout methodsFor: 'initialize-release' stamp: 'AlexandreBergel 9/9/2012 20:03'! userDefinedEdges: aCollectionOfEdges "useful to tell to the layout which edges have to be used for the layout" userDefinedEdges := aCollectionOfEdges. ! ! !ROForceBasedLayout commentStamp: '' prior: 34312649! A ROForceBasedLayout is inspired from the Code of D3. The original d3 version may be found on: http://bl.ocks.org/mbostock/4062045 Layout algorithm inspired by Tim Dwyer and Thomas Jakobsen. Instance Variables alpha: center: charge: charges: fixedNodes: friction: gravity: layoutInitial: length: lengths: nodes: oldPositions: strength: strengths: theta: weights: alpha - xxxxx center - xxxxx charge - xxxxx charges - xxxxx fixedNodes - xxxxx friction - xxxxx gravity - xxxxx layoutInitial - xxxxx length - xxxxx lengths - xxxxx nodes - xxxxx oldPositions - xxxxx strength - xxxxx strengths - xxxxx theta - xxxxx weights - xxxxx ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/29/2013 12:59'! accumulate: aQuad | cx cy k random | cx := 0. cy := 0. aQuad charge: 0; cx: 0; cy: 0. random := Random new. aQuad leaf ifFalse: [ aQuad nodes do: [ :e | e isNil ifFalse: [ self accumulate: e. aQuad charge: aQuad charge + e charge. cx := cx + (e charge * e cx). cy := cy + (e charge * e cy) ] ] ]. aQuad node isNil ifFalse: [ aQuad leaf ifFalse: [ aQuad node position: aQuad node position + (random next - 0.5 @ ( random next - 0.5)) ]. k := alpha * (self chargeOf: aQuad node). aQuad charge: aQuad charge + k. cx := cx + (k * aQuad node position x). cy := cy + (k * aQuad node position y).]. aQuad charge = 0 ifTrue: [ ^ self ]. aQuad cx: cx / aQuad charge. aQuad cy: cy / aQuad charge.! ! !ROForceBasedLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 4/30/2013 12:54'! charge: aFloat charge := aFloat! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/29/2013 12:55'! chargeOf: aNode ^ charges at: aNode ifAbsent: [ ^ charge ] ! ! !ROForceBasedLayout methodsFor: 'hook' stamp: 'AlexandreBergel 5/17/2013 10:35'! doExecute: nodeElements self start: nodeElements. [ alpha := alpha * 0.99 . alpha > 0.005 ] whileTrue: [ self step ]. alpha := 0. nodes do: [ :e | e translateTo: e position ]. ! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 11:46'! fix: aNode at: aPoint fixedNodes at: aNode put: aPoint ! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 12:51'! gravityAt: aPoint center := aPoint ! ! !ROForceBasedLayout methodsFor: 'hook' stamp: 'MathieuDehouck 4/17/2013 14:21'! initialPositionOfNodes: nodeElements layoutInitial new executeOnElements: nodeElements! ! !ROForceBasedLayout methodsFor: 'initialize-release' stamp: 'MathieuDehouck 4/30/2013 12:52'! initialize super initialize. layoutInitial := ROGridLayout. fixedNodes := Dictionary new. strengths := Dictionary new. lengths := Dictionary new. charges := Dictionary new. strength := 1. length := 20. charge := -30. gravity := 0.1. friction := 0.9. theta := 0.8. center := 200@200.! ! !ROForceBasedLayout methodsFor: 'testing' stamp: 'MathieuDehouck 4/29/2013 13:23'! isFixed: aNode ^ fixedNodes includesKey: aNode ! ! !ROForceBasedLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 5/2/2013 13:59'! iterationsToSendEvent: anInteger currentIteraction := anInteger! ! !ROForceBasedLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 4/30/2013 12:53'! length: aFloat length := aFloat! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/29/2013 12:55'! lengthOf: anEdge ^ lengths at: anEdge ifAbsent: [ ^ length ] ! ! !ROForceBasedLayout methodsFor: 'hook' stamp: 'MathieuDehouck 4/18/2013 10:43'! on: elements edges: edgesCol nodes := elements. self applyOn: elements! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/29/2013 13:02'! repulse: aNode from: aQuad | dx dy dn k p | dx := aQuad cx - aNode position x. dy := aQuad cy - aNode position y. ((dx closeTo: 0) and: [ dy closeTo: 0 ] ) ifFalse: [ dn := 1 / ((dx * dx) + (dy * dy)) sqrt. p := oldPositions at: aNode. aQuad node ~= aNode ifTrue: [ aQuad corner x - aQuad origin x * dn < theta ifTrue: [ k := aQuad charge * dn * dn. oldPositions at: aNode put: p x - (dx * k) @ (p y - (dy * k) ). ^ self]. (aQuad node isNil not and: [ dn < 1e9 ]) ifTrue: [ k := (self chargeOf: aQuad node) * dn * dn * alpha. oldPositions at: aNode put: p x - (dx * k) @ (p y - (dy * k) ) ] ]. ]. (aQuad charge closeTo: 0) not ifTrue: [ aQuad nodes do: [ :e | e isNil ifFalse: [ self repulse: aNode from: e ] ] ]! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 12:55'! set: aNode charge: aFloat charges at: aNode put: aFloat! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 12:56'! set: anEdge length: aFloat lengths at: anEdge put: aFloat! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 12:56'! set: anEdge length: aFloat strength: another lengths at: anEdge put: aFloat. strengths at: anEdge put: another ! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/30/2013 12:55'! set: anEdge strength: aFloat strengths at: anEdge put: aFloat! ! !ROForceBasedLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 4/29/2013 12:46'! start: nodeElements self initialPositionOfNodes: nodeElements. weights := Dictionary new. oldPositions := Dictionary new. nodes := nodeElements. nodes do: [ :e | weights add: (Association key: e value: 0). oldPositions add:(Association key: e value: e position) ]. edges do: [ :e | | from to | from := e from. to := e to. weights at: from put: ((weights at: from) + 1). weights at: to put: ((weights at: to) + 1)]. alpha := 0.1. ! ! !ROForceBasedLayout methodsFor: 'events' stamp: 'AlexandreBergel 5/17/2013 10:45'! step "run a step of the force layout algorithm" | from to fp tp x y len k quad old | super step. edges do: [ :e | from := e from. fp := from position. to := e to. tp := to position. x := tp x - fp x. y := tp y - fp y. len := ((x * x) + (y * y)) sqrt. ((len closeTo: 0) not) ifTrue: [ len := alpha * (self strengthOf: e) * ( len - (self lengthOf: e) ) / len. x := x * len. y := y * len. k := (weights at: from) / (( weights at: from) +( weights at: to )). to translateTo: ( tp x - (x * k) )@( tp y - (y * k) ). k := 1 - k. from translateTo: ( fp x + (x * k) )@( fp y + (y * k) ) ] ]. k := alpha * gravity. ((k closeTo: 0) not) ifTrue: [ x := center x. y := center y. nodes do: [ :ea | |pos| pos := ea position. ea translateTo: (pos x + (( x - pos x )* k ) )@(pos y + (( y - pos y )* k ) ) ] ]. quad := ROQuadTree withAll: nodes. self accumulate: quad. nodes do: [ :e | (self isFixed: e) ifFalse: [ self repulse: e from: quad ] ifTrue: [ e translateTo: (fixedNodes at: e) ] ]. nodes do: [ :e | old := e position . e translateTo: (old x - (( (oldPositions at: e) x - old x ) * friction)) @ (old y - (( (oldPositions at: e) y - old y ) * friction)). oldPositions at: e put: old.].! ! !ROForceBasedLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 4/30/2013 12:53'! strength: aFloat strength := aFloat! ! !ROForceBasedLayout methodsFor: 'algorithm' stamp: 'MathieuDehouck 4/29/2013 12:55'! strengthOf: anEdge ^ strengths at: anEdge ifAbsent: [ ^ strength ] ! ! !ROLayout class methodsFor: 'public' stamp: 'AlexandreBergel 11/15/2012 13:29'! isAbstract ^ self name = #ROLayout! ! !ROLayout class methodsFor: 'public' stamp: 'AlexandreBergel 11/15/2012 13:24'! isNotAbstract ^ self isAbstract not! ! !ROLayout class methodsFor: 'public' stamp: 'AlexandreBergel 4/23/2013 15:08'! on: aCollection "main entry point of the class" "If aCollection is empty, then there is not much to do" aCollection isEmpty ifTrue: [ ^ aCollection ]. self new applyOn: aCollection. ^ aCollection! ! !ROLayout class methodsFor: 'public'! on: elements edges: edges "To make all the layout polymorphic" ^ self on: elements ! ! !ROLayout class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2013 18:40'! onElement: aRoassalViewOrRoassalElement ^ self on: aRoassalViewOrRoassalElement elements! ! !ROLayout class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2013 18:33'! onView: aRoassalView ^ self on: aRoassalView elements! ! !ROLayout methodsFor: 'events' stamp: 'AlexandreBergel 11/15/2012 13:11'! announce: anEvent "trigger an event. Objects who registered to me will get notified" | eventToBeSent | eventToBeSent := anEvent isBehavior ifTrue: [ anEvent new ] ifFalse: [ anEvent ]. eventToBeSent layout: self. eventHandler announce: eventToBeSent! ! !ROLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/23/2013 15:41'! applyOn: elements "Return quickly if there is nothing to do" elements isEmpty ifTrue: [ ^ self ]. self executeOnElements: elements! ! !ROLayout methodsFor: 'configuration' stamp: 'AlexandreBergel 4/30/2013 18:25'! defaultIterationsToSendEvent "Every 100 steps an event ROLayoutStep is sent" ^ 100! ! !ROLayout methodsFor: 'hook' stamp: 'JurajKubelka 4/22/2013 15:11'! doExecute: elements "Performs the layout" self subclassResponsibility! ! !ROLayout methodsFor: 'hook' stamp: 'AlexandreBergel 3/11/2013 09:26'! doInitialize: elements "Method executed before beginning the layout. Useful when the graph to be ordered need to be prepared" self announce: (ROLayoutBegin new elements: elements).! ! !ROLayout methodsFor: 'hook' stamp: 'AlexandreBergel 3/11/2013 09:23'! doPost: elements "Method executed after performing the layout" self announce: (ROLayoutEnd new elements: elements).! ! !ROLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 3/11/2013 09:20'! executeOnElements: elements "Execute the layout, myself, on the elements" maxInterations := elements size. self doInitialize: elements. self doExecute: elements asOrderedCollection. self doPost: elements. ! ! !ROLayout methodsFor: 'initialize-release' stamp: 'AlexandreBergel 4/30/2013 18:26'! initialize translator := ROLayoutTranslator default. eventHandler := ROAnnouncer new. currentIteraction := 0. maxInterations := 0. iterationsToSendEvent := self defaultIterationsToSendEvent ! ! !ROLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 4/30/2013 18:24'! iterationsToSendEvent "This method return the amount of iterations before sending ROLayoutStep" ^ iterationsToSendEvent! ! !ROLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 4/30/2013 18:26'! iterationsToSendEvent: anInteger iterationsToSendEvent := anInteger! ! !ROLayout methodsFor: 'hook'! on: elements self applyOn: elements! ! !ROLayout methodsFor: 'events' stamp: 'AlexandreBergel 11/15/2012 13:11'! on: eventClass do: aBlock "Register a block as an handler for eventClass" eventHandler when: eventClass do: aBlock.! ! !ROLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/18/2012 11:38'! on: elements edges: edges self applyOn: elements! ! !ROLayout methodsFor: 'padding' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingFor: elements ^ (self resizeStrategyFor: elements) padding! ! !ROLayout methodsFor: 'padding' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingLeftFor: elements ^ (self resizeStrategyFor: elements) paddingLeft! ! !ROLayout methodsFor: 'padding' stamp: 'AlexandreBergel 4/24/2013 09:20'! paddingTopFor: elements ^ (self resizeStrategyFor: elements) paddingTop! ! !ROLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/23/2013 15:32'! resizeStrategyFor: elements "Return the resize strategy of these elements. This method assumes that all the elements have the same parent." ^ elements anyOne parent resizeStrategy! ! !ROLayout methodsFor: 'events' stamp: 'AlexandreBergel 11/16/2012 09:09'! step currentIteraction := currentIteraction + 1. (currentIteraction \\ self iterationsToSendEvent) = 0 ifTrue: [ self announce: (ROLayoutStep new currentIteration: currentIteraction; maxInterations: maxInterations) ]. ! ! !ROLayout methodsFor: 'accessing'! translator ^ translator! ! !ROLayout methodsFor: 'accessing'! translator: t translator := t! ! !RONullLayout commentStamp: '' prior: 34313542! A RONullLayout does not relocate nodes! !RONullLayout methodsFor: 'hook' stamp: 'AlexandreBergel 7/14/2012 15:52'! doExecute: elements "do nothing"! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/23/2013 16:15'! cornerFor: r and: c | w h | w := 0. h := 0. (1 to: c - 1) do: [ :e | w := w + (columns at: e) ]. (1 to: r - 1) do: [ :e | h := h + (rows at: e) ]. ^ (w @ h)! ! !RORectanglePackingLayout methodsFor: 'hook' stamp: 'AlexandreBergel 10/16/2013 08:41'! doExecute: nodeElements | surface t | resizeStrategy isNil ifFalse: [ self nodeResize: nodeElements ]. nodeElements sort: [ :first :second | (first perform: #height) < (second perform: #height) ]. nodeElements sort: [ :first :second | first width > second width ]. surface := (nodeElements inject: 0 into: [ :sum : e | sum + (e width + padding * (e height + padding)) ] ). t := (surface / ratioWidth / ratioHeight ) sqrt ceiling. width := ratioWidth * t. height := ratioHeight * t. [ nodeElements first width > width ] whileTrue: [ self resize ]. rows add: height. columns add: width. [ self place: nodeElements ] whileFalse: [ self resize ]. " the following indicates the proportion of filling in per cent in the Transcript |w h eff| Transcript open. w := (nodeElements collect: [ :e | e position x + e width + padding ]) max. h := (nodeElements collect: [ :e | e position y + e height + padding ]) max. eff := surface / h / w * 100. Transcript show: eff asFloat ; show: '%'; cr; cr ]. "! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/24/2013 10:10'! findSpaceFor: extent | r c bool space | bool := false. r := 1. c := 1. [ bool ] whileFalse: [ [ matrix at: r at: c ] whileFalse: [ r < matrix rowCount ifTrue: [ r := r + 1 ] ifFalse: [ c < matrix columnCount ifTrue: [ r := 1. c := c + 1 ] ifFalse: [ ^ false ] ] ]. space := self spaceFrom: r and: c. (space x >= extent x and: [ space y >= extent y ]) ifTrue: [ ^ c@r ]. r < matrix rowCount ifTrue: [ r := r + 1 ] ifFalse: [ c < matrix columnCount ifTrue: [ r := 1. c := c + 1 ] ifFalse: [ ^ false ] ] ]! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:56'! heightLog: nodeElements nodeElements do: [ :e | e height > heightStone ifTrue: [ e height: (e height log * heightScale ) ceiling ]]! ! !RORectanglePackingLayout methodsFor: 'initialize-release' stamp: 'AlexandreBergel 10/16/2013 08:42'! initialize super initialize. ratioWidth := 2. ratioHeight := 3. padding := 4. matrix := Matrix rows: 1 columns: 1. matrix at: 1 at: 1 put: true. rows := OrderedCollection new. columns := OrderedCollection new. logWidth := false. logHeight := false! ! !RORectanglePackingLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 5/23/2013 17:09'! insert: aNode | corner cell | cell := self findSpaceFor: (aNode extent + ( padding @ padding )). cell = false ifTrue: [ ^ false ] . corner := self cornerFor: cell y and: cell x. aNode translateTo: corner. self updateMatrixWith: (aNode extent + ( padding @ padding )) at: cell y and: cell x. ^ true! ! !RORectanglePackingLayout methodsFor: 'Nodes-Resizing' stamp: 'MathieuDehouck 5/29/2013 14:04'! linearReduceBiggestOf: anInt resizeStrategy := #linear. scale := anInt! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:50'! logHeightIfMoreThan: anInt "if height of a renctangle is bigger than anInt, we change it with his log" logHeight := true. heightStone := anInt. heightScale := 5! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:51'! logHeightIfMoreThan: anInt scale: anOther "if height of a renctangle is bigger than anInt, we change it with his log" logHeight := true. heightStone := anInt. heightScale := anOther! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:48'! logIfMoreThan: anInt scale: anOther "if height and/or width of a renctangle is bigger than anInt, we change it with his log" logWidth := true. widthStone := anInt. widthScale := anOther. logHeight := true. heightStone := anInt. heightScale := anOther ! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:50'! logWidthIfMoreThan: anInt "if width of a renctangle is bigger than anInt, we change it with its log" logWidth := true. widthStone := anInt. widthScale := 5! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:50'! logWidthIfMoreThan: anInt scale: anOther "if width of a renctangle is bigger than anInt, we change it with its log" logWidth := true. widthStone := anInt. widthScale := anOther! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/29/2013 14:26'! nodesLinearResize: nodeElements |min max k | min := (nodeElements collect: [ :e | e width ]) min. max := (nodeElements collect: [ :e | e width ]) max. Transcript show: max; cr; show: min;cr;cr. (max * (1 - (scale / 100)) > min) ifTrue: [ k := max * (1 - (scale / 100)) - min / (max - min). nodeElements do: [ :e | e width: ( min + (k * ( e width - min))) ceiling ] ]. min := (nodeElements collect: [ :e | e width ]) min. max := (nodeElements collect: [ :e | e width ]) max. Transcript show: max; cr; show: min;cr;cr. min := (nodeElements collect: [ :e | e height ]) min. max := (nodeElements collect: [ :e | e height ]) max. (max * (1 - (scale / 100)) > min) ifTrue: [ k := max * (1 - (scale / 100)) - min / (max - min). nodeElements do: [ :e | e height: ( min + (k * ( e height - min))) ceiling ] ].! ! !RORectanglePackingLayout methodsFor: 'accessing' stamp: 'MathieuDehouck 5/28/2013 10:54'! padding: anInt "sets the number of white pixels between two rectangles" padding := anInt! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/23/2013 17:15'! place: nodes | bool i | i := 1. bool := true. [bool and: [ i <= nodes size ]] whileTrue: [ bool := self insert: (nodes at: i). i := i + 1. ]. ^ bool! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 11:14'! ratioWidth: anInt height: anOther "this is the desired ratio of the shape where are stored rectangles, and the number of pixel added to the shape when doing 'resize', but it may not be really respected, it will depends of the number and the size of the rectangles and of the padding " ratioWidth := anInt. ratioHeight := anOther! ! !RORectanglePackingLayout methodsFor: 'updating' stamp: 'MathieuDehouck 5/28/2013 11:17'! resize "when resizing the big container we also clear the matrix and so on" width := width + ratioWidth . height := height + ratioHeight . columns := OrderedCollection new. rows := OrderedCollection new. rows add: height. columns add: width. matrix := Matrix rows: 1 columns: 1. matrix at: 1 at: 1 put: true.! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/23/2013 16:14'! spaceFrom: r and: c | w h i j | w := 0. h := 0. i := c. j := r. [matrix at: j at: i ifInvalid: false ] whileTrue: [ w := (w + (columns at: i)). i := i + 1 ]. i := c. [matrix at: j at: i ifInvalid: false ] whileTrue: [ h := (h + (rows at: j)). j := j + 1 ]. ^ (w @ h)! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/23/2013 17:01'! updateMatrixWith: extent at: r and: c | new x y newC newR i j | x := extent x. y := extent y. i := r. j := c. newC := 1. newR := 1. [ x > 0 ] whileTrue: [ x := x - (columns at: j). x = 0 ifTrue: [ newC := 0 ]. j := j+1]. j := j-1. x := x + (columns at: j). [ y > 0 ] whileTrue: [ y := y - (rows at: i). y = 0 ifTrue: [ newR := 0 ]. i := i+1]. i := i-1. y := y + (rows at: i). new := Matrix rows: matrix rowCount + newR columns: matrix columnCount + newC. new atRows: 1 to: i columns: 1 to: j put: (matrix atRows: 1 to: i columns: 1 to: j ). new atRows: 1 to: i columns: j+newC to: new columnCount put: (matrix atRows: 1 to: i columns: j to: matrix columnCount ). new atRows: i+newR to: new rowCount columns: 1 to: j put: (matrix atRows: i to: matrix rowCount columns: 1 to: j ). new atRows: i+newR to: new rowCount columns: j+newC to: new columnCount put: (matrix atRows: i to: matrix rowCount columns: j to: matrix columnCount ). ( r to: i ) do: [ :e | (c to: j) do: [ :ea | new at: e at: ea put: false ] ]. newC = 1 ifTrue: [ columns add: (columns at: j) - x afterIndex: j. columns at: j put: x. ]. newR = 1 ifTrue: [ rows add: (rows at: i) - y afterIndex: i. rows at: i put: y. ]. matrix := new.! ! !RORectanglePackingLayout methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 5/28/2013 14:55'! widthLog: nodeElements nodeElements do: [ :e | e width > widthStone ifTrue: [ e width: (e width log * widthScale ) ceiling ]]! ! !ROScatterplotLayout commentStamp: '' prior: 34313642! A ROScatterplotLayout plots each element along a X-Y plan Instance Variables horizontalPadding: scaleFactorX: scaleFactorY: scaledToHeight: scaledToWidth: upSideDown: verticalPadding: xBlock: xOffset: yBlock: yOffset: horizontalPadding - xxxxx scaleFactorX - xxxxx scaleFactorY - xxxxx scaledToHeight - xxxxx scaledToWidth - xxxxx upSideDown - xxxxx verticalPadding - xxxxx xBlock - xxxxx xOffset - xxxxx yBlock - xxxxx yOffset - xxxxx ! !ROScatterplotLayout methodsFor: 'adjusting'! defaultAdjustHeightFor: childrenBounds and: myBounds | deltaY | deltaY := childrenBounds top - myBounds top. ^childrenBounds height + deltaY + self yOutGap! ! !ROScatterplotLayout methodsFor: 'adjusting'! defaultAdjustWidthFor: childrenBounds and: myBounds | deltaX | deltaX := childrenBounds left - myBounds left. ^childrenBounds width + deltaX + self xOutGap! ! !ROScatterplotLayout methodsFor: 'hook' stamp: 'AlexandreBergel 3/20/2013 09:14'! doExecute: elements | maxWidth maxHeight nodesToLayout x y origin newX newY | maxWidth := 0. maxHeight := 0. nodesToLayout := affectedNodes isNil ifTrue: [ elements ] ifFalse: [ affectedNodes ]. nodesToLayout do: [ :node | | m | m := node model isNil ifTrue: [ 0 ] ifFalse: [ node model ]. x := (xBlock value: m) * scaleFactorX. y := (yBlock value: m) * scaleFactorY. maxWidth := maxWidth max: x. maxHeight := maxHeight max: y. "x = #centered ifTrue: [ x := 0 ]." x := x + xOffset. y := upSideDown ifTrue: [ y - yOffset ] ifFalse: [ y + yOffset ]. translator translate: node to: x @ y ]. "We scale them to the width and height" elements do: [ :node | origin := node bounds origin. newX := origin x. newY := origin y. scaledToWidth isNil ifFalse: [ newX := (origin x / maxWidth * scaledToWidth) asInteger ]. scaledToHeight isNil ifFalse: [ newY := (origin y / maxHeight * scaledToHeight) asInteger ]. translator translate: node to: newX @ newY. self step ]. scaledToHeight isNil ifFalse: [ maxHeight := scaledToHeight ]. upSideDown ifFalse: [ ^ self ]. "We need to inverse the plots" nodesToLayout do: [ :node | y := node bounds origin y. node translateBy: 0 @ (maxHeight - (2 * y)) ]! ! !ROScatterplotLayout methodsFor: 'initialize-release'! initialize super initialize. horizontalPadding := 5. verticalPadding := 5. xOffset := 0. yOffset := 0. scaleFactorX := 1. scaleFactorY := 1. upSideDown := false. xBlock := yBlock := [:aNode | aNode ]! ! !ROScatterplotLayout methodsFor: 'accessing'! offset: anInt xOffset := anInt. yOffset := anInt.! ! !ROScatterplotLayout methodsFor: 'accessing'! outGap ^ self xOutGap @ self yOutGap! ! !ROScatterplotLayout methodsFor: 'accessing'! outGap: anObject self xOutGap: anObject. self yOutGap: anObject! ! !ROScatterplotLayout methodsFor: 'accessing'! scaleFactor: aValue scaleFactorX := aValue. scaleFactorY := aValue! ! !ROScatterplotLayout methodsFor: 'accessing'! scaleFactorX: aValue scaleFactorX := aValue.! ! !ROScatterplotLayout methodsFor: 'accessing'! scaleFactorY: aValue scaleFactorY := aValue.! ! !ROScatterplotLayout methodsFor: 'accessing'! scaledToHeight ^ scaledToHeight! ! !ROScatterplotLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 8/6/2013 08:13'! scaledToHeight: anInteger "Set the maximum width taken by the nodes" scaledToHeight := anInteger! ! !ROScatterplotLayout methodsFor: 'accessing'! scaledToWidth ^ scaledToWidth! ! !ROScatterplotLayout methodsFor: 'accessing' stamp: 'AlexandreBergel 8/6/2013 08:12'! scaledToWidth: anInteger "Set the maximum width taken by the nodes" scaledToWidth := anInteger! ! !ROScatterplotLayout methodsFor: 'accessing'! upSideDown upSideDown := upSideDown not! ! !ROScatterplotLayout methodsFor: 'accessing'! x: aBlock xBlock := aBlock! ! !ROScatterplotLayout methodsFor: 'accessing'! xOutGap ^horizontalPadding! ! !ROScatterplotLayout methodsFor: 'accessing'! xOutGap: anObject horizontalPadding := anObject! ! !ROScatterplotLayout methodsFor: 'accessing'! y: aBlock yBlock := aBlock! ! !ROScatterplotLayout methodsFor: 'accessing'! yOutGap ^verticalPadding! ! !ROScatterplotLayout methodsFor: 'accessing'! yOutGap: anObject verticalPadding := anObject! ! !ROTreeMapLayout commentStamp: '' prior: 34314280! A ROTreeMapLayout locates the element as a tree Instance Variables baseZIndex: canvas: inset: interactionBlock: leafBlock: minAreaPerNode: minInset: nodeBlock: rootNodes: splitPercentages: view: weightBlock: weightsCache: baseZIndex - xxxxx canvas - xxxxx inset - xxxxx interactionBlock - xxxxx leafBlock - xxxxx minAreaPerNode - xxxxx minInset - xxxxx nodeBlock - xxxxx rootNodes - xxxxx splitPercentages - xxxxx view - xxxxx weightBlock - xxxxx weightsCache - xxxxx ! !ROTreeMapLayout class methodsFor: 'instance creation' stamp: 'AlexandreBergel 8/21/2012 10:12'! withWeightBlock: aWeightBlock | layout | layout := self new. layout weightBlock: aWeightBlock. ^ layout.! ! !ROTreeMapLayout methodsFor: 'interaction' stamp: 'DennisSchenk 5/23/2012 09:48'! addInteraction: aNode "Adds interactions defined in interactionBlock to given node." interactionBlock notNil ifTrue: [ interactionBlock value: aNode. ].! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 7/3/2012 11:00'! addLeafBlock: aNode "Applies leaf block to given node." leafBlock notNil ifTrue: [ leafBlock value: aNode. ].! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 10/24/2012 16:33'! addNodeBlock: aNode "Applies node block to given node." nodeBlock notNil ifTrue: [ nodeBlock value: aNode. ].! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 2/12/2013 13:15'! baseZIndex ^ baseZIndex! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 2/12/2013 13:15'! baseZIndex: anObject baseZIndex := anObject! ! !ROTreeMapLayout methodsFor: 'utility' stamp: 'DennisSchenk 3/4/2013 12:07'! calculateWeight: firstHalf secondHalf: secondHalf | weight sumFirstHalf sumSecondHalf sum | "Initializing values" sumFirstHalf := 0. sumSecondHalf := 0. sum := 0. firstHalf do: [ :e | sumFirstHalf := sumFirstHalf + (self weightBlock value: e) ]. secondHalf do: [ :e | sumSecondHalf := sumSecondHalf + (self weightBlock value: e) ]. "Make sure its always at least one." sumFirstHalf < 1 ifTrue: [ sumFirstHalf := 1. ]. sumSecondHalf < 1 ifTrue: [ sumSecondHalf := 1. ]. sum := sumFirstHalf + sumSecondHalf. weight := sumFirstHalf / sum. "Should never be less or more than specified split percentages, so it looks okay graphically and nodes are not disapearing." weight > splitPercentages y ifTrue: [ weight := splitPercentages y. ]. weight < splitPercentages x ifTrue: [ weight := splitPercentages x. ]. ^ weight asFloat. ! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 6/5/2012 10:17'! childrenFor: aNode ^ aNode elements.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 3/5/2013 12:35'! childrenSortedFor: aNode "Returns all children of given node sorted by weight block." | children | "Sort children by layouts weight block." children isNil ifTrue: [ children := SortedCollection sortBlock: [ :e1 :e2 | | w1 w2 | w1 := self weights at: e1 ifAbsentPut: [self weightBlock value: e1]. w2 := self weights at: e2 ifAbsentPut: [self weightBlock value: e2]. w1 <= w2 ]. children addAll: (self childrenFor: aNode). ]. ^ children.! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'DennisSchenk 6/12/2012 11:18'! defaultBounds ^ Rectangle origin: 5@5 corner: 225@225.! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'DennisSchenk 9/11/2012 10:01'! defaultInset "This is the default value for insets we use for intetendation inside containment nodes to their children." ^ 5! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'DennisSchenk 6/13/2012 12:54'! defaultMinArea "We assume we need a 20x20 rectangle for a treemap at least." ^ 400! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'AlexandreBergel 8/29/2013 08:35'! defaultMinAreaPerNode "The smallest node we want to draw has a size of roughly 5x5." ^ 10! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'DennisSchenk 9/12/2012 10:38'! defaultMinInset "This is the default minimal value for insets in containment nodes we use." ^ 3! ! !ROTreeMapLayout methodsFor: 'default values' stamp: 'DennisSchenk 3/4/2013 12:15'! defaultSplitPercentages "These percentage say what the min (x) and max (y) percentage value are when splitting available drawing space. E.g A node has weight 0 and another weight 100, the visual weight gets capped to 0.01 and 0.99, so the small node is still visible." ^ 0.01@0.99! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 6/12/2012 09:43'! defineNodeShape: node rectangle: rectangle level: level "Sets a nodes shape and does other necessary stuff." node setBounds: rectangle. "Add specific interaction to node, if interactionBlock is set" self addInteraction: node.! ! !ROTreeMapLayout methodsFor: 'hook' stamp: 'DennisSchenk 9/4/2012 15:13'! doExecute: nodeCollection "Create the treemap layout." self layout: rootNodes rectangle: canvas level: 0.! ! !ROTreeMapLayout methodsFor: 'hook' stamp: 'AlexandreBergel 4/29/2013 16:39'! doInitialize: nodeCollection "Let's make sure that everything is set up correctly to draw a treemap layout." | givenBounds | "If there is nothing to draw, then we simply exit" (nodeCollection isEmpty) ifTrue: [ ^ self ]. "We remove the margin of nodeCollection to" self removeMarginFor: nodeCollection. "Can't draw a treemap without a weight definition." self assert: weightBlock notNil description: 'weightBlock has to be set!!'. super doInitialize: nodeCollection. "Getting the view we are in." view := nodeCollection first view. "Before we do anything else, we tell the nodes that they have a fixed size in a treemap." nodeCollection do: [ :node | node resizeStrategy: ROPermissiveParent instance. ]. "Setting up canvas we draw the treemap in based on given nodes." givenBounds := self prepareGraph: nodeCollection. self setupCanvas: givenBounds.! ! !ROTreeMapLayout methodsFor: 'hook' stamp: 'DennisSchenk 3/29/2013 08:40'! doPost: aNodeCollection "Doing things after the layout has been generated." aNodeCollection notEmpty ifTrue: [ "The treemap has to be draggable as a whole, so we forward drag events from all nodes except the rootNodes." rootNodes size > 1 ifTrue: [ aNodeCollection do: [ :node | node forward: ROMouseDragging ]. ] ifFalse: [ (aNodeCollection reject: [ :node | node = rootNodes first ]) do: [ :node | node forward: ROMouseDragging ]. ]. ]. "Releasing temporary vars" weightsCache := nil. super doPost: aNodeCollection.! ! !ROTreeMapLayout methodsFor: 'initialize-release' stamp: 'DennisSchenk 3/4/2013 12:05'! initialize super initialize. "Canvas is the Rectangle where we draw the treemap in." canvas := Rectangle origin: (5@5) corner: (150@150). "Inset is the indentation we use for containment nodes (to their children)." inset := self defaultInset. "This inset will never get smaller than the minimum though." minInset := self defaultMinInset. "This is the minimum area a node should have to be drawn." minAreaPerNode := self defaultMinAreaPerNode. "Where to cap split percentages as a point (x is min, y is max)" splitPercentages := self defaultSplitPercentages. "Base z-index is 0." baseZIndex := 0.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/11/2012 09:54'! inset ^ inset.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/11/2012 09:54'! inset: aNumber inset := aNumber.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! interactionBlock ^ interactionBlock.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! interactionBlock: aBlock "Sets an interaction block which will be set to every individual node." interactionBlock := aBlock.! ! !ROTreeMapLayout methodsFor: 'layouting' stamp: 'DennisSchenk 3/5/2013 09:47'! layout: nodes rectangle: rectangle level: level "Main method that lays out given nodes in given rectangle" "Nothing to draw..." (nodes isNil) ifTrue: [ ^ self. ]. "If we have only one node we can lay it out directly." nodes size == 1 ifTrue: [ self layoutNode: (nodes first) rectangle: rectangle level: level. ] "If we have more then one node, we need to split them up." ifFalse: [ "Make sure nodes are sorted by weight block." | sortedNodes | nodes class ~= SortedCollection ifTrue: [ sortedNodes := SortedCollection sortBlock: [ :e1 :e2 | (self weightBlock value: e1) <= (self weightBlock value: e2) ]. sortedNodes addAll: nodes. ] ifFalse: [ sortedNodes := nodes. ]. "Layout multiple nodes." self layoutNodes: sortedNodes rectangle: rectangle level: level. ].! ! !ROTreeMapLayout methodsFor: 'layouting' stamp: 'DennisSchenk 8/12/2013 16:01'! layoutNode: node rectangle: rectangle level: level "Lays out a single node" | children insetToUse innerRectangle | "Set bounds of the node." self defineNodeShape: node rectangle: rectangle level: level. "Set zIndex of node, depending on level." node zIndex: baseZIndex + level + 1. "Get children of given node." children := self childrenFor: node. "Layouting one node at a time..." self step. "Are we rendering a leaf node?" (children isNil or: children isEmpty) ifTrue: [ self styleLeafNode: node level: level. self addLeafBlock: node. ] "Else it is a containment node, style accordingly" ifFalse: [ "Style as containment node" self styleContainmentNode: node level: level. "Making insets a little bit thinner the more nested in the graph we are, but cap at min inset pixels." insetToUse := (inset - (level * 0.2)) ceiling . insetToUse < minInset ifTrue: [ insetToUse := minInset. ]. "Creating a containment border for the children." innerRectangle := rectangle insetBy: insetToUse. "In Roassal nested nodes are defined with relative bounds." innerRectangle := Rectangle origin: (insetToUse@insetToUse) extent: innerRectangle extent. "Need the children sorted if we draw them." children := self childrenSortedFor: node. "Layout children" self layout: children rectangle: innerRectangle level: level + 1. ]. "Apply node block last, to allow for overwriting of all standard stylings etc." self addNodeBlock: node.! ! !ROTreeMapLayout methodsFor: 'layouting' stamp: 'DennisSchenk 8/12/2013 16:00'! layoutNodes: nodes rectangle: rectangle level: level "Split up given nodes by weightBlock." | firstHalf secondHalf firstRectangle secondRectangle weight | "Split up nodes" firstHalf := self splitCollection: nodes. secondHalf := nodes copy reject: [ :element | firstHalf includes: element. ]. "Calculate weights of the halves" weight := self calculateWeight: firstHalf secondHalf: secondHalf. "Prepare and split up rectangles for the children..." firstRectangle := Rectangle new. secondRectangle := Rectangle new. "Either vertically or..." (rectangle width > rectangle height) ifTrue: [ self splitRectangleVertically: rectangle first: firstRectangle second: secondRectangle weight: weight. ] "....horizontally" ifFalse: [ self splitRectangleHorizontally: rectangle first: firstRectangle second: secondRectangle weight: weight. ]. "Recurse to draw nodes (if we have enough space)" firstRectangle area > minAreaPerNode ifTrue: [ self layout: firstHalf rectangle: firstRectangle level: level. "recurse..." ] ifFalse: [ firstHalf do: [ :n | n remove. ] "Remove these nodes from the view." ]. secondRectangle area > minAreaPerNode ifTrue: [ self layout: secondHalf rectangle: secondRectangle level: level. "recurse..." ] ifFalse: [ secondHalf do: [ :n | n remove. ] "Remove these nodes from the view." ].! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! leafBlock ^ leafBlock! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! leafBlock: aBlock "Sets the leaf block: it will be called on all leaf nodes, can be used to style them in a certain way." leafBlock := aBlock.! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 9/11/2012 11:53'! minAreaNeededFor: nodesChildren ^ (((minAreaPerNode * (nodesChildren size)) sqrt) + (2 * inset)) squared.! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 9/11/2012 11:52'! minAreaNeededForNode: node ^ (((minAreaPerNode * (node size)) sqrt) + (2 * inset)) squared.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/11/2012 10:16'! minAreaPerNode ^ minAreaPerNode.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/11/2012 10:16'! minAreaPerNode: aNumber minAreaPerNode := aNumber.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/12/2012 10:33'! minInset ^ minInset.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/12/2012 10:33'! minInset: aNumber minInset := aNumber.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 10/24/2012 16:33'! nodeBlock ^ nodeBlock! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 10/24/2012 16:33'! nodeBlock: aBlock "Sets the node block: it will be called on all node nodes, can be used to style them in a certain way." nodeBlock := aBlock.! ! !ROTreeMapLayout methodsFor: 'initialize-release' stamp: 'DennisSchenk 3/26/2013 17:01'! prepareGraph: nodeCollection "Checks if the given nodeColection and the (implicit contained) graph are in the expected format and tries to transform it automatically if not. Returns bounds that were given from the outside. TODO: The automatic transformation of graphs needs to be much more generic, so far we only capture single possible configurations..." | givenBounds | "In most cases we expect exactly one node, which is the root node." "Here we have more than one root node." nodeCollection size > 1 ifTrue: [ | edges parent roots | parent := nodeCollection first parent. edges := parent elements select: [ :e | e isEdge ]. "But if we have more than one node in the collection, maybe we got an edge driven definition of a graph. Let's try to transform it to a node-nested graph." (edges notEmpty) ifTrue: [ roots := ROGraphTransformation new fromEdgesToNesting: nodeCollection edges: edges. (roots isKindOf: Collection) ifFalse: [ roots := OrderedCollection with: roots. ]. parent class = ROElement ifTrue: [ parent removeAllElements. parent addAll: roots. "TODO: HACK HACK: this if-else is used to distinguish between setting size of shape externally of the treemap layout or on the nodes inside of it via an heuristic." roots first extent = (5@5) ifTrue: [ givenBounds := parent bounds insetBy: inset. ] ifFalse: [ givenBounds := roots first bounds. ] ]. parent class = ROView ifTrue: [ "Dont need edges anymore, all nodes are now nested." edges do: [ :edge | edge remove ]. givenBounds := nodeCollection first bounds ]. rootNodes := OrderedCollection withAll: roots. ] "If we have no edges, we have multiple root nodes (alone or with nested children)." ifFalse: [ rootNodes := nodeCollection. parent class = ROView ifTrue: [ givenBounds := rootNodes first bounds. ] ifFalse: [ givenBounds := parent bounds insetBy: inset. ] ]. ] "...as expected: only one root node." ifFalse: [ | edges nodes roots | rootNodes := nodeCollection. givenBounds := rootNodes first bounds. "TODO: HACK HACK: we have two seperate configurations here. If givenBounds of first rootNode are only 5@5, we can assume, that the bounds given from the outside, were actually given to its parent." givenBounds extent = (5@5) ifTrue: [ rootNodes first parent class ~= ROView ifTrue: [ givenBounds := rootNodes first parent bounds insetBy: inset. ]. ]. "Another possibility is that only the first level is nested, but then we have a graph driven defintion, so lets try to transform it to a nested graph." nodes := nodeCollection first elements. edges := nodeCollection first elements select: [ :e | e isEdge ]. (edges notEmpty) ifTrue: [ roots := (ROGraphTransformation new fromEdgesToNesting: nodes edges: edges) select: [ :e | e isNotEdge]. rootNodes first removeAllElements. rootNodes first addAll: roots. ]. ]. ^ givenBounds.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/23/2012 09:32'! recursiveChildrenFor: aNode "Returns all children, childrens children etc. of given node in a Set" | allChildren myChildren | allChildren := Set new. myChildren := Set new. myChildren addAll: (self childrenFor: aNode). allChildren addAll: myChildren. myChildren do: [ :each | allChildren addAll: (self recursiveChildrenFor: each) ]. ^ allChildren.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 9/11/2012 10:12'! recursiveChildrenSortedFor: aNode "Returns all children, childrens children etc. of given node in a SortedCollection sorted by weight block." | allChildren myChildren | allChildren := SortedCollection sortBlock: [ :e1 :e2 | (self weightBlock value: e1) <= (self weightBlock value: e2) ]. myChildren := Set new. myChildren addAll: (self childrenFor: aNode). allChildren addAll: myChildren. myChildren do: [ :each | allChildren addAll: (self recursiveChildrenFor: each) ]. ^ allChildren.! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'DennisSchenk 2/26/2013 16:22'! removeChildrenFromRendering: children "Recursive method that removes given children (and if applicable their grand children) from the view to render." (children notNil and: children notEmpty) ifTrue: [ children do: [ :child | view removeElementToRender: child. self removeChildrenFromRendering: child elements ]. ]. ! ! !ROTreeMapLayout methodsFor: 'utility' stamp: 'AlexandreBergel 4/29/2013 16:29'! removeMarginFor: elements "Assume that elements is not nil, and that all the elements have the same parent" elements do: [ :e | e allElementsDo: [ :ee | ee resizeStrategy: (e resizeStrategy paddingGap: 0) ] ] ! ! !ROTreeMapLayout methodsFor: 'initialize-release' stamp: 'DennisSchenk 9/19/2012 11:43'! setupCanvas: givenBounds "Setting up the dimensions and position of the canvas we draw the treemap on." "If bounds are specified from the outside (e.g. view shape width: 400; height: 400) we have to apply these bounds only to the canvas of the treemap, not all the nodes." "Leave some space to possible parent." canvas := Rectangle origin: (inset@inset) extent: givenBounds extent. ! ! !ROTreeMapLayout methodsFor: 'utility' stamp: 'DennisSchenk 7/3/2012 11:01'! splitCollection: aSortedCollection "Returns the first half of a SortedCollection" "TODO: this does not belong here and can surely be solved more elegant." | indexOfSplitElement n firstHalf | indexOfSplitElement := (aSortedCollection size / 2) floor. n := 1. firstHalf := SortedCollection sortBlock: aSortedCollection sortBlock. [ n <= indexOfSplitElement ] whileTrue: [ | element | element := aSortedCollection at: n. firstHalf add: element. n := n+1. ]. ^ firstHalf.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 3/4/2013 12:05'! splitPercentages ^ splitPercentages! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 3/4/2013 12:05'! splitPercentages: aPoint splitPercentages := aPoint.! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'AlexandreBergel 8/27/2012 09:57'! splitRectangleHorizontally: rectangle first: firstRectangle second: secondRectangle weight: weight "Splits given rectangle to given rectangles by given weight on the y axis" | y | "This is where we are going to split on the y-axis" y := ((((rectangle bottomLeft y) - (rectangle topLeft y)) * weight) floor + rectangle topLeft y). "HACKY: Subtract 1 of the seconds rectangles origin y value, so the borders between the rectangles are overlaying eachother, so we dont have thick borders" firstRectangle roOrigin: (rectangle origin); roCorner: (rectangle corner x)@y. secondRectangle roOrigin: (rectangle origin x)@(y-1); roCorner: (rectangle corner). ! ! !ROTreeMapLayout methodsFor: 'layouting-utility' stamp: 'AlexandreBergel 8/27/2012 09:58'! splitRectangleVertically: rectangle first: firstRectangle second: secondRectangle weight: weight "Splits given rectangle to given rectangles by given weight on the x axis" | x | "This is where we are going to split on the x-axis" x := ((((rectangle topRight x) - (rectangle topLeft x)) * weight) floor + rectangle topLeft x). "HACKY: Subtract 1 of the seconds rectangles origin x value, so the borders between the rectangles are overlaying eachother, so we dont have thick borders" firstRectangle roOrigin: (rectangle origin); roCorner: x@(rectangle corner y). secondRectangle roOrigin: (x-1)@(rectangle origin y); roCorner: (rectangle corner). ! ! !ROTreeMapLayout methodsFor: 'styling' stamp: 'DennisSchenk 9/12/2012 10:41'! styleContainmentNode: node level: level | shape | shape := (node getShape: ROBox). shape color: ((Color r: 0.934 g: 0.934 b: 0.934) adjustBrightness: -0.03 * level). shape borderColor: ((Color r: 0.2 g: 0.2 b: 0.2) adjustBrightness: -0.008 * level). ! ! !ROTreeMapLayout methodsFor: 'styling' stamp: 'DennisSchenk 9/12/2012 10:42'! styleContainmentNodeWithOmittedChildren: node level: level | shape | shape := (node getShape: ROBox). shape color: ((Color r: 0.884 g: 0.884 b: 0.884) adjustBrightness: -0.03 * level). shape borderColor: ((Color r: 0.2 g: 0.2 b: 0.2) adjustBrightness: -0.008 * level). ! ! !ROTreeMapLayout methodsFor: 'styling' stamp: 'DennisSchenk 4/9/2013 08:59'! styleLeafNode: node level: level | shape | shape := node getShape: ROBox. shape color: Color white. shape borderColor: Color gray.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! weightBlock ^ weightBlock ! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 5/22/2012 09:24'! weightBlock: aWeightBlock weightBlock := aWeightBlock.! ! !ROTreeMapLayout methodsFor: 'accessing' stamp: 'DennisSchenk 7/25/2012 11:12'! weightFor: aNode "Returns weight for given node based on weightBlock" self assert: weightBlock notNil description: 'weightBlock has to be set!!'. ^ weightBlock value: aNode.! ! !ROTreeMapLayout methodsFor: 'caching' stamp: 'DennisSchenk 3/5/2013 09:53'! weights weightsCache isNil ifTrue: [ weightsCache := Dictionary new. ]. ^ weightsCache .! ! !ROLayoutTranslator commentStamp: 'AlexandreBergel 11/28/2011 10:48' prior: 34314999! ROLayoutTranslator is used by the layout to translate object. Each layout can be parametrized with a translator to produce a visual effect. I am an abstract class! !ROAbsorbLayoutTranslator methodsFor: 'hook'! translate: element to: newPosition "Does not perform the translation. Used in testing essentially"! ! !RODirectLayoutTranslator class methodsFor: 'testing'! isDefault ^ true! ! !RODirectLayoutTranslator methodsFor: 'hook'! translate: element to: newPosition element translateTo: newPosition! ! !ROLayoutTranslator class methodsFor: 'accessing'! default "Return the default translator, the one used in the layouts" defaultTranslator ifNotNil: [ ^ defaultTranslator ]. ^ defaultTranslator := self defaultClass new! ! !ROLayoutTranslator class methodsFor: 'accessing'! defaultClass ^ self withAllSubclasses detect: #isDefault! ! !ROLayoutTranslator class methodsFor: 'testing'! isDefault ^ false! ! !ROLayoutTranslator methodsFor: 'hook' stamp: 'AlexandreBergel 5/27/2013 14:35'! nbCycles: anInteger "Do nothing"! ! !ROLayoutTranslator methodsFor: 'hook'! translate: element to: newPosition self subclassResponsibility ! ! !ROSmoothLayoutTranslator methodsFor: 'testing'! hasCompleted "Return true if all the translation has completed" ^ move hasCompleted! ! !ROSmoothLayoutTranslator methodsFor: 'initialize-release' stamp: 'AlexandreBergel 4/13/2013 22:10'! initialize super initialize. "The amount of view refresh we need to complete the transition" nbCycles := 180! ! !ROSmoothLayoutTranslator methodsFor: 'accessing' stamp: 'AlexandreBergel 4/13/2013 22:10'! nbCycles: anInteger "Set the number of cycle we need to complete the transition" nbCycles := anInteger ! ! !ROSmoothLayoutTranslator methodsFor: 'hook' stamp: 'AlexandreBergel 4/13/2013 22:10'! translate: element to: newPosition move := ROLinearMove new nbCycles: nbCycles; for: element to: newPosition! ! !ROAbstractArrow methodsFor: 'drawing' stamp: 'AlexandreBergel 11/1/2012 12:09'! drawOn: aCanvas for: anEdge fromPoint: fromPoint toPoint: toPoint line: line "Draw the arrow on the canvas and return the begining and ending of the arrow" | vector u unit arrowMiddle arrowLeft arrowRight w c toPointWithOffset r | "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. toPointWithOffset := toPoint - (offset * (vector r - size) * unit). arrowMiddle := toPointWithOffset - (unit * size). arrowLeft := arrowMiddle- (u * size). arrowRight := arrowMiddle + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: toPointWithOffset to: arrowLeft width: w color: c. aCanvas line: arrowLeft to: arrowRight width: w color: c. aCanvas line: arrowRight to: toPointWithOffset width: w color: c. ^ Array with: toPointWithOffset with: arrowMiddle! ! !ROAbstractArrow methodsFor: 'drawing' stamp: 'AlexandreBergel 11/1/2012 12:09'! drawOn: aCanvas for: anEdge line: line "Draw the arrow on the canvas and return the begining and ending of the arrow" ^ self drawOn: aCanvas for: anEdge fromPoint: (line startingPointOf: anEdge) toPoint: (line endingPointOf: anEdge) line: line! ! !ROArrow commentStamp: '' prior: 34315212! A ROArrow represent an arrow. A ROLine may receive arrows. Instance Variables color: offset: size: color - Color of the arrow offset - float that represent where to put the arrow on a line size - size of the arrow ! !ROArrow methodsFor: 'hooks' stamp: 'AlexandreBergel 7/29/2012 21:18'! getDirectionVectorFrom: fromPoint to: toPoint ^ toPoint - fromPoint! ! !ROReversedArrow methodsFor: 'drawing' stamp: 'AlexandreBergel 7/29/2012 22:48'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector u unit arrowMiddle arrowLeft arrowRight w c toPointWithOffset r | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. toPointWithOffset := toPoint - (offset * (vector r - size) * unit). arrowMiddle := toPointWithOffset - (unit * size). arrowLeft := toPointWithOffset - (u * size). arrowRight := toPointWithOffset + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: arrowMiddle to: arrowLeft width: w color: c. aCanvas line: arrowLeft to: arrowRight width: w color: c. aCanvas line: arrowRight to: arrowMiddle width: w color: c. ^ Array with: toPointWithOffset with: arrowMiddle! ! !ROHorizontalArrow methodsFor: 'drawing' stamp: 'BenComan 8/5/2012 20:33'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector u unit arrowMiddle arrowTop arrowBottom w c toPointWithOffset r | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. " toPointWithOffset := toPoint - (offset * (vector r - size) * unit)." (offset = 0) ifTrue: [ toPointWithOffset := toPoint - (offset * (vector r - size) * unit) ] ifFalse: [ toPointWithOffset := fromPoint + (unit * (size @ 0)) ]. arrowMiddle := toPointWithOffset - (unit * size). arrowTop := arrowMiddle - (u * size). arrowBottom := arrowMiddle + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: toPointWithOffset to: arrowTop width: w color: c. aCanvas line: arrowTop to: arrowBottom width: w color: c. aCanvas line: arrowBottom to: toPointWithOffset width: w color: c. ^ Array with: toPointWithOffset with: arrowMiddle! ! !ROHorizontalArrow methodsFor: 'hooks' stamp: 'BenComan 8/5/2012 14:52'! getDirectionVectorFrom: fromPoint to: toPoint ^ (toPoint - fromPoint) x @ 0! ! !ROReversedHorizontalArrow methodsFor: 'drawing' stamp: 'BenComan 8/5/2012 20:31'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector u unit arrowMiddle arrowTop arrowBottom w c toPointWithOffset r | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. (offset = 0) ifTrue: [ toPointWithOffset := toPoint - (offset * (vector r - size) * unit) ] ifFalse: [ toPointWithOffset := fromPoint + (unit * (size @ 0)) ]. arrowMiddle := toPointWithOffset - (unit * size). arrowTop := toPointWithOffset - (u * size). arrowBottom := toPointWithOffset + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: arrowMiddle to: arrowTop width: w color: c. aCanvas line: arrowTop to: arrowBottom width: w color: c. aCanvas line: arrowBottom to: arrowMiddle width: w color: c. ^ Array with: (fromPoint + (unit * (size @ 0))) with: (toPoint - (unit * (size @ 0)))! ! !ROReversedVerticalArrow methodsFor: 'drawing' stamp: 'AlexandreBergel 7/29/2012 23:58'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector u unit arrowMiddle arrowLeft arrowRight w c toPointWithOffset r | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. (offset = 0) ifTrue: [ toPointWithOffset := toPoint - (offset * (vector r - size) * unit) ] ifFalse: [ toPointWithOffset := fromPoint + (unit * (0 @ size)) ]. arrowMiddle := toPointWithOffset - (unit * size). arrowLeft := toPointWithOffset - (u * size). arrowRight := toPointWithOffset + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: arrowMiddle to: arrowLeft width: w color: c. aCanvas line: arrowLeft to: arrowRight width: w color: c. aCanvas line: arrowRight to: arrowMiddle width: w color: c. ^ Array with: (fromPoint + (unit * (0 @ size))) with: (toPoint - (unit * (0 @ size)))! ! !ROVerticalArrow methodsFor: 'drawing' stamp: 'AlexandreBergel 7/29/2012 23:47'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector u unit arrowMiddle arrowLeft arrowRight w c toPointWithOffset r | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. u := vector normal. unit := vector / r. " toPointWithOffset := toPoint - (offset * (vector r - size) * unit)." (offset = 0) ifTrue: [ toPointWithOffset := toPoint - (offset * (vector r - size) * unit) ] ifFalse: [ toPointWithOffset := fromPoint + (unit * (0 @ size)) ]. arrowMiddle := toPointWithOffset - (unit * size). arrowLeft := arrowMiddle- (u * size). arrowRight := arrowMiddle + (u * size). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: toPointWithOffset to: arrowLeft width: w color: c. aCanvas line: arrowLeft to: arrowRight width: w color: c. aCanvas line: arrowRight to: toPointWithOffset width: w color: c. ^ Array with: toPointWithOffset with: arrowMiddle! ! !ROVerticalArrow methodsFor: 'accessing' stamp: 'AlexandreBergel 7/29/2012 21:19'! getDirectionVectorFrom: fromPoint to: toPoint ^ 0 @ (toPoint - fromPoint) y! ! !RODiamondDecoration methodsFor: 'drawing' stamp: 'BenComan 10/20/2012 21:32'! drawOn: aCanvas for: anEdge line: line "Return the begining and ending of the arrow" | fromPoint toPoint vector normal unit endPoint leftPoint rightPoint w c toPointWithOffset r middlePoint | fromPoint := line startingPointOf: anEdge. toPoint := line endingPointOf: anEdge. "Draw head" vector := self getDirectionVectorFrom: fromPoint to: toPoint. r := vector r. r = 0 ifTrue: [ ^ Array with: fromPoint with: fromPoint ]. normal := vector normal. unit := vector / r. toPointWithOffset := toPoint - (offset * (vector r - size) * unit). endPoint := toPointWithOffset - (unit * size). middlePoint := toPointWithOffset + (unit * size). leftPoint := toPointWithOffset - (normal * size * 0.7 ). rightPoint := toPointWithOffset + (normal * size * 0.7). w := line width roValue: anEdge. c := line colorFor: anEdge. aCanvas line: endPoint to: leftPoint width: w color: c. aCanvas line: leftPoint to: middlePoint width: w color: c. aCanvas line: middlePoint to: rightPoint width: w color: c. aCanvas line: rightPoint to: endPoint width: w color: c. ^ Array with: middlePoint with: endPoint! ! !RODiamondDecoration methodsFor: 'hooks' stamp: 'AlexandreBergel 11/1/2012 12:06'! getDirectionVectorFrom: fromPoint to: toPoint ^ toPoint - fromPoint! ! !ROLineDecoration methodsFor: 'configuration' stamp: 'DennisSchenk 9/18/2012 10:20'! defaultSize ^ 10! ! !ROLineDecoration methodsFor: 'drawing' stamp: 'AlexandreBergel 11/1/2012 12:09'! drawOn: aCanvas for: anEdge line: line "Draw the decorator on the canvas and return the begining and ending of the decoration" self subclassResponsibility. ! ! !ROLineDecoration methodsFor: 'hooks' stamp: 'AlexandreBergel 7/29/2012 21:26'! getDirectionVectorFrom: fromPoint to: toPoint self subclassResponsibility! ! !ROLineDecoration methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/29/2012 21:25'! initialize super initialize. offset := 0. size := self defaultSize! ! !ROLineDecoration methodsFor: 'accessing' stamp: 'AlexandreBergel 7/29/2012 21:25'! offset ^ offset! ! !ROLineDecoration methodsFor: 'accessing' stamp: 'AlexandreBergel 7/29/2012 21:25'! offset: aFloat offset := aFloat! ! !ROLineDecoration methodsFor: 'accessing' stamp: 'AlexandreBergel 11/1/2012 12:10'! size "Return the size of the decoration" ^ size! ! !ROLineDecoration methodsFor: 'accessing' stamp: 'AlexandreBergel 11/1/2012 12:10'! size: anInteger "Set the size of the decoration. DefaultSize return the default size" size := anInteger! ! !ROMondrianFrame commentStamp: '' prior: 34315524! The Mondrian specific language structures a visualization as a tree (using nodes:forEach:). A ROMondrianFrame is an element of this tree. A frame correspond to what has to be pushed and popup. It also contains funcionalities to lookup nodes. Instance Variables children: elements: interactions: layout: parent: shape: view: children - the list of children frames elements - elements (nodes and edges) that are defined in the frame interactions - xxxxx layout - xxxxx parent - xxxxx shape - xxxxx view - xxxxx ! !ROMondrianFrame class methodsFor: 'public' stamp: 'AlexandreBergel 5/25/2013 18:39'! newFrom: aViewBuilder "Create a mondrian frame from the mondrian view builder" | rawView instance | rawView := aViewBuilder raw. instance := self new. instance view: rawView. instance shape: aViewBuilder getShape. instance interactionBuilder: aViewBuilder interaction. ^ instance! ! !ROMondrianFrame methodsFor: 'adding' stamp: 'AlexandreBergel 7/24/2012 17:57'! addChild: aFrame children add: aFrame! ! !ROMondrianFrame methodsFor: 'adding' stamp: 'AlexandreBergel 7/25/2012 11:03'! addEdge: edge "we need to add the edge in the frame that includes both the from and to" | frameTo frameFrom | frameTo := self frameOfElement: edge to. frameFrom := self frameOfElement: edge from. (frameTo == frameFrom) ifTrue: [ frameFrom addElement: edge ] ifFalse: [ "This looks like to be a weir case" self addElement: edge ]! ! !ROMondrianFrame methodsFor: 'adding' stamp: 'AlexandreBergel 7/25/2012 11:17'! addElement: element "self haltIf: [ element class == ROEdge ]." elements add: element! ! !ROMondrianFrame methodsFor: 'adding' stamp: 'AlexandreBergel 7/25/2012 11:03'! addElements: elementss elementss do: [:e | self addElement: e] ! ! !ROMondrianFrame methodsFor: 'actions' stamp: 'VanessaPena 4/12/2013 10:42'! applyLayout children do: [ :frameChild | frameChild applyLayout ]. layout on: self nodes edges: self edges.! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/25/2012 09:46'! children ^ children copy! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'DR 3/27/2013 16:46'! edges ^ (elements select: [ :el | el isEdge ]) asArray! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/25/2012 09:48'! elements ^ elements copy asArray! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/25/2012 11:16'! frameOfElement: element "Return the frame that contains element. In case several frames contains the same element, the result is unspecified" ^ self frameOfElement: element ifFound: [ :foundFrame | ^ foundFrame ]! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/25/2012 11:15'! frameOfElement: element ifFound: aBlock "aBlock takes an argument, the frame just found" "Return the frame that contains element. In case several frames contains the same element, the result is unspecified" (elements includes: element) ifTrue: [ ^ aBlock value: self ]. children do: [ :childFrame | childFrame frameOfElement: element ifFound: aBlock. ]. ! ! !ROMondrianFrame methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/24/2012 17:46'! initialize super initialize. elements := OrderedCollection new. children := OrderedCollection new.! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 5/25/2013 18:15'! interactionBuilder ^ interactionBuilder! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 5/25/2013 18:15'! interactionBuilder: anObject interactionBuilder := anObject! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:05'! layout ^ layout! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:05'! layout: aLayoutClass layout := aLayoutClass ! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/25/2012 09:59'! nodes ^ (elements select: [ :el | el class ~~ ROEdge ]) asArray ! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/25/2012 09:45'! numberOfChildren ^ children size! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/24/2012 17:33'! numberOfElements ^ elements size! ! !ROMondrianFrame methodsFor: 'accessing-computed' stamp: 'AlexandreBergel 7/24/2012 17:47'! numberOfFrames ^ children inject: 1 into: [ :s :e | s + e numberOfFrames ]! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:43'! parent ^ parent! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:43'! parent: aFrame parent := aFrame! ! !ROMondrianFrame methodsFor: 'printing' stamp: 'AlexandreBergel 7/25/2012 09:30'! printOn: stream super printOn: stream. self parent == self ifTrue: [ stream nextPutAll: '' ] ! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 11:45'! removeChild: aFrame children remove: aFrame ifAbsent: [ ]! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 12:27'! removeEdge: edge self removeEdges: (Array with: edge)! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 12:29'! removeEdges: objects elements removeAllFoundIn: objects! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 11:45'! removeElement: element |frame| element elements do:[:el | frame := (self frameOfElement: el). frame removeElement: el. frame removeFromParent. ]. elements remove: element ifAbsent: [ ]! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 12:29'! removeElements: objects objects do:[:ob | self removeElement: ob ]. ! ! !ROMondrianFrame methodsFor: 'removing' stamp: 'VanessaPena 4/12/2013 11:44'! removeFromParent parent removeChild: self.! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:05'! shape ^ shape ! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:05'! shape: aShape shape := aShape! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:04'! view ^ view! ! !ROMondrianFrame methodsFor: 'accessing' stamp: 'AlexandreBergel 7/24/2012 17:04'! view: aView view := aView! ! !ROMondrianInteractionBuilder commentStamp: '' prior: 34316212! A ROMondrianInteractionBuilder is a builder for interaction. Instance Variables selfDefinedInteraction: shouldHavePopup: viewBuilder: selfDefinedInteraction - xxxxx shouldHavePopup - xxxxx viewBuilder - xxxxx ! !ROMondrianInteractionBuilder class methodsFor: 'create Instance' stamp: 'AlexandreBergel 5/25/2013 11:22'! initializeOn: aViewBuilder ^self new viewBuilder: aViewBuilder.! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:25'! action: aBlockOrSymbol ^ self item: aBlockOrSymbol printString action: aBlockOrSymbol! ! !ROMondrianInteractionBuilder methodsFor: 'public' stamp: 'AlexandreBergel 5/25/2013 17:50'! applyToElement: element self applyToElements: (Array with: element)! ! !ROMondrianInteractionBuilder methodsFor: 'public' stamp: 'AlexandreBergel 5/25/2013 17:47'! applyToElements: elements selfDefinedInteraction do: [:int | int value: elements ].! ! !ROMondrianInteractionBuilder methodsFor: 'status bar' stamp: 'AlexandreBergel 9/15/2013 00:43'! createStatusBarIfNecessary | statusBar labelShape | (viewBuilder stack hasAttribute: #statusBar) ifTrue: [^ viewBuilder stack attributeAt: #statusBar]. statusBar := ROElement new + (labelShape := ROLabel text: ' ') + ROBox white. viewBuilder stack add: statusBar. ROConstraint stickToBottomLeft: statusBar. viewBuilder stack attributeAt: #statusBar put: statusBar. labelShape text: ''. ^ statusBar ! ! !ROMondrianInteractionBuilder methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/25/2013 17:55'! dynamicEdgeFromAll: aBlockOrSymbol using: aShape selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :n | n @ (RODynamicEdge fromAll: [ :element | (viewBuilder elementsFromModels: (aBlockOrSymbol roValue: element model)) ] using: aShape) ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/25/2013 17:55'! dynamicEdgeToAll: aBlockOrSymbol using: aShape selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :n | n @ (RODynamicEdge toAll: [ :element | (viewBuilder elementsFromModels: (aBlockOrSymbol roValue: element model)) ] using: aShape) ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'dynamic edges' stamp: 'AlexandreBergel 5/25/2013 17:55'! dynamicEdgeToAll: aBlockOrSymbol usingFading: aShape selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :n | n @ (RODynamicFadingEdge toAll: [ :element | | allElements | allElements := (viewBuilder elementsFromModels: (aBlockOrSymbol roValue: element model)). ROWiggle onAll: allElements. allElements ] using: aShape) ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:25'! forward self forwarder! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:25'! forward: event selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | node forward: event ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! forwarder selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | node forward ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'updating' stamp: 'AlexandreBergel 5/25/2013 11:27'! highlightNodesWhenOver: aBlockOrSymbol self highlightNodesWhenOver: aBlockOrSymbol color: Color red! ! !ROMondrianInteractionBuilder methodsFor: 'updating' stamp: 'AlexandreBergel 8/27/2013 21:39'! highlightNodesWhenOver: aBlockOrSymbol color: aColorAsBlockOrSymbol self on: ROMouseEnter do: [ :n | | nodes | nodes := (aBlockOrSymbol roValue: n element) . ROBlink highlightElements: nodes color: (aColorAsBlockOrSymbol roValue: n element model). n element signalUpdate ]. self on: ROMouseLeave do: [ :n | | nodes | nodes := (aBlockOrSymbol roValue: n element). ROBlink unhighlightElements: nodes. n element signalUpdate ].! ! !ROMondrianInteractionBuilder methodsFor: 'updating' stamp: 'AlexandreBergel 5/25/2013 11:28'! highlightWhenOver: aBlockOrSymbol "(aBlockOrSymbol roValue: element) should return a collection of the models that should be highlighted" self highlightWhenOver: aBlockOrSymbol color: Color red! ! !ROMondrianInteractionBuilder methodsFor: 'updating' stamp: 'AlexandreBergel 5/25/2013 17:57'! highlightWhenOver: aBlockOrSymbol color: aColorAsBlockOrSymbol "We use 'nodes asSet' to make sure that we do not go twice over the same node, else it behaves strangely'" self on: ROMouseEnter do: [ :n | | nodes | nodes := viewBuilder elementsFromModels: (aBlockOrSymbol roValue: n element model) . ROBlink highlightElements: nodes asSet color: (aColorAsBlockOrSymbol roValue: n element model) ]. self on: ROMouseLeave do: [ :n | | nodes | nodes := viewBuilder elementsFromModels: (aBlockOrSymbol roValue: n element model). ROBlink unhighlightElements: nodes asSet ].! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! if: conditionBlock popupText: popupTextBlock "If conditionBlock is evaluated at true, then popupTextBlock is used to for the popup" ^ self popupView: [ :entity :myView | (conditionBlock roValue: entity) ifTrue: [ myView shape rectangle. myView node: entity forIt: [ myView shape label. myView node: (popupTextBlock roValue: entity) ] ] ] " selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | | oldBlockOrValue | oldBlockOrValue := (node is: ROPopupView) ifTrue: [ node getInteraction: ROPopupView ] ifFalse: [ #printString ]. self popupText: [ :each | (conditionBlock roValue: each) ifTrue: [ popupTextBlock roValue: each ] ifFalse: [ oldBlockOrValue roValue: each ] ] ] ] "! ! !ROMondrianInteractionBuilder methodsFor: 'initialize-release' stamp: 'AlexandreBergel 5/25/2013 17:46'! initialize super initialize. selfDefinedInteraction := OrderedCollection new.! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:25'! item: titleAsString action: aBlockOrSymbol "aBlockOrSymbol accepts an object model, and not the element " selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :n | n @ (ROMenuActivable new item: titleAsString action: [ :element | aBlockOrSymbol roValue: element model ]) ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:24'! noPopup selfDefinedInteraction add: [ :listOfElements | listOfElements do: [ :element | element removeInteraction: ROAbstractPopup ] ].! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 17:57'! nodraggable selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | node removeInteraction: RODraggable ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 5/25/2013 17:58'! numberOfDefinedInteractions "Used essentially for debugging purpose" ^ selfDefinedInteraction size! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! on: event do: block selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | node on: event do: block ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! popupText ^ self popupText: [ :v | (v class == 'ab' class) ifTrue: [ v ] ifFalse: [ v printString ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! popupText: aBlockOrSelector ^ self popupView: [ :entity :myView | myView shape rectangle. myView node: entity forIt: [ myView shape label. myView node: (aBlockOrSelector roValue: entity) ] ] " selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | | int | int := ROPopup text: aBlockOrSelector. int receivingView: stack. int textColor: Color black. node changeInteraction: ROAbstractPopup for: int. ] ] " ! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:26'! popupView: aTwoArgsBlock "aTwoArgsBlock is in the form [ :entity :myView | ... ]" ^ self popupView: aTwoArgsBlock delay: 100 ! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 17:55'! popupView: aTwoArgsBlock delay: delayAsInteger "aTwoArgsBlock is in the form [ :entity :myView | ... ]" selfDefinedInteraction add: [ :listOfElements | listOfElements do: [ :element | element changeInteraction: ROAbstractPopup for: (ROPopupView new receivingView: viewBuilder stack; view: [ :entity | | v | v := viewBuilder class new. aTwoArgsBlock value: entity model value: v. v applyLayout. v ] ) ] ]! ! !ROMondrianInteractionBuilder methodsFor: 'status bar' stamp: 'AlexandreBergel 5/31/2013 13:49'! statusBar ^ self statusBar: #yourself ! ! !ROMondrianInteractionBuilder methodsFor: 'status bar' stamp: 'AlexandreBergel 6/12/2013 11:43'! statusBar: aOneArgBlockOrSymbol "Display a status bar when the mouse enter an element" | statusBar | statusBar := self createStatusBarIfNecessary. selfDefinedInteraction add: [ :listOfNodes | listOfNodes do: [ :node | node on: ROMouseEnter do: [ :event | (statusBar getShape: ROLabel) text: (aOneArgBlockOrSymbol roValue: event model) printString ] ] ]. ^ statusBar ! ! !ROMondrianInteractionBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 5/25/2013 11:29'! viewBuilder: aViewBuilder viewBuilder := aViewBuilder.! ! !ROMondrianInteractionBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:27'! withPopup shouldHavePopup := true! ! !ROMondrianShapeBuilder commentStamp: '' prior: 34316526! A ROMondrianShapeBuilder is a convenient way to build shapes. Instance Variables color: shape: viewBuilder: color - xxxxx shape - xxxxx viewBuilder - xxxxx ! !ROMondrianShapeBuilder class methodsFor: 'createInstance' stamp: 'AlejandroInfante 4/15/2013 15:17'! initializeOn: aViewBuilder ^self new viewBuilder: aViewBuilder.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! arrowedLine self arrowedLineWithOffset: 0! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! arrowedLineReversed self arrowedLineReversedWithOffset: 1.0! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! arrowedLineReversedWithOffset: aFloat self setShape: ROLine new. self getShape add: (ROReversedArrow new offset: aFloat). self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! arrowedLineWithOffset: aFloat self setShape: ROLine new. self getShape add: (ROArrow new offset: aFloat). self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 21:48'! attachPoint: aROHorizontalAttachPoint self getShape attachPoint: aROHorizontalAttachPoint! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! bezierLine self setShape: RORadialBezierCurve new. self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - private' stamp: 'AlejandroInfante 4/15/2013 14:22'! borderColor ^ self getShape borderColor! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlejandroInfante 4/15/2013 14:22'! borderColor: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a symbol or a one-arg block" self getShape borderColor: [ :element | aBlockOrSymbol roValue: element model ] ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:22'! borderWidth: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a symbol or a one-arg block" self getShape borderWidth: [ :element | aBlockOrSymbol roValue: element model ] ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'JurajKubelka 4/26/2013 10:50'! centeredLabel self setShape: self newCenteredLabel.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'AlejandroInfante 4/15/2013 14:22'! circle self setShape: ROEllipse new. self color: self defaultNodeColor. self getShape borderWidth: 1. ! ! !ROMondrianShapeBuilder methodsFor: 'accessors' stamp: 'AlejandroInfante 4/15/2013 14:37'! color ^color.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlejandroInfante 4/15/2013 14:22'! color: aBlockOrSymbol color := aBlockOrSymbol. self getShape color: [ :element | aBlockOrSymbol roValue: element model ] ! ! !ROMondrianShapeBuilder methodsFor: 'configuration' stamp: 'AlejandroInfante 4/15/2013 14:26'! defaultColor ^ Color veryLightGray.! ! !ROMondrianShapeBuilder methodsFor: 'configuration' stamp: 'AlejandroInfante 4/15/2013 14:26'! defaultLineColor ^ Color veryLightGray.! ! !ROMondrianShapeBuilder methodsFor: 'configuration' stamp: 'AlejandroInfante 4/15/2013 14:25'! defaultNodeColor ^ Color white! ! !ROMondrianShapeBuilder methodsFor: 'configuration' stamp: 'AlejandroInfante 4/15/2013 14:26'! defaultTextColor ^ Color black.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'JurajKubelka 6/3/2013 15:23'! ellipse self circle! ! !ROMondrianShapeBuilder methodsFor: 'shapes - private' stamp: 'AlejandroInfante 4/15/2013 14:22'! fillColor ^ self getShape color! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlejandroInfante 4/15/2013 14:22'! fillColor: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a symbol or a one-arg block" self getShape color: [ :element | aBlockOrSymbol roValue: element model ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 15:21'! fixedSize self viewBuilder fixedSize.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'JurajKubelka 6/3/2013 14:59'! fontColor: aBlockOrASymbolAnOrObject self getLabelShape color: [ :element | aBlockOrASymbolAnOrObject roValue: element model ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'JurajKubelka 5/30/2013 01:04'! fontSize: aBlockOrASymbolOrAnObject self getLabelShape fontSize: [:element | aBlockOrASymbolOrAnObject roValue: element model]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - private' stamp: 'JurajKubelka 5/30/2013 01:03'! getLabelShape "private" ^ self getShape shapeDetect: [ :s | s isKindOf: ROAbstractLabel ]! ! !ROMondrianShapeBuilder methodsFor: 'accessors' stamp: 'AlejandroInfante 4/15/2013 13:50'! getShape ^shape! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:22'! height: aHeightBlock self getShape height: [ :elem | aHeightBlock roValue: elem model ] ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlexandreBergel 8/27/2013 21:42'! if: conditionBlock borderColor: colorBlock "If conditionBlock is evaluated at true, then colorBlock is used to pick the color to use. Both conditionBlock and colorBlock are evaluated with the model value of the node." | oldBlockOrValue | oldBlockOrValue := self borderColor. ^ self borderColor: [ :aModel | (conditionBlock roValue: aModel) ifTrue: [ colorBlock roValue: aModel ] ifFalse: [ "Having to create a new element is rather ugly. Ideally, the oldBlockOrValue has to be 'unwrapped' for the translation" oldBlockOrValue roValue: (ROElement on: aModel) ]].! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlexandreBergel 8/27/2013 21:43'! if: conditionBlock fillColor: colorBlock "If conditionBlock is evaluated at true, then colorBlock is used to set the color of the node. Both conditionBlock and colorBlock are evaluated with the model value of the node." | oldBlockOrValue | oldBlockOrValue := self fillColor. ^self fillColor: [ :aModel | (conditionBlock roValue: aModel) ifTrue: [ colorBlock roValue: aModel ] ifFalse: [ "Having to create a new element is rather ugly. Ideally, the oldBlockOrValue has to be 'unwrapped' for the translation" oldBlockOrValue roValue: (ROElement on: aModel) ]]. ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'AlexandreBergel 4/19/2013 16:16'! label self setShape: self newLabel. ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! line self setShape: ROLine new. self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlexandreBergel 9/15/2013 00:44'! linearFillColor: block "Set the linear fill color for the nodes. The gradient goes from white to black. anObject could be a symbol, a block or a value. anObject is evaluated against the model of the node to be paint. aGroup is a collection of the model values. This is where the maximum is looked into." self getShape color: [ :element | | max | max := (element view attributes includesKey: #tmpMaxValue) ifTrue: [ element view attributeAt: #tmpMaxValue ] ifFalse: [ element view attributeAt: #tmpMaxValue put: ((element view elements collect: #model) maxValue: block )]. Color gray256: 256 - ((block roValue: element model) max: max in: (1 to: 256)) ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - color' stamp: 'AlejandroInfante 4/15/2013 14:22'! linearFillColor: block within: groupOfObjects "Set the linear fill color for the nodes. The gradient goes from white to black. anObject could be a symbol, a block or a value. anObject is evaluated against the model of the node to be paint. aGroup is a collection of the model values. This is where the maximum is looked into." | max | "If the collection is empty, then we return an arbitrary color. If the script is properly done, the color should not be used" groupOfObjects isEmpty ifTrue: [ ^ Color red ]. max := groupOfObjects maxValue: block. self getShape color: [ :v | Color gray256: 256 - ((block roValue: v model) max: max in: (1 to: 256)) ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlexandreBergel 4/19/2013 16:17'! linearFontSize: anObject within: aCollection "Set the linear font size for the nodes. The gradient goes from 0 to the maximum, obtained from aCollection. anObject could be a symbol, a block or a value. anObject is evaluated against the model of the node to be paint. aGroup is a collection of the model values. This is where the maximum is looked into." self fontSize: (RONFontLinearNormalizer inContext: aCollection withCommand: anObject)! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:22'! logHeight: aBlock self height: [ :v | ((aBlock value: v) + 1) log * 10 ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:22'! logWidth: aBlock self width: [ :v | ((aBlock value: v) + 1) log * 10 ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - private' stamp: 'AlexandreBergel 4/23/2013 15:50'! newCenteredLabel ^ ROCenteredLabel new color: self defaultTextColor; yourself! ! !ROMondrianShapeBuilder methodsFor: 'shapes - private' stamp: 'AlejandroInfante 4/15/2013 14:22'! newLabel ^ ROLabel new color: self defaultTextColor; yourself! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! orthoHorizontalLine self setShape: ROOrthoHorizontalLineShape new. self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - lines' stamp: 'JurajKubelka 6/3/2013 15:28'! orthoVerticalLine self setShape: ROOrthoVerticalLineShape new. self color: self defaultLineColor.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'AlejandroInfante 4/15/2013 14:22'! rectangle self setShape: ROBox new. self color: self defaultNodeColor. self getShape borderWidth: 1. ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'AlejandroInfante 4/15/2013 14:22'! rectangleWithoutBorder self setShape: ROBox new. self color: self defaultNodeColor! ! !ROMondrianShapeBuilder methodsFor: 'accessors' stamp: 'AlejandroInfante 4/15/2013 13:51'! setShape: aShape shape := aShape.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:23'! size: aSizeBlock self width: aSizeBlock. self height: aSizeBlock. ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'AlejandroInfante 4/15/2013 14:23'! text: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a unary symbol or a one-arg block" self getShape text: [ :element | aBlockOrSymbol roValue: element model ]! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'JurajKubelka 5/30/2013 14:24'! textHorizontalPadding: aSmallInteger ^ self getLabelShape textHorizontalPadding: aSmallInteger! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'JurajKubelka 5/30/2013 01:03'! textPadding: aSmallInteger ^ self getLabelShape textPadding: aSmallInteger! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'JurajKubelka 5/30/2013 14:24'! textVerticalPadding: aSmallInteger ^ self getLabelShape textVerticalPadding: aSmallInteger! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'AlexandreBergel 8/29/2013 08:00'! triangle self setShape: ROTriangle new. self color: self defaultNodeColor. self getShape borderWidth: 1. ! ! !ROMondrianShapeBuilder methodsFor: 'accessors' stamp: 'AlejandroInfante 4/15/2013 15:19'! viewBuilder ^viewBuilder! ! !ROMondrianShapeBuilder methodsFor: 'accessors' stamp: 'AlejandroInfante 4/15/2013 15:19'! viewBuilder: aViewBuilder viewBuilder := aViewBuilder.! ! !ROMondrianShapeBuilder methodsFor: 'shapes - size' stamp: 'AlejandroInfante 4/15/2013 14:23'! width: aWidthBlock self getShape width: [ :elem | aWidthBlock roValue: elem model ] ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'JurajKubelka 5/27/2013 20:23'! withCenteredText ^ self withCenteredText: #yourself! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'AlexandreBergel 8/27/2013 21:45'! withCenteredText: aBlockOrASymbolAnOrObject | label | label := self newCenteredLabel text: [ :anElement | aBlockOrASymbolAnOrObject roValue: anElement model ]. self getShape next: label. ! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'AlejandroInfante 4/15/2013 14:23'! withText ^ self withText: #yourself! ! !ROMondrianShapeBuilder methodsFor: 'shapes - text' stamp: 'AlejandroInfante 4/15/2013 14:23'! withText: aBlockOrASymbolAnOrObject | label | label := self newLabel text: [ :anElement | aBlockOrASymbolAnOrObject roValue: anElement model ]. self getShape next: label. " width := [ :v | label widthOfString: v printString ]. height := [ :v | label heightOfString: v printString ]."! ! !ROMondrianShapeBuilder methodsFor: 'shapes - nodes' stamp: 'TudorGirba 8/22/2013 12:30'! withoutBorder self getShape borderWidth: 0 ! ! !ROMondrianViewBuilder commentStamp: '' prior: 34316786! A ROMondrianViewBuilder models the Mondrian Domain Specific Language. It is mostly compatible with the original Mondrian language (cf., Mondrian paper and website). Instance Variables color: container: height: isLayouted: selfDefinedInteraction: shape: title: width: color - xxxxx container - xxxxx height - xxxxx isLayouted - xxxxx selfDefinedInteraction - xxxxx shape - xxxxx title - xxxxx width - xxxxx ! !ROMondrianViewBuilder class methodsFor: 'public' stamp: 'AlexandreBergel 5/31/2013 17:52'! draggable "Create a builder with a draggable roView in it, without the inertia" ^ self initializedView: (ROView new @ RODraggable)! ! !ROMondrianViewBuilder class methodsFor: 'public' stamp: 'AlexandreBergel 9/20/2012 12:29'! initializedView: aView ^ self basicNew initializeWithRoassalView: aView; yourself! ! !ROMondrianViewBuilder class methodsFor: 'public' stamp: 'AlexandreBergel 9/26/2012 11:17'! nonDraggable "Create a builder with a non draggable roView in it" ^ self initializedView: ROView new! ! !ROMondrianViewBuilder class methodsFor: 'public'! titled: aTitleAsString ^ self basicNew initializeWithTitle: aTitleAsString; yourself! ! !ROMondrianViewBuilder class methodsFor: 'public' stamp: 'AlexandreBergel 7/4/2013 14:13'! titled: aTitleAsString view: aView "Take a string and an instance of ROView as parameter" ^ self basicNew initializeWithTitle: aTitleAsString roassalView: aView; yourself! ! !ROMondrianViewBuilder class methodsFor: 'public' stamp: 'AlexandreBergel 9/20/2012 12:29'! view: aView "Take an instance of ROView as parameter" aView @ RODraggable @ RODraggableWithVelocity. ^ self initializedView: aView! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/25/2012 11:04'! addEdge: edge "private" | commonParentNode frameOfCommonNode | commonParentNode := (edge from mostSpecificParentCommonWith: edge to). commonParentNode add: edge. frameOfCommonNode := structureTree frameOfElement: commonParentNode. frameOfCommonNode addEdge: edge! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'JurajKubelka 4/22/2013 12:01'! addEdgeIn: aCollection from: source to: target model: model shape: aShape "Mondrian interface." | edge | (source notNil and: [ target notNil ]) ifTrue: [ (source ~= target) ifTrue: [ "An edge is between two different nodes " edge := ROEdge from: source to: target. edge model: model. edge + aShape. (source mostSpecificParentCommonWith: target) add: edge. aCollection addLast: edge ] ]! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/25/2012 11:29'! addEdges: edges "private" edges do: [ :e | self addEdge: e ]! ! !ROMondrianViewBuilder methodsFor: 'menu' stamp: 'AlexandreBergel 7/4/2013 08:55'! addMenu: aTitle callBack: aBlock self stack addMenu: aTitle callBack: aBlock! ! !ROMondrianViewBuilder methodsFor: 'compatibility'! addUserCommand: anArray "TODO"! ! !ROMondrianViewBuilder methodsFor: 'layout - operating' stamp: 'VanessaPena 4/11/2013 19:19'! applyLayout structureTree applyLayout. ! ! !ROMondrianViewBuilder methodsFor: '*glamour-roassal-presentations' stamp: 'TudorGirba 6/30/2013 22:37'! asBrowserWithStatusbar | browser | browser := GLMWrapper withStatusbar. browser title: 'Roassal painting'. browser show: [ :a | a roassal view: self ]. ^ browser! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:58'! bottomFlowLayout ^ self layout: ROBottomFlowLayout new! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 5/25/2013 17:50'! buildEdgeFrom: fromNode to: toNode for: anObject "Shape is not initialized here" | edge | edge := (ROEdge on: anObject from: fromNode to: toNode) + self getShape copy. interactionBuilder applyToElement: edge. ^ edge! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'JurajKubelka 6/3/2013 20:54'! cellLayout ^ self layout: (ROCellLayout new gapSize: 2)! ! !ROMondrianViewBuilder methodsFor: 'layout - operating' stamp: 'AlexandreBergel 5/14/2013 18:32'! center currentFrame layout on: ROLayoutEnd do: [ :event| ROFocusView centerView: rawView ]. ! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:52'! circleLayout ^ self layout: ROCircleLayout new! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 7/24/2012 14:35'! createMondrianView "Creating the view that will contain all the nodes and edges" | v | v := ROView titled: title. v @RODraggable @ RODraggableWithVelocity. ^ v! ! !ROMondrianViewBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 18:35'! createNewInteractionBuilder interactionBuilder := ROMondrianInteractionBuilder initializeOn: self. interactionBuilder popupText. ! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 7/25/2012 09:35'! currentFrame ^ currentFrame! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 7/24/2012 14:34'! defaultHeight "Default height of a node" ^ 5! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 7/24/2012 14:35'! defaultWidth "Default width of a node" ^ 5! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'TudorGirba 10/1/2012 14:00'! dominanceTreeLayout self setEdgesAttachPoint: ROVerticalAttachPoint. ^self layout: RODominanceTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 14:43'! edge: object from: fromBlock to: toBlock "Add an edge going from (fromBlock roValue: object) to (toBlock roValue: object)" ^ self edgeFromAssociation: ((fromBlock roValue: object) -> (toBlock roValue: object)) ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 4/7/2013 00:42'! edge: object toAll: toAllBlock "- object is the object from which the edges are defined from. - toAllBlock will be called similarly to return a collection of destination correpsonding to each source." ^ self edges: (Array with: object) from: #yourself toAll: toAllBlock! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 15:01'! edgeFromAssociation: assoc "Create an edge from an association e.g., view nodes: #(1 2). view edgeFromAssociation: 1 -> 2. " | edge | (assoc key isNil or: [ assoc value isNil ]) ifTrue: [ ^ nil ]. (assoc key == assoc value) ifTrue: [ ^ nil ]. self prepareForNewEdge. edge := self rawEdgeFromAssociation: assoc. edge notNil ifTrue: [ self addEdge: edge ]. self unsetShape. ^ edge! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 12/5/2012 18:03'! edgeFromModel: aModelObject ^ self raw edgeFromModel: aModelObject! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'JurajKubelka 4/22/2013 13:04'! edgeShape "Compatibility from Mondrian" ^ self getShape ! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 15:19'! edges ^ self raw elementsSuchThat: [ :v | v class == ROEdge ]! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'TudorGirba 7/29/2012 23:03'! edges: objects from: fromBlock to: toBlock "- aCollectionOfEntities is the collection of from which the edges are defined from. - aFromBlock will be called on each element of the collection and return one edge source each time. - aToBlock will be called on each element of the collection and return the destination node. Note that there is no restriction on the elements of aCollection, as long as aFromBlock returns a node. " | edges | edges := self rawEdges: objects from: fromBlock to: toBlock. self addEdges: edges. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 14:52'! edges: objects from: fromBlock toAll: toAllBlock "- objects is the collection of from which the edges are defined from. - fromBlock will be called on each entity of the collection and return one edge source each time. - toAllBlock will be called similarly to return a collection of destination correpsonding to each source. Note that there is no restriction on the entities of aCollection, as long as aFromBlock returns a node and aToBlock returns a collection of nodes. For example: aView edges: someFamixInvocations from: #sender toAll: #candidates Or: | collection | collection := #(1 2 3 4 5 6 7 8 9 10). view shape label. view nodes: collection. view edges: collection from: #yourself toAll: (collection select: #odd). view circleLayout aToBlock should return a collection, edges will be drawn from the entity returned by aFromBlock to this collection" | associations | associations := OrderedCollection new. objects do: [ :obj | | from | from := fromBlock roValue: obj. (toAllBlock roValue: obj) do: [:to | associations add: (from -> to) ] ]. ^ self edgesFromAssociations: associations! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'JurajKubelka 4/22/2013 12:01'! edges: aCollectionOfEntities from: aFromBlock toAll: aToBlock using: aShape fromGlobal: fromGlobal toGlobal: toGlobal "Mondrian interface. Same than edges:from:toAll:using: but the lookup can be particularized fromGlobal and toGlobal are boolean values" | source target edges targetModels | edges := OrderedCollection new. aCollectionOfEntities do: [ :each | self flag: #lookuNode:gobally:. source := self lookup: (aFromBlock roValue: each). targetModels := aToBlock roValue: each. self assert: [targetModels isCollection or: [targetModels isNil]] description: 'destination nodes is not a collection'. targetModels ifNotNil: [ targetModels do: [ :targetModel | target := self lookup: targetModel . self addEdgeIn: edges from: source to: target model: each shape: aShape ]]]. self flag: 'self resetInteraction'. self flag: 'self root resetElementsToDisplayCacheRecursively'. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'TudorGirba 11/29/2012 13:31'! edges: objects fromAll: fromAllBlock to: toBlock | associations | associations := OrderedCollection new. objects do: [ :obj | | to | to := toBlock roValue: obj. (fromAllBlock roValue: obj) do: [:from | associations add: (from -> to) ] ]. ^ self edgesFromAssociations: associations! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/25/2012 11:29'! edgesFrom: symbolOrBlock "The message edgesFrom: defines one edge per node. For each node that has been added in the visualization, an edge is defined between this node and a node lookup from the provided block." | edges | edges := self rawEdgesFrom: symbolOrBlock. self addEdges: edges. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 11/28/2012 23:03'! edgesFrom: fromBlock to: toBlock "- aCollectionOfEntities is the collection of from which the edges are defined from. - aFromBlock will be called on each element of the collection and return one edge source each time. - aToBlock will be called on each element of the collection and return the destination node. Note that there is no restriction on the elements of aCollection, as long as aFromBlock returns a node. " ^ self edges: ((rawView elementsSuchThat: #isNotEdge) collect: #model) from: fromBlock to: toBlock! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 15:02'! edgesFromAssociations: associations | answer edge interestingEdges | self prepareForNewEdge. interestingEdges := associations select: [ :assoc | assoc key notNil and: [ assoc value notNil ] ]. interestingEdges := interestingEdges select: [ :assoc | assoc key ~~ assoc value ]. answer := interestingEdges collect: [ :assoc | edge := self rawEdgeFromAssociation: assoc. edge notNil ifTrue: [ self addEdge: edge ]. edge ]. self unsetShape. ^ answer! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 7/24/2012 15:02'! edgesToAll: symbolOrBlock | edges | edges := self rawEdgesToAll: symbolOrBlock. edges do: [ :e | self addEdge: e ]. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 12/5/2012 17:59'! elementFromModel: aModelObject ^ self raw elementFromModel: aModelObject! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 4/7/2013 07:04'! elementsFromModels: objects ^ self raw elementsFromModels: objects! ! !ROMondrianViewBuilder methodsFor: 'menu' stamp: 'JurajKubelka 3/27/2013 11:14'! exportButton self addMenu: 'Export' callBack: [ :stack | | exporters index| exporters := SortedCollection sortBlock: [ :a1 :a2 | a1 key < a2 key ]. ROExportCommand commands do: [:cm | exporters add: cm name -> cm ] . index := UIManager default chooseFrom: (exporters collect: #key). index > 0 ifTrue: [ (exporters at: index) value executeOn: self raw ] ]! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'JurajKubelka 4/23/2013 14:09'! extensibleSize parentBehavior := ROExtensibleParent instance! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'JurajKubelka 4/24/2013 10:26'! extensibleSizeWithPaddingGap: aNumber parentBehavior := ROExtensibleParent new paddingGap: aNumber; yourself! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlejandroInfante 4/15/2013 15:20'! fixedSize parentBehavior := ROFixedSizedParent instance! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'JurajKubelka 5/6/2013 14:50'! fixedSizeWithPaddingGap: aNumber parentBehavior := ROFixedSizedParent new paddingGap: aNumber; yourself! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:58'! flowLayout ^ self layout: ROFlowLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/17/2013 10:38'! forceBasedLayout ^ self layout: ROForceBasedLayout new! ! !ROMondrianViewBuilder methodsFor: 'compatibility'! fromPositions: v "For compatibility reason"! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlejandroInfante 4/15/2013 14:15'! getShape ^ self shape getShape.! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:52'! gridLayout ^ self layout: (ROGridLayout new gapSize: 2) ! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'TudorGirba 9/27/2012 23:08'! horizontalDominanceTreeLayout self setEdgesAttachPoint: ROHorizontalAttachPoint. ^self layout: ROHorizontalDominanceTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:53'! horizontalLineLayout ^ self layout: ROHorizontalLineLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'JurajKubelka 4/2/2013 10:20'! horizontalNarrowTreeLayout ^ self layout: ROHorizontalNarrowTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'BenComan 8/5/2012 16:04'! horizontalTreeLayout self setEdgesAttachPoint: ROHorizontalAttachPoint. ^self layout: ROHorizontalTreeLayout new.! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 5/25/2013 18:40'! initFrame structureTree := ROMondrianFrame newFrom: self. structureTree parent: structureTree. currentFrame := structureTree! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlejandroInfante 4/15/2013 14:31'! initialize self initializeWithTitle: ROView defaultWindowTitle.! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 5/3/2012 09:23'! initializeWithRoassalView: aView self initializeWithTitle: ROView defaultWindowTitle roassalView: aView! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 5/3/2012 09:14'! initializeWithTitle: aTitleAsString self initializeWithTitle: aTitleAsString roassalView: self createMondrianView. ! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlexandreBergel 7/4/2013 08:52'! initializeWithTitle: aTitleAsString roassalView: aView super initialize. shapeBuilder := ROMondrianShapeBuilder initializeOn: self. self createNewInteractionBuilder. title := aTitleAsString. rawView := aView. aView title: title. "Not strictly necessary apparently" aView zOrdering: self zOrdering. shouldHavePopup := true. self initFrame. viewStack := ROViewStack new addView: rawView; title: rawView title. self setNodeShapeIfNecessary. self horizontalLineLayout. ! ! !ROMondrianViewBuilder methodsFor: 'interactions' stamp: 'AlexandreBergel 5/25/2013 11:25'! interaction "For compatibility with Mondrian" ^ interactionBuilder! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 7/24/2012 16:54'! lastFrame ^ structureTree last! ! !ROMondrianViewBuilder methodsFor: 'layout - operating' stamp: 'AlexandreBergel 7/25/2012 10:05'! layout: aLayout currentFrame layout: aLayout. ^ aLayout ! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'TudorGirba 7/29/2012 23:22'! lookup: anObject "Return the node that has the object as model" | ans | ans := self raw elementsSuchThat: [ :n | n isEdge not and: [n model = anObject ] ]. ans isEmpty ifTrue: [ ^ self nestedLookup: anObject ]. ans size ~= 1 ifTrue: [ self error: 'Several candidates' ]. ^ ans first! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'JurajKubelka 4/2/2013 10:20'! narrowTreeLayout ^ self layout: ROVerticalNarrowTreeLayout new.! ! !ROMondrianViewBuilder methodsFor: 'initialize' stamp: 'AlejandroInfante 4/15/2013 13:59'! needToSetup ^ self getShape isNil! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlexandreBergel 6/9/2012 15:19'! nestedLookup: anObject "Return the node that has the object as model, it goes " self raw elementsDo: [ :el | | t | t := self nestedLookup: anObject in: el. t ifNotNil: [ ^ t ] ]. ^ nil! ! !ROMondrianViewBuilder methodsFor: 'nodes'! nestedLookup: anObject in: aNode "Return the node that has the object as model, it goes " | ans | (aNode model = anObject) ifTrue: [ ^ aNode ]. aNode elementsDo: [ :n | | t | t := self nestedLookup: anObject in: n. t ifNotNil: [ ^ t ] ]. ^ nil. ! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 7/14/2012 15:51'! noLayout ^ self layout: RONullLayout ! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlexandreBergel 4/7/2013 00:16'! node: object "Add a new node to the view" ^ (self nodes: (Array with: object)) first! ! !ROMondrianViewBuilder methodsFor: 'nodes'! node: object forIt: aBlock ^ (self nodes: (Array with: object) forEach: [ :v | aBlock value ]) first! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 15:18'! nodes ^ self raw elementsSuchThat: [ :v | v class == ROElement ]! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlexandreBergel 5/25/2013 18:36'! nodes: objects | els | self assert: [ objects isCollection] description: 'Should provide a collection as parameter'. self prepareForNewNode. els := ROElement forCollection: objects. els do: [ :el | el + self getShape chainedCopy @ RODraggable. el resizeStrategy: parentBehavior ]. interactionBuilder applyToElements: els. self assert: [ els allSatisfy: [ :e | e model notNil ] ]. rawView addAll: els. self unsetShape. self createNewInteractionBuilder. currentFrame addElements: els. ^ els! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlexandreBergel 5/25/2013 18:36'! nodes: objects forEach: aBlock "Create a set of nodes, each representing an element of objects. Each node then acts as a view on its own." | nodes oldResizeStrategy | nodes := self nodes: objects. nodes do: [ :n | self push. self horizontalLineLayout. rawView := n. self createNewInteractionBuilder. oldResizeStrategy := n resizeStrategy. n resizeStrategy: (ROPermissiveParent new padding: oldResizeStrategy padding). aBlock roValue: n model. n resizeStrategy: oldResizeStrategy. n adjustSizeIfNecessary. self pop. ]. self unsetShape. ^ nodes! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 15:21'! nodesAndEdges ^ rawView elementsSuchThat: [ :v | true ]! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 7/24/2012 18:05'! numberOfFrames "number of children of the root node" ^ structureTree numberOfFrames! ! !ROMondrianViewBuilder methodsFor: 'opening' stamp: 'AlexandreBergel 7/4/2013 08:56'! open "Open the view. Return the system window opened" | win | win := viewStack open. self applyLayout. ^ win ! ! !ROMondrianViewBuilder methodsFor: 'opening' stamp: 'AlexandreBergel 7/4/2013 08:57'! openInWindowSized: extent "Open the view. Return the system window opened" | win | win := viewStack openInWindowSized: extent. self applyLayout. ^ win ! ! !ROMondrianViewBuilder methodsFor: '*glamour-roassal-presentations' stamp: 'TudorGirba 5/31/2013 09:56'! openWithStatusbar ^ self asBrowserWithStatusbar openOn: self! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 5/25/2013 18:36'! pop rawView := currentFrame view. self setShape: currentFrame shape. self createNewInteractionBuilder. currentFrame := currentFrame parent! ! !ROMondrianViewBuilder methodsFor: 'menu' stamp: 'JurajKubelka 3/27/2013 11:22'! populateBasicNavigationMenu self exportButton. self zoomInButton. self zoomOutButton. "We also do a small scrolling to not have the buttons over the nodes" self raw translateBy: 0 @ 30. ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 5/25/2013 17:45'! prepareForNewEdge self needToSetup ifTrue: [ self setLineShapeIfNecessary ]! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlexandreBergel 5/25/2013 17:45'! prepareForNewNode self needToSetup ifTrue: [ self setNodeShapeIfNecessary ]. parentBehavior ifNil: [ parentBehavior := ROExtensibleParent instance ] ! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 7/24/2012 17:32'! prepareStack structureTree isEmpty ifTrue: [ self push ]! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 5/25/2013 18:40'! push | newFrame | newFrame := ROMondrianFrame newFrom: self. currentFrame addChild: newFrame. newFrame parent: currentFrame. currentFrame := newFrame.! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 4/18/2013 09:11'! radialNarrowTreeLayout ^ self layout: RONarrowRadialTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 4/18/2013 09:11'! radialTreeLayout ^ self layout: RORadialTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 15:21'! raw ^ rawView! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'TudorGirba 7/29/2012 22:48'! rawEdgeFromAssociation: assoc | from to | from := self lookup: assoc key. to := self lookup: assoc value. (from isNil or: [ to isNil ]) ifTrue: [ ^ nil ]. ^ self buildEdgeFrom: from to: to for: assoc! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 12/1/2012 17:39'! rawEdges: objects from: symbolOrBlockFrom to: symbolOrBlockTo | edges alreadyCreatedEdges | edges := OrderedCollection new. alreadyCreatedEdges := IdentityDictionary new. self prepareForNewEdge. objects do: [ :obj | | from to | from := self lookup: (symbolOrBlockFrom roValue: obj). to := self lookup: (symbolOrBlockTo roValue: obj). ((from notNil and: [ to notNil ]) and: [ from ~~ to ]) ifTrue: [ alreadyCreatedEdges at: from model ifAbsentPut: [ IdentitySet new ]. ((alreadyCreatedEdges at: from model) includes: to model) not ifTrue: [ (alreadyCreatedEdges at: from model) add: to model. edges add: (self buildEdgeFrom: from to: to for: obj) ] ] ]. self unsetShape. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'edges'! rawEdgesFrom: symbolOrBlockFrom ^ self rawEdgesFrom: symbolOrBlockFrom to: #yourself! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 8/8/2013 14:29'! rawEdgesFrom: symbolOrBlockFrom to: symbolOrBlockTo ^ self rawEdges: (rawView elementsNotEdge collect: [:e | e model]) from: symbolOrBlockFrom to: symbolOrBlockTo ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlexandreBergel 5/14/2013 19:13'! rawEdgesToAll: symbolOrBlock | edges values v | edges := OrderedCollection new. self prepareForNewEdge. rawView elementsNotEdge do: [ :el | values := symbolOrBlock roValue: el model. rawView elementsDo: [ :el2 | v := values detect: [ :n | n == el2 model ] ifNone: [ nil ]. (v notNil and: [ el ~~ el2 ]) ifTrue: [ edges add: (self buildEdgeFrom: el to: el2 for: el2) ] ] ]. self unsetShape. ^ edges! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:33'! removeAllEdgesFrom: anObject |edges| edges := (self elementFromModel: anObject) allEdgesFrom. edges do: [ :ed | (currentFrame frameOfElement: ed) removeElement: ed. ed remove. ]. ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:35'! removeAllEdgesFromNodes: objects objects do:[:ob | self removeAllEdgesFrom: ob ]. ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:33'! removeAllEdgesTo: anObject |edges| edges := (self elementFromModel: anObject) allEdgesTo. edges do: [ :ed | (currentFrame frameOfElement: ed) removeElement: ed. ed remove. ]. ! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'VanessaPena 4/12/2013 12:35'! removeAllEdgesToNodes: objects objects do:[:ob | self removeAllEdgesTo: ob ]. ! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 11:42'! removeNode: anObject self removeNodes: (Array with: anObject) ! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 11:43'! removeNodes: objects |elements| self assert: [ objects isCollection] description: 'Should provide a collection as parameter'. elements := self raw elementsFromModels: objects. currentFrame removeElements: elements. elements do: [:el | el remove ]. ! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'VanessaPena 4/12/2013 13:22'! removeNodesAndEdgesOf: objects self removeAllEdgesFromNodes: (2 to: 4). self removeAllEdgesToNodes: (2 to: 4). self removeNodes: (2 to: 4).! ! !ROMondrianViewBuilder methodsFor: 'accessing'! root ^ self ! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 09:04'! scatterPlotLayout ^ self layout: ROScatterplotLayout new! ! !ROMondrianViewBuilder methodsFor: 'layout - operating' stamp: 'AlejandroInfante 4/15/2013 14:37'! setEdgesAttachPoint: attachPointClass self edges do: [ :ed | (ed isShapedAs: ROShape) ifTrue: [ (ed getShape: ROShape) attachPoint: attachPointClass instance ] ifFalse: [ ROLine new color: self shape color; attachPoint: attachPointClass instance ] ]! ! !ROMondrianViewBuilder methodsFor: 'edges' stamp: 'AlejandroInfante 4/15/2013 14:01'! setLineShapeIfNecessary "If no shape for edge is defined, then we set up a default one" self getShape ifNil: [ self shape line ]! ! !ROMondrianViewBuilder methodsFor: 'nodes' stamp: 'AlejandroInfante 4/15/2013 14:01'! setNodeShapeIfNecessary "If no shape for node is defined, then we set up a default one" self getShape ifNil: [ self shape rectangle ]! ! !ROMondrianViewBuilder methodsFor: 'shapes' stamp: 'AlejandroInfante 4/15/2013 14:15'! setShape: aShape self shape setShape: aShape.! ! !ROMondrianViewBuilder methodsFor: 'shapes' stamp: 'AlexandreBergel 5/25/2013 11:20'! shape ^ shapeBuilder! ! !ROMondrianViewBuilder methodsFor: 'shapes' stamp: 'AlejandroInfante 4/15/2013 14:02'! shape: aShape self setShape: aShape! ! !ROMondrianViewBuilder methodsFor: 'signalling' stamp: 'JurajKubelka 5/29/2013 14:34'! signalUpdate rawView signalUpdate ! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 7/25/2012 11:38'! stack ^ viewStack! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 7/25/2012 11:38'! stack: aStack "This method is essentially used in the VW Easel. It should not be existing actually" viewStack := aStack! ! !ROMondrianViewBuilder methodsFor: 'stack' stamp: 'AlexandreBergel 7/24/2012 16:36'! structureTree ^ structureTree! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'BenComan 8/5/2012 16:00'! sugiyamaLayout self setEdgesAttachPoint: ROVerticalAttachPoint. ^ self layout: ROSugiyamaLayout new ! ! !ROMondrianViewBuilder methodsFor: 'accessing'! title "Return a string" ^ title! ! !ROMondrianViewBuilder methodsFor: 'accessing'! title: aString "Define the title of the view" title := aString! ! !ROMondrianViewBuilder methodsFor: 'compatibility'! toPositions: v "For compatibility reason"! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'BenComan 8/5/2012 16:10'! treeLayout self setEdgesAttachPoint: ROVerticalAttachPoint. ^ self layout: ROTreeLayout new! ! !ROMondrianViewBuilder methodsFor: 'shapes' stamp: 'AlexandreBergel 5/25/2013 17:45'! unsetShape self setShape: nil. ! ! !ROMondrianViewBuilder methodsFor: 'layout' stamp: 'AlexandreBergel 5/18/2012 08:53'! verticalLineLayout ^ self layout: ROVerticalLineLayout new. ! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 18:38'! view "This method is made to have the builder, roelement and roview polymorphic. Useful in the class ROPopupView" ^ self raw! ! !ROMondrianViewBuilder methodsFor: 'accessing' stamp: 'AlexandreBergel 6/9/2012 15:21'! view: aView rawView := aView! ! !ROMondrianViewBuilder methodsFor: 'todo' stamp: 'AlexandreBergel 11/3/2012 20:32'! withoutBackground! ! !ROMondrianViewBuilder methodsFor: 'zOrdering' stamp: 'AlexandreBergel 12/13/2012 18:13'! zOrdering ^ (ROZOrdering new setZIndex: [:edge | ((edge source depth * 2) max: (edge target depth * 2)) - 1 ] if: #isEdge; setZIndex: [ :element | element depth * 2 ] if: #isNotEdge).! ! !ROMondrianViewBuilder methodsFor: 'menu' stamp: 'JurajKubelka 3/27/2013 11:21'! zoomInButton self addMenu: 'Zoom in' callBack: [ :stack | ROZoomInMove new on: stack firstView ].! ! !ROMondrianViewBuilder methodsFor: 'menu' stamp: 'JurajKubelka 3/27/2013 11:21'! zoomOutButton self addMenu: 'Zoom out' callBack: [ :stack | ROZoomOutMove new on: stack firstView ].! ! !ROMorphicExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/6/2013 16:36'! addClassZoomTo: aClass for: view |zoomClass| zoomClass := ROZoomIntoElementOnClick new. zoomClass stack: view stack; view: [:classEl | |vClass methods methodsNodes| methods := SortedCollection sortBlock: [:a : b | a numberOfLinesOfCode < b numberOfLinesOfCode ]. classEl model methods do: [:eachMethod | methods add: eachMethod]. vClass := ROMondrianViewBuilder new. vClass interaction noPopup. vClass shape rectangle size: [:method | method numberOfLinesOfCode ]. methodsNodes := vClass nodes: methods. methodsNodes do:[:m | m @ (ROPopup new receivingView: view stack; text: (m model methodClass asString, '>> ', m model selector ); box: (ROBox new color: Color white; borderColor: Color black; borderWidth: 1); textColor: Color black ) ]. vClass gridLayout. vClass applyLayout. vClass raw ]. aClass @ zoomClass. ! ! !ROMorphicExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/6/2013 16:35'! addPackageZoomTo: pack for: view |zoom| zoom := ROZoomIntoElementOnClick new. zoom stack: view stack; view: [:el | |v classes classesNodes| classes := pack model classes. v := ROMondrianViewBuilder new. v interaction noPopup. v shape rectangle width: [ :cls | cls instVarNames size * 5 ]; height: [ :cls | cls methods size ]; linearFillColor: #linesOfCode within: classes. classesNodes := v nodes: classes. classesNodes do:[:class | self addClassZoomTo: class for: view. class @ (ROPopup new receivingView: view stack; text: class model name asString; box: (ROBox new color: Color white; borderColor: Color black; borderWidth: 1); textColor: Color black ) .]. v edgesFrom: #superclass. v treeLayout. v applyLayout . v raw ]. pack @ zoom. ! ! !ROMorphicExample methodsFor: 'example' stamp: 'AlexandreBergel 5/20/2012 23:22'! image " self new image This example works only on Pharo " | view elements iconMethods | view := ROView new. iconMethods := ThemeIcons class selectors select: [ :k | k endsWith: 'Icon' ]. elements := ROElement forCollection: iconMethods. elements do: [ :el | el + (ROImage new form: [ :k | ThemeIcons perform: k model ] ) ]. view addAll: elements. ROGridLayout on: elements. view open.! ! !ROMorphicExample methodsFor: 'example' stamp: 'AlexandreBergel 5/22/2012 21:01'! innerNodeAndZoom3 " self new innerNodeAndZoom3 " | view els packages | packages := PackageInfo allPackages copyFrom: 1 to: 20. view := ROView new. els := ROElement forCollection: packages. els do: [:spr | | innerNodes | spr extent: 50@50. spr + ROBorder red. spr @ ROZoomOnClick @ RODraggable. innerNodes := ROElement forCollection: (spr model classes). innerNodes do: [:s | s + ROBox green @ RODraggable @ (ROPopup new textColor: Color red) ]. spr addAll: (ROGridLayout on: innerNodes). ]. view addAll: els. view @ RODraggable. ROGridLayout on: els. view open. ! ! !ROMorphicExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/6/2013 16:36'! polymetricSemantic " self new polymetricSemantic " | view | view := ROMondrianViewBuilder new. self polymetricSemanticOn: view. view open! ! !ROMorphicExample methodsFor: 'interaction' stamp: 'AlexandreBergel 5/6/2013 16:35'! polymetricSemanticOn: view | nodes categories packages | "Left Click to a package to inspect its classes. Left Click to a class to inspect its methods. RIght Click to the view to return. " categories := Smalltalk globals organization categories select:[:cat | 'Roassal-*' match: cat]. packages := categories collect: [:cat | PackageInfo named: cat]. view shape rectangle size: 450. view interaction popupText: [:each | each packageName]. nodes := view nodes: packages. nodes do: [:pack | self addPackageZoomTo: pack for: view ]. view layout: (ROTreeMapLayout withWeightBlock: [ :e | e model classes size ]).! ! !ROMorphicExample methodsFor: 'example' stamp: 'AlexandreBergel 11/16/2012 09:28'! progressWhenLayouting " self new progressWhenLayouting " "Source code: ROMondrianExample>>statusBarOn:" "Preambule. It includes the initialization. " | view rawView statusBar | rawView := ROView new. view := ROMondrianViewBuilder view: rawView. "-------------" "-------------" statusBar := ROElement new + ROLabel + ROBox white. view stack add: statusBar. statusBar translateTo: 0 @ 480. view interaction on: ROMouseEnter do: [ :event | statusBar model: event element model. ]. view shape rectangle size: 10. view nodes: (1 to: 1500). view horizontalLineLayout on: ROLayoutStep do: [ :evt | statusBar model: evt currentIteration printString, ' / ', evt maxInterations printString. World doOneCycleNow. view raw signalUpdate. ]. "-------------" "-------------" "Below is the initiation of the menu and opening the visualization" ROEaselMorphic new populateMenuOn: view. view open! ! !ROMultipleColorLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:05'! valueRange: anArrayOfNumbers colorRange: anArrayOfColors ^ self new valueRange: anArrayOfNumbers colorRange: anArrayOfColors! ! !ROMultipleColorLinearNormalizer methodsFor: 'private-accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! detectNormalizerFor: aValue normalizers keysAndValuesDo: [:range :norm | (range rangeIncludes: aValue) ifTrue: [^ norm] ]. self error: aValue asString, ' not in declared ranges'! ! !ROMultipleColorLinearNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/2/2012 16:05'! initialize command := #yourself! ! !ROMultipleColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/3/2012 18:35'! roValue: anEntity | value | value := self command value: anEntity. "detect range for the value, retrieve and call corresponding normalizers" ^ (self detectNormalizerFor: value) roValue: value! ! !ROMultipleColorLinearNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/4/2012 01:06'! valueRange: anArrayOfNumbers colorRange: anArrayOfColors " {1. 2. 3} {Color red. Color yellow. Color green}" | size start end | normalizers := Dictionary new. self assert: anArrayOfNumbers size = anArrayOfColors size. size := anArrayOfNumbers size. 1 to: size - 1 do: [ :i | start := anArrayOfNumbers at: i. end := anArrayOfNumbers at: i + 1. normalizers at: (start to: end) put: (RONColorLinearNormalizer inContext: (Array with: start with: end) lowColor: (anArrayOfColors at: i) highColor: (anArrayOfColors at: i + 1)) ]. ! ! !RONAbstractNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! command ^command! ! !RONAbstractNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! command: aBlock command := aBlock! ! !RONAbstractNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:13'! roValue: anEntity self subclassResponsibility! ! !RONExplicitIdentityNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:05'! withCommand: aBlock withColors: aCollection withDefaultColor: aColor ^(self withCommand: aBlock) colors: aCollection; defaultColor: aColor; yourself! ! !RONExplicitIdentityNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! colors ^colors! ! !RONExplicitIdentityNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! colors: anObject colors := anObject! ! !RONExplicitIdentityNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! defaultColor ^defaultColor! ! !RONExplicitIdentityNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:05'! defaultColor: anObject defaultColor := anObject! ! !RONExplicitIdentityNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 7/4/2012 00:21'! nextColor colorIndex := colorIndex + 1. ^colorIndex > self colors size ifTrue: [ self defaultColor ] ifFalse: [ self colors at: colorIndex ]! ! !RONIdentityNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/14/2012 10:43'! beginingAtBlue ^ self new setIndexTo: #blue; yourself! ! !RONIdentityNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/14/2012 10:40'! beginingAtRed ^ self new setIndexTo: #red; yourself! ! !RONIdentityNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:05'! withCommand: aBlock ^(self new) command: aBlock; yourself! ! !RONIdentityNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 10/21/2013 23:45'! colorNames ^ #(#black #veryVeryDarkGray #veryDarkGray #darkGray #gray #lightGray #veryLightGray #veryVeryLightGray #white #red #yellow #green #cyan #blue #magenta #brown #orange #lightRed #lightYellow #lightGreen #lightCyan #lightBlue #lightMagenta #lightBrown #lightOrange #transparent)! ! !RONIdentityNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/2/2012 16:05'! initialize super initialize. colorIndex := 0. dictionary := IdentityDictionary new. command := #yourself! ! !RONIdentityNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 10/21/2013 23:45'! nextColor colorIndex := colorIndex \\ self colorNames size + 1. ^Color perform: (self colorNames at: colorIndex)! ! !RONIdentityNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/3/2012 00:12'! roValue: anEntity ^dictionary at: (command roValue: anEntity) ifAbsentPut: [ self nextColor ]! ! !RONIdentityNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 10/21/2013 23:45'! setIndexTo: colorAsSymbol "colorAsSymbol has to be one of Color colorNames. The method set the current index to the color given in parameter" colorIndex := (self colorNames indexOf: colorAsSymbol) - 1! ! !RONColorLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection lowColor: lowColor highColor: highColor | normalizer | normalizer := self inContext: aCollection. normalizer lowColor: lowColor. normalizer highColor: highColor. ^normalizer! ! !RONColorLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection lowColor: lowColor lowThreshold: lowThreshold highColor: highColor highThreshold: highThreshold | normalizer | normalizer := self inContext: aCollection. normalizer lowColor: lowColor. normalizer highColor: highColor. normalizer minBrightness: lowThreshold. normalizer maxBrightness: highThreshold. ^normalizer! ! !RONColorLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection withCommand: aBlock lowColor: lowColor highColor: highColor | normalizer | normalizer := self inContext: aCollection withCommand: aBlock. normalizer lowColor: lowColor. normalizer highColor: highColor. ^normalizer! ! !RONColorLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection withCommand: aBlock lowColor: lowColor lowThreshold: lowThreshold highColor: highColor highThreshold: highThreshold | normalizer | normalizer := self inContext: aCollection withCommand: aBlock. normalizer lowColor: lowColor. normalizer highColor: highColor. normalizer minBrightness: lowThreshold. normalizer maxBrightness: highThreshold. ^normalizer! ! !RONColorLinearNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 7/2/2012 16:06'! blend: aColor with: aColorValue weight: wt "Answer a new ColorValue which is a weighted blend of the receiver and the supplied ColorValue." "Simply interpolates in RGB space." | rv gv bv invWt | invWt := 1-wt. rv := ((aColor red * invWt) + ((aColorValue red)*wt)) "rounded". gv := ((aColor green * invWt) + ((aColorValue green)*wt)) "rounded". bv := ((aColor blue *invWt)+ ((aColorValue blue)*wt)) "rounded". ^Color r: rv g: gv b: bv! ! !RONColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! highColor: aBlock highColor := aBlock! ! !RONColorLinearNormalizer methodsFor: 'translator protocol' stamp: 'AlexandreBergel 7/3/2012 18:35'! highColorFor: anEntity ^highColor roValue: anEntity! ! !RONColorLinearNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/2/2012 16:06'! initialize super initialize. lowColor := Color white. highColor := Color black! ! !RONColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! lowColor: aBlock lowColor := aBlock! ! !RONColorLinearNormalizer methodsFor: 'translator protocol' stamp: 'AlexandreBergel 7/3/2012 18:35'! lowColorFor: anEntity ^lowColor roValue: anEntity! ! !RONColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! maxBrightness: aBlock maxBrightness := aBlock! ! !RONColorLinearNormalizer methodsFor: 'translator protocol' stamp: 'AlexandreBergel 7/3/2012 18:35'! maxBrightnessFor: anEntity ^maxBrightness isNil ifTrue: [1.0] ifFalse: [maxBrightness roValue: anEntity]! ! !RONColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! minBrightness: aBlock minBrightness := aBlock! ! !RONColorLinearNormalizer methodsFor: 'translator protocol' stamp: 'AlexandreBergel 7/3/2012 18:35'! minBrightnessFor: anEntity ^minBrightness isNil ifTrue: [0.0] ifFalse: [minBrightness roValue: anEntity]! ! !RONColorLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:14'! roValue: anEntity "Calculates the color of the entity based on the context." | myValue myHighColor myLowColor myMinBrightness myMaxBrightness weight minValue maxValue | "Get color specific data" minValue := self minimumValue: anEntity. maxValue := self maximumValue: anEntity. myMinBrightness := self minBrightnessFor: anEntity. myMaxBrightness := self maxBrightnessFor: anEntity. myHighColor := self highColorFor: anEntity. myLowColor := self lowColorFor: anEntity. "Get data" weight := minValue = maxValue ifTrue: [(myMinBrightness + myMaxBrightness) / 2] ifFalse: [ myValue := (self command value: anEntity) - (self minimumValue: anEntity). myMinBrightness + (myValue abs / (maxValue - minValue) * (myMaxBrightness - myMinBrightness)) ]. ^self blend: myLowColor with: myHighColor weight: weight! ! !RONFontLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/3/2012 00:12'! roValue: anEntity "Calculates the color of the entity based on the context." | value | value := self command roValue: anEntity. ^5 + (38 * (value abs / (self maximumValue: anEntity))) asInteger! ! !RONLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection ^self inContext: aCollection withCommand: #yourself! ! !RONLinearNormalizer class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/2/2012 16:06'! inContext: aCollection withCommand: aBlock ^(self new) context: aCollection; command: aBlock; yourself! ! !RONLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! command: aBlock super command: aBlock. self flushCache! ! !RONLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! context ^context! ! !RONLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! context: aContext context := aContext. self flushCache! ! !RONLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:06'! flushCache maximumValue := nil! ! !RONLinearNormalizer methodsFor: 'initialize-release' stamp: 'AlexandreBergel 7/2/2012 16:06'! initialize "Initialize a newly created instance. This method must answer the receiver." super initialize. maximumValue := nil! ! !RONLinearNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 7/3/2012 00:12'! maximumValue: anEntity "Returns the largest value that the color metric provides" maximumValue isNil ifTrue: [maximumValue := (self context roValue: anEntity) inject: 1 into: [:maximum :entity | maximum max: (self command roValue: entity)]]. ^maximumValue! ! !RONLinearNormalizer methodsFor: 'private' stamp: 'AlexandreBergel 7/4/2012 00:15'! minimumValue: anEntity "Returns the smallest value that the color metric provides" minimumValue isNil ifTrue: [minimumValue := (self context roValue: anEntity) inject: 100000000000 into: [:minimum :entity | minimum min: (self command roValue: entity)]]. ^minimumValue! ! !RONumberLinearNormalizer methodsFor: 'initialization' stamp: 'AlexandreBergel 7/2/2012 16:07'! initialize super initialize. scale := 1! ! !RONumberLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/3/2012 00:13'! roValue: anEntity "Normalize value based on maximum value." | value | value := self command roValue: anEntity. ^ ((value abs / (self maximumValue: anEntity)) asFloat * self scale) asInteger! ! !RONumberLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:07'! scale ^ scale! ! !RONumberLinearNormalizer methodsFor: 'accessing' stamp: 'AlexandreBergel 7/2/2012 16:07'! scale: anObject scale := anObject! ! !ROValueLinearNormalizer methodsFor: 'initialize-release' stamp: 'AlejandroInfante 1/11/2013 15:19'! initialize super initialize. minScale := 0. maxScale := 1.! ! !ROValueLinearNormalizer methodsFor: 'accessing' stamp: 'AlejandroInfante 1/11/2013 15:19'! maxScale ^maxScale.! ! !ROValueLinearNormalizer methodsFor: 'accessing' stamp: 'AlejandroInfante 1/11/2013 15:20'! maxScale: aValue ^maxScale := aValue.! ! !ROValueLinearNormalizer methodsFor: 'accessing' stamp: 'AlejandroInfante 1/11/2013 15:20'! minScale ^minScale.! ! !ROValueLinearNormalizer methodsFor: 'accessing' stamp: 'AlejandroInfante 1/11/2013 15:20'! minScale: aValue minScale := aValue.! ! !ROValueLinearNormalizer methodsFor: 'accessing' stamp: 'AlejandroInfante 1/11/2013 15:20'! roValue: anEntity "Normalize value based on minimum and maximum value." | value slope | value := self command roValue: anEntity. slope := self slope: anEntity. ^ ((value abs * slope) + self maxScale - ((self maximumValue: anEntity) asFloat * slope)) asInteger! ! !ROValueLinearNormalizer methodsFor: 'as yet unclassified' stamp: 'AlejandroInfante 1/11/2013 15:20'! slope: anEntity ^ (maxScale - minScale) / ((self maximumValue: anEntity) asFloat - (self minimumValue: anEntity )asFloat).! ! !ROMorphicExampleUtility class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 5/11/2012 14:50'! getMethodsForClass: aClass ^aClass methods ! ! !ROMorphicExampleUtility class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 1/17/2013 16:00'! substringsFor: aString ^aString substrings ! ! !RONativeExampleUtility class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 5/11/2012 14:48'! current ^self allSubclasses first ! ! !RONativeExampleUtility class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 5/11/2012 14:50'! getMethodsForClass: aClass ^self subclassResponsibility ! ! !RONativeExampleUtility class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 5/11/2012 14:51'! substringsFor: aString ^self subclassResponsibility ! ! !RONativeWidgetFactory commentStamp: 'AlexandreBergel 4/23/2012 17:31' prior: 34317380! RONativeWidgetFactory is useful to create a ROMorph or ROVWVisual, depending on where the platform is running! !ROMorphWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 18:03'! forView: aView "Return an instance of ROMorph" ^ (ROPlatform current hostVisualElement on: aView) ! ! !ROMorphWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 11/23/2012 08:36'! forView: aView windowSized: aPoint "Return an instance of ROMorph" ^ (ROPlatform current hostVisualElement on: aView) extent: aPoint; openInWindow! ! !ROMorphWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 10/2/2012 20:25'! menuForAssociations: associations on: element "associations is a list of association following: #aSymbol -> [ :model | ... ] The block contains in the association is evaluated with the model provided by the element." | v | v := MenuMorph new. associations do: [ :assoc | v add: assoc key target: assoc value selector: #roValue: argument: element ]. v popUpInWorld.! ! !RONativeWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 4/23/2012 17:34'! current ^ self subclasses first! ! !RONativeWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 5/7/2012 18:38'! forView: aView "Return an instance of ROMorph of ROVWVisual without opening the window. " self subclassResponsibility! ! !RONativeWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 4/26/2012 17:07'! forView: aView windowSized: aPoint "Return an instance of ROMorph of ROVWVisual and open the window. This depends on which platform it is run" self subclassResponsibility! ! !RONativeWidgetFactory class methodsFor: 'public' stamp: 'AlexandreBergel 4/26/2012 17:09'! menuForAssociations: associations on: element "associations is a list of association following: #aSymbol -> [ :model | ... ] The block contains in the association is evaluated with the model provided by the element." self subclassResponsibility! ! !ROObject class methodsFor: 'instance creation' stamp: 'AlexandreBergel 7/24/2012 17:52'! new ^ self basicNew initialize! ! !ROObject methodsFor: 'initialize-release' stamp: 'AlexandreBergel 4/17/2012 20:19'! initialize! ! !ROPharoBenchmarks methodsFor: 'benchmarks' stamp: 'AlexandreBergel 9/14/2012 19:09'! display " self new display 461 503 1624 (MacBook Air) 2544 (by removing the generation of canvas in ROAbstractView>>drawOn: !!!!!!) 4817 => 4817 (Pharo 1.4, MacBookPro) " | view roView roMorph canvas | "Preparing" view := ROMondrianViewBuilder new. view shape rectangle size: 20. view nodes: (1 to: 20). view shape line. view edgesFrom: [ :i | i \\ 3 ]. view treeLayout. view applyLayout. roView := view raw. roMorph := ROMorph on: roView. canvas := FormCanvas on: Display. roMorph drawOn: canvas. "Profiling" ^ Time millisecondsToRun: [ 2000 timesRepeat: [ roMorph drawOn: canvas] ] .! ! !ROPlatform commentStamp: '' prior: 34317542! A ROPlatform enable to have different canvas rending. For example having athens, morphic or cairo. ! !ROMorphicPlatform class methodsFor: 'class initialization' stamp: 'AlexandreBergel 7/25/2012 15:56'! initialize "self initialize" | p | p := self new. ROPlatform add: p. ROPlatform setCurrent: p name! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:49'! canvasClass ^ ROPharoCanvas! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:51'! fontOrganizerClass ^ ROFontOrganizerMorphic! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 18:02'! hostVisualElement ^ ROMorph! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/25/2012 14:52'! htmlExporterClass ^ ROPharoHTMLExporter ! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/19/2012 21:41'! imageExporterClass ^ ROPharoImageExporter ! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:49'! name ^ 'morphic'! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'DR 1/22/2013 17:08'! newLine ^String cr! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'DR 1/16/2013 17:01'! randomClass ^ Random! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'VanessaPena 12/5/2012 16:22'! serializerClass ^ROFuelExporter! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/19/2012 21:39'! svgExporterClass ^ ROPharoSVGExporter ! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 17:12'! timeOrganizerClass ^ ROMorphicTimeOrganizer! ! !ROMorphicPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:52'! widgetFactory ^ ROMorphWidgetFactory! ! !ROPlatform class methodsFor: 'adding' stamp: 'AlexandreBergel 7/25/2012 15:38'! add: aPlatform aPlatform check. self platforms at: aPlatform name put: aPlatform ! ! !ROPlatform class methodsFor: 'public' stamp: 'DR 1/16/2013 18:58'! current current ifNil: [current := self subclasses first new]. ^ current! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 15:17'! names ^ nil! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 15:36'! numberOfPlatforms ^ self platforms size ! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 15:18'! platforms ^ platforms ifNil: [ platforms := Dictionary new ]! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 15:42'! removeNamed: aName self platforms removeKey: aName! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 7/25/2012 15:44'! removeNamed: aName ifAbsent: aBlock self platforms removeKey: aName ifAbsent: aBlock! ! !ROPlatform class methodsFor: 'public' stamp: 'AlexandreBergel 5/6/2013 19:02'! setCurrent: aPlatformName "aPlatformName is a string. Evaluate to get the possible value of aPlatformName: ROPlatform platforms keys" current := self platforms at: aPlatformName! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:32'! canvasClass ^ canvasClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 15:28'! canvasClass: aClass canvasClass := aClass ! ! !ROPlatform methodsFor: 'util' stamp: 'VanessaPena 12/2/2012 19:09'! check self assert: [ self name class == 'abc' class ] description: 'A platform name should be a string'. self assert: [ self canvasClass superclass == ROAbstractCanvas ] description: 'A platform canvas should be a subclass of ROAbstractCanvas'. self assert: [ self fontOrganizerClass superclass == ROFontOrganizer ] description: 'A platform font organizer should be a subclass of ROFontOrganizerMorphic'. self assert: [ self widgetFactory superclass == RONativeWidgetFactory ] description: 'A platform widget organizer should be a subclass of ROFontOrganizerMorphic'. self assert: [ self timeOrganizerClass superclass == ROTimeOrganizer ] description: 'A platform time organizer should be a subclass of ROTimeOrganizer'. self assert: [ self hostVisualElement notNil ] description: 'You need to provide a host visual element (a Morph or a Visual)'. ! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:50'! fontOrganizerClass ^ fontOrganizerClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 16:05'! fontOrganizerClass: aClass ^ fontOrganizerClass := aClass! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 17:55'! hostVisualElement ^ hostVisualElement! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 17:58'! hostVisualElement: visualElement "Typically a morph (Pharo) or a visual (VW)" hostVisualElement := visualElement! ! !ROPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/25/2012 14:52'! htmlExporterClass ^ htmlExporterClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'VanessaPena 11/25/2012 14:53'! htmlExporterClass: aClass htmlExporterClass := aClass ! ! !ROPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/19/2012 21:43'! imageExporterClass ^ imageExporterClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'VanessaPena 11/19/2012 21:44'! imageExporterClass: aClass imageExporterClass := aClass ! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:43'! name ^ name! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 15:35'! name: aString name := aString! ! !ROPlatform methodsFor: 'configuration' stamp: 'DR 1/22/2013 17:08'! newLine ^newLine ! ! !ROPlatform methodsFor: 'mutators' stamp: 'DR 1/22/2013 17:08'! newLine: aString newLine := aString! ! !ROPlatform methodsFor: 'configuration' stamp: 'DR 1/16/2013 17:01'! randomClass ^ randomClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'DR 1/16/2013 17:00'! randomClass: aClass ^ randomClass := aClass! ! !ROPlatform methodsFor: 'util' stamp: 'AlexandreBergel 7/25/2012 15:44'! remove ROPlatform removeNamed: self name ifAbsent: []! ! !ROPlatform methodsFor: 'configuration' stamp: 'VanessaPena 12/5/2012 16:21'! serializerClass ^serializerClass ! ! !ROPlatform methodsFor: 'mutators' stamp: 'VanessaPena 12/5/2012 16:21'! serializerClass: aClass serializerClass := aClass ! ! !ROPlatform methodsFor: 'configuration' stamp: 'VanessaPena 11/19/2012 21:37'! svgExporterClass ^ svgExporterClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'VanessaPena 11/19/2012 21:37'! svgExporterClass: aClass svgExporterClass := aClass ! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:50'! timeOrganizerClass ^ timeOrganizerClass! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 17:10'! timeOrganizerClass: aClass ^ timeOrganizerClass := aClass! ! !ROPlatform methodsFor: 'configuration' stamp: 'AlexandreBergel 7/25/2012 15:52'! widgetFactory ^ widgetFactory! ! !ROPlatform methodsFor: 'mutators' stamp: 'AlexandreBergel 7/25/2012 16:05'! widgetFactory: aClass ^ widgetFactory := aClass! ! !ROQuadTree class methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 4/24/2013 10:23'! withAll: aNodeCollection ^ self withAll: aNodeCollection origin: (aNodeCollection collect: [:e | e position x]) min @ (aNodeCollection collect: [:e | e position y]) min corner: (aNodeCollection collect: [:e | e position x]) max @ (aNodeCollection collect: [:e | e position y]) max! ! !ROQuadTree class methodsFor: 'as yet unclassified' stamp: 'MathieuDehouck 4/24/2013 13:36'! withAll: aNodeCollection origin: aPoint corner: anotherPoint | dx dy root | dx := anotherPoint x - aPoint x. dy := anotherPoint y - aPoint y. (dx closeTo: dy ) ifTrue: [ root := self new. root origin: aPoint; corner: anotherPoint. aNodeCollection do: [ :e | root add: e ]. ^ root ] . dx > dy ifTrue: [ ^ self withAll: aNodeCollection origin: aPoint corner: anotherPoint x @ (aPoint y + dx) ]. dy > dx ifTrue: [ ^ self withAll: aNodeCollection origin: aPoint corner: (aPoint x + dy) @ anotherPoint y ] .! ! !ROQuadTree methodsFor: 'adding' stamp: 'MathieuDehouck 4/24/2013 14:40'! add: aNode |n| leaf ifTrue: [ x isNil ifFalse: [ (x - aNode position x) abs + (y - aNode position y) abs < 0.01 ifTrue: [ self addChild: aNode ] ifFalse: [ n := node. x := nil. y := nil. node := nil. self addChild: aNode; addChild: n ] ] ifTrue: [ x := aNode position x. y := aNode position y. node := aNode ] ] ifFalse: [ self addChild: aNode ] ! ! !ROQuadTree methodsFor: 'adding' stamp: 'MathieuDehouck 4/24/2013 14:40'! addChild: aNode | sx sy new | sx := (origin x + corner x) / 2. sy := (origin y + corner y) / 2. leaf := false. aNode position x < sx ifTrue: [ aNode position y < sy ifTrue: [ (nodes at: 1) isNil ifTrue: [ new := ROQuadTree new. new origin: origin; corner: sx@sy. nodes at: 1 put: new ] . (nodes at: 1) add: aNode ] ifFalse: [ (nodes at: 3) isNil ifTrue: [ new := ROQuadTree new. new origin: origin x @ sy; corner: sx @ corner y. nodes at: 3 put: new ] . (nodes at: 3) add: aNode ] ] ifFalse: [ aNode position y < sy ifTrue: [ (nodes at: 2) isNil ifTrue: [ new := ROQuadTree new. new origin: sx @ origin y; corner: corner x @ sy. nodes at: 2 put: new ] . (nodes at: 2) add: aNode ] ifFalse: [ (nodes at: 4) isNil ifTrue: [ new := ROQuadTree new. new origin: sx @ sy; corner: corner. nodes at: 4 put: new ] . (nodes at: 4) add: aNode ] ] ! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:29'! charge ^ charge! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:29'! charge: anObject charge := anObject! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 10:41'! corner ^ corner! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 10:41'! corner: anObject corner := anObject! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:47'! cx ^ cx! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 12:07'! cx: aFloat cx := aFloat! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:48'! cy ^ cy! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 12:07'! cy: aFloat cy := aFloat! ! !ROQuadTree methodsFor: 'initialize-release' stamp: 'MathieuDehouck 4/24/2013 11:09'! initialize super initialize. leaf := true. nodes := Array new: 4. ! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:37'! leaf ^ leaf! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:49'! node ^ node! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 11:43'! nodes ^ nodes! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 10:41'! origin ^ origin! ! !ROQuadTree methodsFor: 'accessing' stamp: 'MathieuDehouck 4/24/2013 10:41'! origin: anObject origin := anObject! ! !ROSVGCanvas class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 11/20/2012 09:31'! onCamera: camera ^ self new camera: camera! ! !ROSVGCanvas class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 12/2/2012 15:24'! onCamera: camera onStream: aStream ^ self new camera: camera; stream: aStream ! ! !ROSVGCanvas methodsFor: 'svg' stamp: 'VanessaPena 11/19/2012 21:02'! addEnd stream nextPutAll: ''.! ! !ROSVGCanvas methodsFor: 'svg' stamp: 'AlexandreBergel 4/19/2013 15:50'! addStart stream nextPutAll: ''; nextPutAll: ROPlatform current newLine! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 1/31/2013 13:01'! camera ^camera! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 11/16/2012 18:17'! camera: aCamera camera := aCamera ! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:16'! drawString: aByteString at: aPoint "Render a string at a given position. No specification about the font is given. Use the default then" |p| p := camera virtualToRealPoint: aPoint + self stringOffset . stream nextPutAll: ''; nextPutAll: aByteString ; nextPutAll: ''; nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:16'! drawString: aByteString at: aPoint color: color "Render a colored string at a given position. No specification about the font is given. Use the default then" |p| p := camera virtualToRealPoint: aPoint + self stringOffset . stream nextPutAll: '' expandMacrosWith: (color red * 256) rounded with: (color green * 256) rounded with: (color blue * 256) rounded); nextPutAll: aByteString ; nextPutAll: ''; nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:17'! drawString: aByteString at: aPoint font: f color: color "Render a colored string at a given position using a particular font." |p| p := camera virtualToRealPoint: aPoint + self stringOffset . stream nextPutAll: '' expandMacrosWith: (color red * 256) rounded with: (color green * 256) rounded with: (color blue * 256) rounded); nextPutAll: aByteString; nextPutAll: ''; nextPutAll: ROPlatform current newLine. ! ! !ROSVGCanvas methodsFor: 'svg' stamp: 'DR 1/22/2013 17:17'! endGroup stream nextPutAll: ''; nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:17'! fillOval: aRectangle color: aColor borderWidth: aSmallInteger borderColor: aColor4 "Render an oval" |center w h extent r2 b| b := camera virtualToRealRectangle: aRectangle. center := b center. w := b width. h := b height. stream nextPutAll: '' expandMacrosWith: aSmallInteger); nextPutAll: ROPlatform current newLine. ! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:17'! fillRectangle: aRectangle color: fillColor "Render a rectangle" |b| b := camera virtualToRealRectangle: aRectangle. stream nextPutAll: '' expandMacrosWith: (fillColor red * 256) rounded with: (fillColor green * 256) rounded with: (fillColor blue * 256) rounded); nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:17'! frameAndFillRectangle: aRectangle fillColor: fillColor borderWidth: aSmallInteger borderColor: aColor "Render a framed rectangle. Implementation example: " |b| b := camera virtualToRealRectangle: aRectangle. stream nextPutAll: ''; nextPutAll: ROPlatform current newLine. ! ! !ROSVGCanvas methodsFor: 'initialize-release' stamp: 'VanessaPena 1/31/2013 18:43'! initialize stream := WriteStream on: String new. stringOffset := 0@10! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'DR 1/22/2013 17:18'! line: aPoint to: aPoint2 width: aSmallInteger color: aColor "Draw a line between two points" "Implementation example canvas line: (self virtualToRealPoint: aPoint) to: (self virtualToRealPoint: aPoint2) width: aSmallInteger color: aColor. " |p1 p2| p1 := camera virtualToRealPoint: aPoint. p2 := camera virtualToRealPoint: aPoint2. stream nextPutAll: '' expandMacrosWith: aSmallInteger ); nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'VanessaPena 11/20/2012 23:54'! paintBackground: aColor self fillRectangle: view encompassingRectangle color: aColor ! ! !ROSVGCanvas methodsFor: 'hooks' stamp: 'VanessaPena 11/20/2012 17:32'! paintImage: aForm at: aPoint "Render a bitmap on screen" "TODO" ! ! !ROSVGCanvas methodsFor: 'svg' stamp: 'DR 1/22/2013 17:18'! startGroup stream nextPutAll: ''; nextPutAll: ROPlatform current newLine.! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 11/16/2012 17:43'! stream ^stream ! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 12/2/2012 15:24'! stream: aStream stream := aStream ! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 11/20/2012 22:59'! stringOffset ^stringOffset! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'VanessaPena 11/13/2012 19:18'! view ^view! ! !ROSVGCanvas methodsFor: 'accesing' stamp: 'AlexandreBergel 8/9/2013 18:40'! view: aROView view := aROView. bounds := view camera virtualToRealRectangle: view encompassingRectangle! ! !ROShape commentStamp: 'AlexandreBergel 10/15/2012 13:21' prior: 34317711! A ROShape represents the graphical representation of an element. Decorator has a color, and they are link together. All the accessors in Mondrian's builder operates on the model. However, outside the builder, shapes accepts roassal elements. For example: -=-=-=-=-=-=-=-=-=-=-=-= testIfFillColor | nodes | view shape rectangle if: #odd fillColor: [ :model | model + 1]; if: #even fillColor: [ :model | model + 10]. nodes := view nodes: #(2 3 4 5 6). self assert: (nodes collect: [ :n | (n getShape: ROBox) colorFor: n]) = #(12 4 14 6 16) -=-=-=-=-=-=-=-=-=-=-=-= This piece of code works only in the test since a number is not a color. But it illustrates the point. Then fillColor: is defined as: -=-=-=-=-=-=-=-=-=-=-=-= ROMondrianBuilder>>fillColor: aBlockOrSymbol "aBlockOrSymbol expect to be evaluated against the model. It may either be a symbol or a one-arg block" shape color: [ :element | aBlockOrSymbol roValue: element model ] -=-=-=-=-=-=-=-=-=-=-=-= Something is left ugly, that I cannot easily remove: -=-=-=-=-=-=-=-=-=-=-=-= ROMondrianBuilder>>if: conditionBlock fillColor: colorBlock "If conditionBlock is evaluated at true, then colorBlock is used to set the color of the node. Both conditionBlock and colorBlock are evaluated with the model value of the node." | oldBlockOrValue | oldBlockOrValue := self fillColor ifNil: [ self defaultFillColor ]. ^self fillColor: [ :aModel | (conditionBlock roValue: aModel) ifTrue: [ colorBlock roValue: aModel ] ifFalse: [ "Having to create a new element is rather ugly. Ideally, the oldBlockOrValue has to be 'unwrapped' for the translation" oldBlockOrValue roValue: (ROElement on: aModel) ]]. -=-=-=-=-=-=-=-=-=-=-=-= Instance Variables color: colorCache: next: color - xxxxx colorCache - xxxxx next - xxxxx ! !ROAbstractLabel class methodsFor: 'public' stamp: 'JurajKubelka 5/29/2013 23:14'! defaultColor ^ Color black! ! !ROAbstractLabel class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:01'! isAbstract ^ self name = #ROAbstractLabel ! ! !ROAbstractLabel class methodsFor: 'public' stamp: 'JurajKubelka 5/29/2013 23:14'! text: aBlock ^ self new text: aBlock! ! !ROAbstractLabel methodsFor: 'visitor' stamp: 'VanessaPena 12/27/2012 13:18'! accept: visitor visitor visitAbstractLabel: self! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/29/2013 23:53'! clearTextCache "private" textCache := nil! ! !ROAbstractLabel methodsFor: 'configuration' stamp: 'AlexandreBergel 9/1/2013 11:41'! defaultInterlineSpace ^ 3! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'AlexandreBergel 9/20/2012 12:05'! drawOn: aCanvas for: aROElement self subclassResponsibility ! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:33'! extentFor: element ^(super extentFor: element) max: (self preferedExtentFor: element)! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 4/30/2013 15:16'! fontFor: anElement ^ self fontFor: anElement with: anElement view camera! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'TudorGirba 8/25/2013 09:41'! fontFor: anElement with: aCamera |fo| fo := ROPlatform current fontOrganizerClass. ^ fontSize isNil ifTrue: [ fo defaultFontForSize: fo defaultFontSize * (aCamera scale x) ] ifFalse: [ fo defaultFontForSize: ((self fontSizeFor: anElement) * (aCamera scale x)) ]. ! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'VanessaPena 12/23/2012 13:14'! fontSize: aBlockOrASymbolOrAnObject fontSize := aBlockOrASymbolOrAnObject.! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 4/2/2013 16:14'! fontSizeFor: anElement ^fontSize roValue: anElement! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/19/2013 00:58'! heightFor: aROElement "Return the height for the element" | tmpFont | tmpFont := self fontFor: aROElement with: aROElement view camera. ^ self heightFor: aROElement withFont: tmpFont! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/29/2013 23:33'! heightFor: aROElement withFont: aFont "Return the height for the element" | lineCount | lineCount := (self linesOf: aROElement) size. ^ ((aFont height asInteger + self interlineSpace) * lineCount) + (2 * textVerticalPadding) - self interlineSpace.! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/30/2013 00:10'! heightOfLineWithFont: font "Return the height of a string. It is expected the string is just one line." ^ font height asInteger + self interlineSpace! ! !ROAbstractLabel methodsFor: 'initialize' stamp: 'AlexandreBergel 9/1/2013 11:41'! initialize super initialize. text := #model. textHorizontalPadding := textVerticalPadding := 3. interlineSpace := self defaultInterlineSpace! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 11:41'! interlineSpace "Space between lines in a multi-line text" ^ interlineSpace! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'AlexandreBergel 9/1/2013 11:42'! interlineSpace: anInteger "Space between lines in a multi-line text" interlineSpace := anInteger! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/17/2013 21:44'! linesOf: aROElement ^ self textCache hasLines ifTrue: [ self textCache lines ] ifFalse: [ | str v | str := self textAdaptedFor: aROElement. v := self rawLinesOf: str. self textCache lines: v. v ]! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/17/2013 21:44'! linesOf: aROElement do: aOneArgBlock (self linesOf: aROElement) do: aOneArgBlock! ! !ROAbstractLabel methodsFor: 'events-accessing' stamp: 'TudorGirba 8/27/2013 11:54'! modelChanged: aROAbstractComponent self clearTextCache! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'AlexandreBergel 3/6/2013 15:36'! offsetWhenDrawing ^ ROPlatform current fontOrganizerClass offsetWhenDrawing! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'AlexandreBergel 9/20/2012 12:04'! preferedExtentFor: aROElement ^ (self widthFor: aROElement) @ (self heightFor: aROElement)! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/17/2013 21:38'! rawLinesOf: aString "Return a collection of strings got from aString." | ans | ans := OrderedCollection new. aString lineIndicesDo: [:start :endWithoutDelimiters :end | ans add: (aString copyFrom: start to: endWithoutDelimiters)]. ^ ans asArray! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'AlexandreBergel 9/20/2012 12:05'! text ^ text! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'AlexandreBergel 5/31/2013 18:12'! text: aOneArgBlockOrSymbolOrValue text := aOneArgBlockOrSymbolOrValue. self clearTextCache! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/17/2013 12:17'! textAdaptedFor: anElement "Return the text from anElement. All the tabulation are replaced" ^ self textCache hasAdaptedText ifTrue: [ self textCache adaptedText ] ifFalse: [ | v | v := (self textFor: anElement) copyReplaceAll: ' ' with: ' '. self textCache adaptedText: v. v ]! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/17/2013 11:24'! textCache ^ textCache ifNil: [ textCache := ROTextCache new ]! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/17/2013 11:33'! textFor: aROElement ^ self textCache hasText ifTrue: [ self textCache text ] ifFalse: [ | v | v := (text roValue: aROElement). (v class == 'abc' class) ifFalse: [ v := v printString ]. self textCache text: v. v ]! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/27/2013 20:38'! textHorizontalPadding: aSmallInteger textHorizontalPadding := aSmallInteger! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/27/2013 20:38'! textPadding: aSmallInteger self textVerticalPadding: aSmallInteger. self textHorizontalPadding: aSmallInteger.! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/30/2013 00:31'! textVerticalPadding ^ textVerticalPadding! ! !ROAbstractLabel methodsFor: 'accessing' stamp: 'JurajKubelka 5/27/2013 20:38'! textVerticalPadding: aSmallInteger textVerticalPadding := aSmallInteger! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/29/2013 22:56'! widthFor: aROElement "Return the width for the element" | cols tmpFont tmpWidth | tmpFont := self fontFor: aROElement with: aROElement view camera. cols := (self linesOf: aROElement) collect: [ :line | self widthOfLine: line withFont: tmpFont ]. tmpWidth := cols notEmpty ifTrue: [ cols inject: cols anyOne into: [ :s :e | s max: e ] ] ifFalse: [ 0 ]. ^ tmpWidth + (2 * textHorizontalPadding)! ! !ROAbstractLabel methodsFor: 'rendering' stamp: 'AlexandreBergel 8/29/2013 09:49'! widthOfLine: string withFont: aFont "Return the length of a string. It is expected the string is just one line." ^ ROPlatform current fontOrganizerClass widthOfString: string font: aFont! ! !ROCenteredLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/30/2013 00:19'! drawOn: aCanvas for: aROElement | runner tmpFont tmpColor tmpHeight | tmpFont := self fontFor: aROElement with: aCanvas camera. tmpHeight := 0 @ (self heightOfLineWithFont: tmpFont). tmpColor := self colorFor: aROElement. runner := aROElement absolutePosition + self offsetWhenDrawing + (0 @ (aROElement height - (self heightFor: aROElement withFont: tmpFont) /2) ) + (textHorizontalPadding @ textVerticalPadding). runner := runner asIntegerPoint. self linesOf: aROElement do: [ :line | | lineOffset | lineOffset := ( ( (aROElement width - (self widthOfLine: line withFont: tmpFont)) / 2 ) - textHorizontalPadding ) @ 0. aCanvas drawString: line at: (runner + lineOffset) font: tmpFont color: tmpColor. runner := runner + tmpHeight ]! ! !ROLabel class methodsFor: 'public' stamp: 'JurajKubelka 5/13/2013 14:13'! verticalText ^ self verticalText: #model! ! !ROLabel class methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2013 12:01'! verticalText: aBlock | answer | answer := self text: [:object | String streamContents: [ :stream | (aBlock roValue: object) asString do: [ :e | stream nextPut: e ] separatedBy: [ stream nextPut: Character cr ] ] ]. answer interlineSpace: -4. ^ answer! ! !ROLabel methodsFor: 'rendering' stamp: 'JurajKubelka 5/27/2013 20:57'! drawOn: aCanvas for: aROElement | runner tmpFont tmpColor tmpHeight | tmpFont := self fontFor: aROElement with: aCanvas camera. tmpHeight := 0 @ (self heightOfLineWithFont: tmpFont). tmpColor := self colorFor: aROElement. runner := aROElement absolutePosition + self offsetWhenDrawing + (textHorizontalPadding @ textVerticalPadding). self linesOf: aROElement do: [ :line | aCanvas drawString: line at: runner font: tmpFont color: tmpColor. runner := runner + tmpHeight ]! ! !ROAbstractBezierCurve class methodsFor: 'maths' stamp: 'MathieuDehouck 4/16/2013 10:54'! approximate: anArray in: anInteger | bary rightPart leftPart col | ( anInteger <= 0 ) ifTrue: [ ^ anArray ]. bary := self barycentersFor: anArray. col := (Array with: anArray) , bary. rightPart := col collect: [ :e | e first ]. leftPart := (col collect: [ :e | e last ]) reverse . ^ (self approximate: rightPart in: anInteger-1 ),(self approximate: leftPart in: anInteger-1)! ! !ROAbstractBezierCurve class methodsFor: 'maths' stamp: 'AlexandreBergel 8/27/2013 21:48'! barycentersFor: anArray | barycenters bary new | barycenters := OrderedCollection new. bary := OrderedCollection new. (1 to: anArray size - 1) do: [ :i | bary add: ((anArray at: i) + (anArray at: i+1) /2)]. barycenters add: bary. [ bary size > 1 ] whileTrue: [ new := OrderedCollection new. 1 to: bary size - 1 do: [ :i | new add: ((bary at: i) + (bary at: i+1) /2) ]. barycenters add: new. bary := new]. ^ barycenters! ! !ROAbstractBezierCurve class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:02'! isAbstract ^ self name = #ROAbstractBezierCurve ! ! !ROAbstractBezierCurve methodsFor: 'rendering' stamp: 'AlexandreBergel 4/18/2013 09:21'! drawOn: aCanvas for: anEdge | rawStartingPoint rawEndingPoint approx | rawEndingPoint := attachPoint startingPointOf: anEdge. rawStartingPoint := attachPoint endingPointOf: anEdge. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. approx := self lineSegmentsFor: anEdge. "We draw a line before each arrow" arrows do: [ :arrow | | arr | arr := arrow drawOn: aCanvas for: anEdge line: self. ]. "We draw a line after the arrow" 1 to: approx size -1 do: [ :i | aCanvas line: (approx at: i) to: (approx at: i+1) width: (strokeWidth roValue: anEdge) color: (color roValue: anEdge) ]! ! !ROAbstractBezierCurve methodsFor: 'initialize' stamp: 'MathieuDehouck 4/16/2013 10:55'! initialize super initialize. Recursion := 4! ! !ROAbstractBezierCurve methodsFor: 'hooks' stamp: 'MathieuDehouck 4/12/2013 10:24'! lineSegmentsFor: anEdge self subclassResponsibility ! ! !RORadialBezierCurve methodsFor: 'hooks' stamp: 'MathieuDehouck 4/16/2013 11:01'! lineSegmentsFor: anEdge | startingPoint endingPoint firstControl secondControl gap | startingPoint := anEdge from position. (startingPoint = (0@0)) ifTrue: [ ^ ROLine new lineSegmentsFor: anEdge ]. startingPoint := attachPoint startingPointOf: anEdge. endingPoint := attachPoint endingPointOf: anEdge. gap := endingPoint r - startingPoint r. (startingPoint r = 0) ifTrue: [ firstControl := Point radius: 0 + (gap/2) theta: endingPoint theta. ] ifFalse: [ firstControl := Point radius: startingPoint r + (gap/2) theta: startingPoint theta. ]. secondControl := Point radius: endingPoint r - (gap/2) theta: endingPoint theta. ^ self class approximate: (Array with: startingPoint with: firstControl with: secondControl with: endingPoint ) in: Recursion! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2013 13:24'! buildEdgesFromAssociations: associations inContainer: container ^ ROEdge buildEdgesFromAssociations: associations using: self inView: container! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 9/1/2013 13:24'! buildEdgesFromAssociations: associations inView: container ^ ROEdge buildEdgesFromAssociations: associations using: self inView: container! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 10/21/2013 14:16'! buildEdgesFromElement: element from: fromBlock toAll: toBlock ^ ROEdge buildEdgesFromElements: (Array with: element) from: fromBlock toAll: toBlock using: self! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 8/11/2013 22:06'! buildEdgesFromElements: elements from: fromBlock to: toBlock ^ ROEdge buildEdgesFromElements: elements from: fromBlock to: toBlock using: self! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 10/21/2013 14:09'! buildEdgesFromElements: elements from: fromBlock toAll: toBlock ^ ROEdge buildEdgesFromElements: elements from: fromBlock toAll: toBlock using: self! ! !ROAbstractLine class methodsFor: 'public' stamp: 'AlexandreBergel 4/14/2013 12:50'! elementFrom: fromElement to: toElement ^ self new elementFrom: fromElement to: toElement! ! !ROAbstractLine class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:01'! isAbstract ^ self name = #ROAbstractLine ! ! !ROAbstractLine class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:53'! isEdgeShape ^ true! ! !ROAbstractLine methodsFor: 'visitor' stamp: 'VanessaPena 1/31/2013 17:59'! accept: visitor visitor visitAbstractLine: self ! ! !ROAbstractLine methodsFor: 'accessing' stamp: 'AlexandreBergel 9/28/2012 09:47'! add: aROArrow arrows add: aROArrow! ! !ROAbstractLine methodsFor: 'arrowing' stamp: 'AlexandreBergel 9/28/2012 09:47'! add: aROArrow offset: aNumber aROArrow offset: aNumber. self add: aROArrow! ! !ROAbstractLine methodsFor: 'arrowing' stamp: 'AlexandreBergel 9/28/2012 09:47'! addBegining: aROArrow self add: aROArrow offset: 0! ! !ROAbstractLine methodsFor: 'accessing'! attachPoint ^ attachPoint! ! !ROAbstractLine methodsFor: 'accessing' stamp: 'AlexandreBergel 5/8/2013 16:09'! attachPoint: attach "attach is an object, instance of a subclass of ROAttachPoint" attachPoint := attach! ! !ROAbstractLine methodsFor: 'public' stamp: 'AlexandreBergel 8/11/2013 22:10'! buildEdgesFromElements: elements from: fromBlock to: toBlock ^ ROEdge buildEdgesFromElements: elements from: fromBlock to: toBlock using: self! ! !ROAbstractLine methodsFor: 'testing' stamp: 'miltonmamani 4/17/2013 15:22'! contains: aPoint for: anEdge "Return true if aPoint is contained in at least one of the line segments" | segments index | segments := self lineSegmentsFor: anEdge. segments isEmpty ifTrue: [ ^ false ]. index := segments first. segments allButFirst do: [ :p | (aPoint onLineFrom: index to: p within: 2) ifTrue: [ ^ true]. index := p. ]. ^ false! ! !ROAbstractLine methodsFor: 'hooks' stamp: 'AlexandreBergel 9/4/2012 12:53'! defaultShape ^ RONullShape new! ! !ROAbstractLine methodsFor: 'initialize' stamp: 'TudorGirba 7/29/2012 21:58'! defaultWidth ^ 1! ! !ROAbstractLine methodsFor: 'rendering' stamp: 'AlexandreBergel 11/28/2012 22:25'! drawOn: aCanvas for: anEdge | maxArrowSize unit startingPoint endingPoint rawStartingPoint rawEndingPoint | rawEndingPoint := (self startingPointOf: anEdge). rawStartingPoint := (self endingPointOf: anEdge). (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. "We draw a line before each arrow" arrows do: [ :arrow | | arr | arr := arrow drawOn: aCanvas for: anEdge line: self. aCanvas line: rawStartingPoint to: arr first width: (self widthFor: anEdge) color: (self colorFor: anEdge). rawStartingPoint := arr second. ]. "We draw a line after the arrow" aCanvas line: rawStartingPoint to: rawEndingPoint width: (self widthFor: anEdge) color: (self colorFor: anEdge). ! ! !ROAbstractLine methodsFor: 'public' stamp: 'miltonmamani 4/16/2013 17:55'! elementFrom: fromElement to: toElement "Easy way to create element from a shape" ^ (ROEdge from: fromElement to: toElement) + self! ! !ROAbstractLine methodsFor: 'public' stamp: 'AlexandreBergel 4/7/2013 01:02'! elementOn: object "Easy way to create element from a shape" ^ (ROEdge on: object) + self! ! !ROAbstractLine methodsFor: 'computing attach point' stamp: 'AlexandreBergel 12/11/2012 05:20'! endingPointOf: anEdge ^ attachPoint endingPointOf: anEdge! ! !ROAbstractLine methodsFor: 'testing' stamp: 'AlexandreBergel 9/28/2012 09:47'! hasArrow "True if some arrows have been added" ^ arrows isNil or: [ arrows notEmpty ]! ! !ROAbstractLine methodsFor: 'initialize' stamp: 'AlexandreBergel 10/17/2012 08:40'! initialize super initialize. attachPoint := ROShorterDistanceAttachPoint instance. strokeWidth := self defaultWidth. arrows := OrderedCollection new! ! !ROAbstractLine methodsFor: 'hooks' stamp: 'AlexandreBergel 8/23/2012 22:41'! lineSegmentsFor: anEdge self subclassResponsibility ! ! !ROAbstractLine methodsFor: 'arrowing' stamp: 'AlexandreBergel 9/28/2012 09:47'! numberOfArrows "Answer the number of arrows the edge contains" ^ arrows size ! ! !ROAbstractLine methodsFor: 'computing attach point' stamp: 'AlexandreBergel 12/11/2012 05:17'! startingPointOf: anEdge ^ attachPoint startingPointOf: anEdge! ! !ROAbstractLine methodsFor: 'accessing' stamp: 'AlexandreBergel 10/17/2012 08:40'! width ^ strokeWidth! ! !ROAbstractLine methodsFor: 'accessing' stamp: 'AlexandreBergel 10/17/2012 08:40'! width: aNumber strokeWidth := aNumber! ! !ROAbstractLine methodsFor: 'accessing' stamp: 'AlexandreBergel 10/14/2012 19:09'! widthFor: anEdge ^ self width roValue: anEdge! ! !ROBSplineLine commentStamp: '' prior: 34320080! A ROBSplineLine is a bspline with control points. This work has been done by Hernan Fierro, at the University of Chile. The work has been inspired from "Hierarchical Edge Bundles" www.win.tue.nl/~dholten/papers/bundles_infovis.pdf‎ alpha - xxxxx cachePoints - xxxxx cpoints - xxxxx customCpoints - xxxxx discoveryFunction - xxxxx knots - xxxxx straightcpoints - xxxxx ! !ROBSplineLine methodsFor: 'basis' stamp: 'HernanFierro 5/30/2013 22:19'! Ct: t "Calculates the corresponding point in the spline given parameter t inside [0,1]" | sum p n | sum := 0@0. p := self p. n := straightcpoints size. 1 to: n do: [ :i | sum := sum + ((straightcpoints at: i ) * (self recursionFori: i p: p t:t ) ). ]. ^sum! ! !ROBSplineLine methodsFor: 'configuring' stamp: 'AlexandreBergel 9/23/2013 18:55'! addControlElement: aROElement "Adds a Control Point and updates the straightness" "aROElement correspond to a location on screen, a 2D point" self customCpoints add: aROElement! ! !ROBSplineLine methodsFor: 'configuring' stamp: 'AlexandreBergel 9/23/2013 18:25'! addControlPoint: aPoint "Adds a Control Point and updates the straightness" "aPoint correspond to a location on screen, a 2D point" cpoints addLast: aPoint. ! ! !ROBSplineLine methodsFor: 'accessing' stamp: 'AlexandreBergel 9/23/2013 18:27'! alpha "Return the value that correspond to the attraction the line has for the control points" ^ alpha! ! !ROBSplineLine methodsFor: 'configuring' stamp: 'AlexandreBergel 9/23/2013 18:27'! alpha: aFloat "Set the value that correspondsto the attraction the line has for the control points" "aFloat = 0, control points have no attraction. The line is straight" alpha := aFloat. ! ! !ROBSplineLine methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 00:34'! controlPoints ^ cpoints! ! !ROBSplineLine methodsFor: 'accessing' stamp: 'HernanFierro 7/23/2013 02:34'! customCpoints "comment stating purpose of message" ^customCpoints.! ! !ROBSplineLine methodsFor: 'hooks' stamp: 'HernanFierro 7/9/2013 17:19'! defaultDivision ^ 30! ! !ROBSplineLine methodsFor: 'rendering' stamp: 'AlexandreBergel 9/14/2013 00:35'! drawOn: aCanvas for: anEdge | rawStartingPoint rawEndingPoint approx | rawEndingPoint := attachPoint startingPointOf: anEdge. rawStartingPoint := attachPoint endingPointOf: anEdge. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. approx := self lineSegmentsFor: anEdge. "We draw a line after the arrow" 1 to: approx size - 1 do: [ :i | aCanvas line: (approx at: i) to: (approx at: i+1) width: (strokeWidth roValue: anEdge) color: (color roValue: anEdge) ]! ! !ROBSplineLine methodsFor: 'basis' stamp: 'HernanFierro 5/30/2013 15:24'! getPoints: npoints "Returns an array of points" |step array| step := 0.9999 / npoints. array := (0 to: npoints ) collect: [ :i | self Ct: (step * i). ]. ^array! ! !ROBSplineLine methodsFor: 'initialize' stamp: 'HernanFierro 7/23/2013 02:33'! initialize super initialize. knots := OrderedCollection new. cpoints := OrderedCollection new. straightcpoints := OrderedCollection new. alpha := 0.8. discoveryFunction := nil. cachePoints := nil. customCpoints := OrderedCollection new.! ! !ROBSplineLine methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 00:35'! knots ^ knots! ! !ROBSplineLine methodsFor: 'hooks' stamp: 'HernanFierro 7/23/2013 02:29'! lineSegmentsFor: anEdge | v | (anEdge attributes includesKey: #cacheBSpline) ifTrue: [ ^ anEdge attributes at: #cacheBSpline ]. self setLCAControlPointsFor: anEdge. self updateStraightness . self updateKnots. v := self getPoints: self defaultDivision. anEdge attributes at: #cacheBSpline put: v. ^ v ! ! !ROBSplineLine methodsFor: 'basis' stamp: 'AlexandreBergel 9/14/2013 00:35'! p "comment stating purpose of message" ^ (knots size) - (cpoints size) - 1.! ! !ROBSplineLine methodsFor: 'basis' stamp: 'AlexandreBergel 9/14/2013 00:35'! recursionBaseFori: i t: t "comment stating purpose of message" | min max | min := knots at: i. max := knots at: (i + 1). ^ (min <= t and: [ t < max ]) ifTrue: [ 1] ifFalse: [ 0 ]! ! !ROBSplineLine methodsFor: 'basis' stamp: 'AlexandreBergel 9/14/2013 00:35'! recursionFori: i p: p t:t "comment stating purpose of message" | recursion1 recursion2 coeff1 coeff2 sentence1 sentence2 | (p == 0) ifTrue: [^self recursionBaseFori: i t:t]. recursion1 := self recursionFori: i p: (p - 1) t:t. (recursion1 == 0) ifTrue: [ sentence1 := 0 ] ifFalse:[ coeff1 := (t - (knots at: i)) / ((knots at: (i + p)) - ( knots at: i)) . sentence1 := coeff1 * recursion1. ]. recursion2 := self recursionFori: (i + 1) p: (p - 1) t:t. (recursion2 == 0) ifTrue:[ sentence2 :=0. ] ifFalse:[ coeff2 := ((knots at: (i + p + 1)) - t) / ((knots at: (i + p + 1)) - (knots at: (i + 1) )). sentence2 := recursion2 * coeff2. ]. ^ sentence1 + sentence2! ! !ROBSplineLine methodsFor: 'rendering' stamp: 'AlexandreBergel 9/23/2013 18:13'! resetView: anEdge self resetView: anEdge from forEdge: anEdge. self resetView: anEdge to forEdge: anEdge.! ! !ROBSplineLine methodsFor: 'rendering' stamp: 'AlexandreBergel 9/23/2013 18:12'! resetView: anElement forEdge: anEdge "comment stating purpose of message" anElement on: ROElementTranslated do: [ :item | anEdge attributes removeKey: #cacheBSpline ifAbsent: [ ] ]. anElement on: ROElementTranslated do: [ :item | anEdge attributes removeKey: #cacheBSpline ifAbsent: [ ] ].! ! !ROBSplineLine methodsFor: 'configuring' stamp: 'AlexandreBergel 9/23/2013 18:55'! setDiscovery: ablock "Sets a discovery function that returns the element parent of a given element. If there's no parent, the function should return nil" "The block has to return an ROElement" discoveryFunction := ablock.! ! !ROBSplineLine methodsFor: 'basis' stamp: 'AlexandreBergel 9/30/2013 18:44'! setLCAControlPointsFor: anEdge "Finds LCA and defines the corresponding control points" |rawEndingPoint rawStartingPoint eStart eFinish view startHierarchy finishHierarchy LCA found aux| view := anEdge view. cpoints := OrderedCollection new. rawEndingPoint := attachPoint endingPointOf: anEdge. rawStartingPoint := attachPoint startingPointOf: anEdge. "Bind the event" (anEdge attributes includesKey: #firstTime) ifFalse: [ self resetView: anEdge]. discoveryFunction isNil ifTrue: [ self useCustomPoints: anEdge. ^ nil ]. self addControlPoint: rawStartingPoint. eStart := (anEdge from) model. eFinish := (anEdge to) model. startHierarchy := OrderedCollection new. finishHierarchy := OrderedCollection new. aux := discoveryFunction value: eStart. [ aux notNil and: [ (view elementFromModel: aux) notNil ] ] whileTrue: [ (aux isKindOf: ROElement) ifTrue: [ self error: 'discovery function not properly defined' ]. startHierarchy addLast: aux. aux:=discoveryFunction value: aux. ]. aux := discoveryFunction value: eFinish. [ aux notNil and: [ (view elementFromModel: aux) notNil ] ] whileTrue: [ (aux isKindOf: ROElement) ifTrue: [ self error: 'discovery function not properly defined' ]. finishHierarchy addLast: aux. aux:=discoveryFunction value: aux. ]. LCA := finishHierarchy detect:[ :cls | startHierarchy includes: cls]. (LCA == nil) ifFalse:[ |reversedCollection| (anEdge attributes includesKey: #firstTime) ifFalse: [ self resetView: (view elementFromModel: LCA) forEdge:anEdge]. found := false. startHierarchy do: [ :cls | found ifFalse: [ (cls == LCA) ifTrue:[ found := true ] ifFalse:[ (anEdge attributes includesKey: #firstTime) ifFalse: [ self resetView: (view elementFromModel: cls) forEdge:anEdge]. self addControlPoint: ((view elementFromModel: cls) position)]. ]. ]. reversedCollection := OrderedCollection new. found := false. finishHierarchy do: [ :cls | found ifFalse: [ (cls == LCA) ifTrue:[ found := true ] ifFalse:[ (anEdge attributes includesKey: #firstTime) ifFalse: [ self resetView: (view elementFromModel: cls) forEdge:anEdge]. reversedCollection addFirst: ((view elementFromModel: cls) position)]. ]. ]. self addControlPoint: ((view elementFromModel: LCA) position). reversedCollection do:[ :apoint | self addControlPoint: apoint]. ]. self addControlPoint: rawEndingPoint. (anEdge attributes includesKey: #firstTime) ifFalse: [ anEdge attributes at: #firstTime put: 1 ]. ! ! !ROBSplineLine methodsFor: 'accessing' stamp: 'HernanFierro 5/30/2013 22:21'! straightControlPoints ^straightcpoints.! ! !ROBSplineLine methodsFor: 'basis' stamp: 'HernanFierro 5/31/2013 01:56'! updateKnots "Knots vector is recreated, for four or more points, the bspline will be cubic" |uniform paso| knots := OrderedCollection new. ((cpoints size) = 2) ifTrue:[ knots add: 0. knots add: 0. knots add: 1. knots add: 1. ]. ((cpoints size) = 3) ifTrue:[ knots add: 0. knots add: 0. knots add: 0. knots add: 1. knots add: 1. knots add: 1. ]. ((cpoints size) > 3) ifTrue:[ uniform := (cpoints size) - 4. knots add: 0. knots add: 0. knots add: 0. knots add: 0. paso := 1/(uniform +1). (1 to: uniform) do: [ :i | knots add: (paso*i). ]. knots add: 1. knots add: 1. knots add: 1. knots add: 1. ]. ! ! !ROBSplineLine methodsFor: 'basis' stamp: 'HernanFierro 5/31/2013 01:56'! updateStraightness "Recalculates Straightened points" | P1 PN Size | Size := cpoints size. Size > 2 ifTrue: [ PN := cpoints at: Size. P1 := cpoints at: 1. straightcpoints := OrderedCollection new. 1 to: Size do: [ :i | | cp point | cp := cpoints at: i. point := cp * alpha. point := point + ((P1 + ((PN - P1) * ((i - 1)/ (Size - 1))) )* (1 - alpha)). straightcpoints add: point ] ] ifFalse: [ straightcpoints := cpoints ]. ! ! !ROBSplineLine methodsFor: 'basis' stamp: 'HernanFierro 7/23/2013 02:47'! useCustomPoints: anEdge "comment stating purpose of message" | rawStartingPoint rawEndingPoint| rawEndingPoint := attachPoint endingPointOf: anEdge. rawStartingPoint := attachPoint startingPointOf: anEdge. self addControlPoint: rawStartingPoint. customCpoints do: [ :it | (anEdge attributes includesKey: #firstTime) ifFalse: [ self resetView: it forEdge:anEdge]. self addControlPoint: (it position) ]. self addControlPoint: rawEndingPoint. (anEdge attributes includesKey: #firstTime) ifFalse: [ anEdge attributes at: #firstTime put: 1 ].! ! !ROLine class methodsFor: 'public' stamp: 'AlexandreBergel 4/7/2013 01:21'! arrowed "Return an arrowed line" ^ ROLine new add: (ROArrow new offset: 0)! ! !ROLine methodsFor: 'rendering' stamp: 'AlexandreBergel 5/14/2013 19:24'! drawOn: aCanvas for: anEdge | rawStartingPoint rawEndingPoint | rawEndingPoint := attachPoint startingPointOf: anEdge. rawStartingPoint := attachPoint endingPointOf: anEdge. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. "We draw a line before each arrow" arrows do: [ :arrow | | arr | arr := arrow drawOn: aCanvas for: anEdge line: self. aCanvas line: rawStartingPoint to: arr first width: (self widthFor: anEdge) color: (self colorFor: anEdge). rawStartingPoint := arr second. ]. "We draw a line after the arrow" aCanvas line: rawStartingPoint to: rawEndingPoint width: (self widthFor: anEdge) color: (self colorFor: anEdge). ! ! !ROLine methodsFor: 'utility' stamp: 'AlexandreBergel 8/19/2012 21:01'! lineSegmentsFor: anEdge | rawStartingPoint rawEndingPoint | rawStartingPoint := attachPoint startingPointOf: anEdge. rawEndingPoint := attachPoint endingPointOf: anEdge. ^ Array with: rawStartingPoint with: rawEndingPoint! ! !ROLine methodsFor: 'enumerating' stamp: 'AlexandreBergel 8/20/2012 10:42'! lineSegmentsFor: anEdge do: aTwoArgBlock | segments p | segments := self lineSegmentsFor: anEdge. p := segments first. segments allButFirst do: [ :point| aTwoArgBlock value: p value: point. p := point ]! ! !ROLine methodsFor: 'utility' stamp: 'AlexandreBergel 6/12/2012 15:24'! unitFor: anEdge | vector toPoint fromPoint u unit | fromPoint := self startingPointOf: anEdge. toPoint := self endingPointOf: anEdge. vector := toPoint - fromPoint. u := vector normal. unit := vector / vector r. ^ unit! ! !ROOrthoHorizontalLineShape methodsFor: 'rendering' stamp: 'JurajKubelka 5/21/2013 21:18'! drawOn: aCanvas for: anEdge | rawStartingPoint rawEndingPoint edgeBound midx w c rawEndingPointOriginal rawStartingPointOriginal | rawEndingPoint := attachPoint startingPointOf: anEdge. rawEndingPointOriginal := rawEndingPoint. rawStartingPoint := attachPoint endingPointOf: anEdge. rawStartingPointOriginal := rawStartingPoint. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. "We draw a line before each arrow" arrows do: [ :arrow | | arr | arr := arrow drawOn: aCanvas for: anEdge line: self. "aCanvas line: rawStartingPoint to: arr first width: (width roValue: anEdge) color: color." (arrow offset = 0) ifTrue: [ rawStartingPoint := arr second ] ifFalse: [ rawEndingPoint := arr first ]. ]. "-------- " edgeBound := rawStartingPointOriginal corner: rawEndingPointOriginal. midx := ((edgeBound corner x - edgeBound origin x) / 2) asInteger + edgeBound origin x. w := strokeWidth roValue: anEdge. c := color roValue: anEdge. aCanvas line: rawStartingPoint to: (midx @ edgeBound origin y) width: w color: c. aCanvas line: (midx @ edgeBound origin y) to: (midx @ edgeBound corner y) width: w color: c. aCanvas line: (midx @ edgeBound corner y) to: rawEndingPoint width: w color: c.! ! !ROOrthoHorizontalLineShape methodsFor: 'rendering' stamp: 'AlexandreBergel 8/19/2012 19:06'! lineSegmentsFor: anEdge | rawEndingPoint rawStartingPoint edgeBound midx | rawStartingPoint := attachPoint startingPointOf: anEdge. rawEndingPoint := attachPoint endingPointOf: anEdge. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ #() ]. edgeBound := rawStartingPoint corner: rawEndingPoint. midx := ((edgeBound corner x - edgeBound origin x) / 2) asInteger + edgeBound origin x. ^ Array with: rawStartingPoint with: (midx @ edgeBound origin y) with: (midx @ edgeBound corner y) with: rawEndingPoint ! ! !ROOrthoVerticalLineShape methodsFor: 'rendering' stamp: 'JurajKubelka 5/21/2013 21:15'! drawOn: aCanvas for: anEdge | rawStartingPoint rawEndingPoint edgeBound midy w c rawEndingPointOriginal rawStartingPointOriginal | rawEndingPoint := attachPoint startingPointOf: anEdge. rawEndingPointOriginal := rawEndingPoint. rawStartingPoint := attachPoint endingPointOf: anEdge. rawStartingPointOriginal := rawStartingPoint. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ self ]. "We draw a line before each arrow" arrows do: [ :arrow | | arr | arr := arrow drawOn: aCanvas for: anEdge line: self. "aCanvas line: rawStartingPoint to: arr first width: (width roValue: anEdge) color: color." (arrow offset = 0) ifTrue: [ rawStartingPoint := arr second ] ifFalse: [ rawEndingPoint := arr first ]. ]. "We draw a line after the arrow" " aCanvas line: rawStartingPoint to: rawEndingPoint width: (width roValue: anEdge) color: (color roValue: anEdge). " "-------- " edgeBound := rawStartingPointOriginal corner: rawEndingPointOriginal. midy := ((edgeBound corner y - edgeBound origin y) / 2) asInteger + edgeBound origin y. w := strokeWidth roValue: anEdge. c := color roValue: anEdge. aCanvas line: rawStartingPoint to: (edgeBound origin x @ midy) width: w color: c. aCanvas line: (edgeBound origin x @ midy) to: (edgeBound corner x @ midy) width: w color: c. aCanvas line: (edgeBound corner x @ midy) to: rawEndingPoint width: w color: c.! ! !ROOrthoVerticalLineShape methodsFor: 'rendering' stamp: 'AlexandreBergel 8/19/2012 19:14'! lineSegmentsFor: anEdge | rawEndingPoint rawStartingPoint edgeBound midy | rawStartingPoint := attachPoint startingPointOf: anEdge. rawEndingPoint := attachPoint endingPointOf: anEdge. (rawStartingPoint = rawEndingPoint) ifTrue: [ ^ #() ]. edgeBound := rawStartingPoint corner: rawEndingPoint. midy := ((edgeBound corner y - edgeBound origin y) / 2) asInteger + edgeBound origin y. ^ Array with: rawStartingPoint with: (edgeBound origin x @ midy) with: (edgeBound corner x @ midy) with: rawEndingPoint ! ! !ROBorder commentStamp: '' prior: 34320515! A ROBorder defines a border to be added to an element. Instance Variables width: Number width - Width of the border! !ROBorder class methodsFor: 'public'! defaultColor ^ Color black! ! !ROBorder methodsFor: 'visitor' stamp: 'VanessaPena 12/27/2012 13:19'! accept: visitor visitor visitBorder: self! ! !ROBorder methodsFor: 'rendering' stamp: 'AlexandreBergel 7/10/2013 10:33'! drawOn: aCanvas for: aROElement | topLeft extent c strokeWidthComputed | topLeft := aROElement absolutePosition. extent := aROElement extent. c := color roValue: aROElement. strokeWidthComputed := strokeWidth roValue: aROElement. aCanvas line: topLeft to: topLeft + (extent x @ 0) width: strokeWidthComputed color: c. aCanvas line: topLeft + (extent x @ 0) to: topLeft + extent width: strokeWidthComputed color: c. aCanvas line: topLeft + extent to: topLeft + (0 @ extent y) width: strokeWidthComputed color: c. aCanvas line: topLeft + (0 @ extent y) to: topLeft width: strokeWidthComputed color: c. ! ! !ROBorder methodsFor: 'initialization' stamp: 'AlexandreBergel 10/17/2012 08:41'! initialize super initialize. strokeWidth := 1. color := self class defaultColor! ! !ROBorder methodsFor: 'accessing' stamp: 'AlexandreBergel 7/10/2013 10:36'! strokeWidth: aNumberOrABlockOrASymbol strokeWidth := aNumberOrABlockOrASymbol! ! !ROInnerBorder commentStamp: '' prior: 34320691! A ROInnerBorder is a specialization of ROBorder which is drawn inside the shape Roberto Minelli @ REVEAL, Lugano (CH) roberto.minelli@usi.ch! !ROInnerBorder methodsFor: 'rendering' stamp: 'RobertoMinelli 10/11/2013 09:01'! drawOn: aCanvas for: aROElement | topLeft extent c strokeWidthComputed halfStrokeWidth | topLeft := aROElement absolutePosition. extent := aROElement extent. c := color roValue: aROElement. strokeWidthComputed := self evenStrokeWidthFor: aROElement. (strokeWidthComputed = 1) ifTrue: [ "If the stroke width is 1, I cannot split a pixel" super drawOn: aCanvas for: aROElement ] ifFalse: [ halfStrokeWidth := strokeWidthComputed / 2. topLeft := topLeft + halfStrokeWidth. aCanvas line: topLeft to: topLeft + (extent x - strokeWidthComputed @ 0) width: strokeWidthComputed color: c. aCanvas line: topLeft + (extent x - strokeWidthComputed @ 0) to: topLeft + extent - strokeWidthComputed width: strokeWidthComputed color: c. aCanvas line: topLeft + extent - strokeWidthComputed to: topLeft + (strokeWidthComputed @ extent y - strokeWidthComputed) width: strokeWidthComputed color: c. aCanvas line: topLeft + (strokeWidthComputed @ extent y - strokeWidthComputed) to: topLeft width: strokeWidthComputed color: c. ]. ! ! !ROInnerBorder methodsFor: 'rendering' stamp: 'RobertoMinelli 10/11/2013 12:05'! evenStrokeWidthFor: aROElement | computedWidth | computedWidth := strokeWidth roValue: aROElement. ((computedWidth > 1) and: [ (computedWidth \\ 2) = 1]) ifTrue: [ computedWidth := computedWidth + 1 ]. ^ computedWidth.! ! !ROBox commentStamp: '' prior: 34320880! A ROBox draws a box Instance Variables borderColor: borderColorCache: borderWidth: borderWidthCache: borderColor - could be a block, a color or a normalizer. Used to determine the color of the element being painted borderColorCache - used as a cache borderWidth - a block or a number that represent the border width. borderWidthCache - cache of the width ! !ROBox class methodsFor: 'defaults'! defaultColor ^ Color veryLightGray! ! !ROBox methodsFor: 'visitor' stamp: 'VanessaPena 12/27/2012 13:19'! accept: visitor visitor visitBox: self! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 9/14/2013 11:42'! borderColor "Color of a box is set by setting a color, a block or a symbol, which is evaluated against the model of the element" "Return a color, a block or a symbol" ^ borderColor! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 9/14/2013 11:42'! borderColor: aBlockOrSymbolOrObject "Color of a box is set by setting a color, a block or a symbol, which is evaluated against the model of the element" borderColor := aBlockOrSymbolOrObject! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 10/17/2012 12:16'! borderColorFor: element ^ borderColor roValue: element! ! !ROBox methodsFor: 'rendering'! borderWidth ^ borderWidth! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 10/17/2012 12:16'! borderWidth: aBlockOrSymbolOrObject borderWidth := aBlockOrSymbolOrObject.! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 10/17/2012 12:16'! borderWidthFor: element ^ borderWidth roValue: element! ! !ROBox methodsFor: 'initialize' stamp: 'AlexandreBergel 9/14/2013 00:12'! defaultBorderColor ^ Color black! ! !ROBox methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 12:07'! drawOn: aCanvas for: aROElement aCanvas frameAndFillRectangle: (self absoluteBoundsFor: aROElement) fillColor: (self colorFor: aROElement) borderWidth: (self borderWidthFor: aROElement) borderColor: (self borderColorFor: aROElement)! ! !ROBox methodsFor: 'initialize' stamp: 'AlexandreBergel 9/14/2013 00:12'! initialize super initialize. borderColor := self defaultBorderColor. borderWidth := 0! ! !RODiamond methodsFor: 'accessing' stamp: 'AlexandreBergel 8/9/2013 19:04'! borderColor ^ borderColor ! ! !RODiamond methodsFor: 'accessing' stamp: 'AlexandreBergel 8/9/2013 19:04'! borderColor: aBlockOrSymbolOrObject borderColor := aBlockOrSymbolOrObject.! ! !RODiamond methodsFor: 'accessing' stamp: 'AlexandreBergel 8/9/2013 19:05'! borderWidth ^ borderWidth ! ! !RODiamond methodsFor: 'accessing' stamp: 'AlexandreBergel 8/9/2013 19:05'! borderWidth: anInteger borderWidth := anInteger. ! ! !RODiamond methodsFor: 'rendering' stamp: 'AlexandreBergel 8/9/2013 19:08'! drawOn: aCanvas for: aROElement | b w bc | b := self absoluteBoundsFor: aROElement. w := borderWidth roValue: aROElement. bc := borderColor roValue: aROElement. aCanvas line: b topCenter to: b rightCenter width: w color: bc. aCanvas line: b rightCenter to: b bottomCenter width: w color: bc. aCanvas line: b bottomCenter to: b leftCenter width: w color: bc. aCanvas line: b leftCenter to: b topCenter width: w color: bc. ! ! !RODiamond methodsFor: 'initialize' stamp: 'AlexandreBergel 8/9/2013 19:05'! initialize super initialize. borderWidth := 1. borderColor := Color black.! ! !ROEllipse commentStamp: '' prior: 34321375! A ROCircle draws a circle! !ROEllipse class methodsFor: 'public'! color: aColor ^ self new color: aColor! ! !ROEllipse class methodsFor: 'defaults'! defaultColor ^ Color veryLightGray! ! !ROEllipse methodsFor: 'visitor' stamp: 'VanessaPena 12/27/2012 13:20'! accept: visitor visitor visitCircle: self! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 10/17/2012 11:55'! borderColor ^ borderColor ! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 10/15/2012 13:12'! borderColor: aBlockOrSymbolOrObject borderColor := aBlockOrSymbolOrObject.! ! !ROEllipse methodsFor: 'rendering' stamp: 'BenComan 9/16/2012 20:38'! borderOnly self borderWidth: 1. self borderColor: Color black. self color: Color transparent. ! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 8/9/2013 19:04'! borderWidth ^ borderWidth ! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 8/9/2013 19:13'! borderWidth: anInteger borderWidth := anInteger ! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 12:07'! drawOn: aCanvas for: aROElement aCanvas fillOval: (self absoluteBoundsFor: aROElement) color: (color roValue: aROElement) borderWidth: (borderWidth roValue: aROElement) borderColor: (borderColor roValue: aROElement)! ! !ROEllipse methodsFor: 'rendering' stamp: 'AlexandreBergel 8/9/2013 19:05'! initialize super initialize. borderWidth := 0. borderColor := Color black.! ! !ROImage methodsFor: 'rendering' stamp: 'AlexandreBergel 10/22/2013 01:12'! drawOn: aCanvas for: aROElement aCanvas paintImage: (form roValue: aROElement) at: (self absoluteBoundsFor: aROElement) topLeft ! ! !ROImage methodsFor: 'accessing'! form ^ form! ! !ROImage methodsFor: 'accessing'! form: aFormBlockOrObject form := aFormBlockOrObject! ! !ROImage methodsFor: 'accessing' stamp: 'AlexandreBergel 10/22/2013 01:17'! height self form isNil ifTrue: [ ^ 5 ]. ^ self form height! ! !ROImage methodsFor: 'initialize' stamp: 'AlexandreBergel 10/22/2013 01:22'! initialize super initialize. width := [ :el | self form isNil ifTrue: [ 5 ] ifFalse: [ self form width ] ]. height := [ :el | self form isNil ifTrue: [ 5 ] ifFalse: [ self form height ] ].! ! !ROImage methodsFor: 'hooks'! installedOn: element "This method is meant to be overriden in case a special treatment has to be realized on the element" | p | super installedOn: element. p := (form roValue: element) extent. element extent < p ifTrue: [ element extent: p ]. ! ! !ROImage methodsFor: 'accessing' stamp: 'AlexandreBergel 5/29/2012 10:22'! preferedExtentFor: element ^ (form roValue: element) extent! ! !ROImage methodsFor: 'accessing' stamp: 'AlexandreBergel 10/22/2013 01:17'! width self form isNil ifTrue: [ ^ 5 ]. ^ self form width! ! !RONullShape commentStamp: '' prior: 34321454! A RONullShape is the terminator of the shape chain. A new element will have an instance of null shape in it.! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 12:02'! addLast: aShape ^ aShape! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 12:03'! addLast: aShape in: elementToAdd elementToAdd next: aShape! ! !RONullShape methodsFor: 'copying' stamp: 'AlexandreBergel 9/1/2013 11:59'! chainedCopy ^ self copy! ! !RONullShape methodsFor: 'rendering' stamp: 'AlexandreBergel 9/14/2012 19:03'! chainedDrawOn: aCanvas for: aROElement self drawOn: aCanvas for: aROElement ! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/22/2012 08:45'! change: aShapeClass for: aShape ^ self ! ! !RONullShape methodsFor: 'hooks' stamp: 'AlexandreBergel 8/20/2012 10:03'! contains: aPoint for: aROEdge ^ false! ! !RONullShape methodsFor: 'hooks' stamp: 'AlexandreBergel 9/4/2012 12:50'! defaultShape ^ RONullShape new! ! !RONullShape methodsFor: 'testing' stamp: 'AlexandreBergel 9/24/2012 18:53'! element: aROElement containsPoint: aPoint "Return true if aPoint is contained in the bounds defined by myself for the element" ^ self boundsFor: aROElement containsPoint: aPoint ! ! !RONullShape methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 17:22'! elementExtent: aPoint width := aPoint x. height := aPoint y! ! !RONullShape methodsFor: 'hooks' stamp: 'AlexandreBergel 10/17/2012 08:45'! extent: anExtentPoint width := anExtentPoint x. height := anExtentPoint y.! ! !RONullShape methodsFor: 'hooks' stamp: 'JurajKubelka 10/11/2013 16:13'! extentFor: element ^ self shouldNotImplement! ! !RONullShape methodsFor: 'util' stamp: 'AlexandreBergel 8/19/2012 13:06'! hasNext ^ false! ! !RONullShape methodsFor: 'accessing' stamp: 'VanessaPena 1/28/2013 15:44'! height: anObject height := anObject! ! !RONullShape methodsFor: 'initialize' stamp: 'AlexandreBergel 10/17/2012 08:46'! initialize color := self class defaultColor. self extent: self defaultExtent. ! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 12:09'! isShapedAs: aShapeClass ^ false! ! !RONullShape methodsFor: 'hooks' stamp: 'AlexandreBergel 1/26/2013 19:13'! lineSegmentsFor: element ^ Array with: 0 @ 0! ! !RONullShape methodsFor: 'linking' stamp: 'JurajKubelka 10/11/2013 17:24'! maxChainedExtentFor: element ^ width @ height! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/22/2012 08:23'! removeShape: aShapeClass ^ self ! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 8/20/2012 08:55'! removeShape: aShapeClass previousShape: aShape ^ self ! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 9/24/2012 11:46'! shapeDetect: aBlock (aBlock value: self) ifTrue: [ ^ self ]. self error: 'Not found'! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 7/23/2012 14:53'! shapesDetect: aBlock self error: 'Not found'! ! !RONullShape methodsFor: 'linking' stamp: 'AlexandreBergel 9/24/2012 11:55'! shapesDo: aBlock aBlock value: self! ! !RONullShape methodsFor: 'looking up elements' stamp: 'AlexandreBergel 9/25/2012 09:59'! subElementsAt: aPoint forElement: aROElement "Return one of the direct children element of aROElement pointed by aPoint. Return null if none" ^ nil! ! !RONullShape methodsFor: 'accessing' stamp: 'VanessaPena 1/28/2013 15:45'! width: anObject width := anObject! ! !ROShape class methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:47'! + aShape ^ self compose: aShape! ! !ROShape class methodsFor: 'public' stamp: 'JurajKubelka 4/19/2013 12:38'! black ^ self new color: Color black! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 6/4/2012 00:53'! blue ^ self new color: Color blue! ! !ROShape class methodsFor: 'copying' stamp: 'JurajKubelka 4/9/2013 17:13'! chainedCopy ^ self! ! !ROShape class methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:38'! compose: aShape ^ self new compose: aShape; yourself! ! !ROShape class methodsFor: 'public'! defaultColor ^ Color veryLightGray! ! !ROShape class methodsFor: 'public' stamp: 'JurajKubelka 10/11/2013 17:32'! defaultExtent ^ 5 @ 5! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 19:00'! element ^ self elementOn: nil! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 4/11/2013 14:27'! elementOn: object "Easy way to create element from a shape" ^ (ROElement on: object) + self! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 8/11/2013 21:59'! elementsOn: objects "Easy way to create elements from a shape" ^ objects collect: [ :o | self elementOn: o ] ! ! !ROShape class methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:38'! ensureInstance ^ self new! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 9/24/2012 12:12'! gray ^ self new color: Color gray! ! !ROShape class methodsFor: 'public'! green ^ self new color: Color green! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 4/11/2013 14:27'! installedOn: element ^ self new installedOn: element; yourself! ! !ROShape class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:00'! isAbstract ^ self name = #ROShape! ! !ROShape class methodsFor: 'testing' stamp: 'JurajKubelka 4/19/2013 14:52'! isEdgeShape ^ false! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 9/24/2012 12:12'! lightGray ^ self new color: Color lightGray! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 10/1/2013 18:51'! lightRed ^ self new color: (Color r: 1.0 g: 0.5 b: 0.5)! ! !ROShape class methodsFor: 'public'! red ^ self new color: Color red! ! !ROShape class methodsFor: 'public' stamp: 'AlexandreBergel 4/7/2013 01:15'! size: aSize ^ self new size: aSize! ! !ROShape class methodsFor: 'public'! white ^ self new color: Color white! ! !ROShape class methodsFor: 'public'! yellow ^ self new color: Color yellow! ! !ROShape methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:46'! + aShape self compose: aShape! ! !ROShape methodsFor: 'rendering' stamp: 'AlexandreBergel 6/14/2013 12:18'! OLDchainedDrawOn: aCanvas for: aROElement " The following code is without the optimization. true ifTrue: [ self drawOn: aCanvas for: aROElement. next chainedDrawOn: aCanvas for: aROElement. ^ true]." ((aCanvas camera windowSize = (0 @ 0)) or: [ (self isElementVisible: aROElement inCanvas: aCanvas) ]) ifTrue: [ (aROElement attributes includesKey: #childrenAreShadowed) ifTrue: [ aROElement attributes removeKey: #childrenAreShadowed. aROElement allElementsDo: #setAsRendered ]. "If the window size is more than (0@0), meaning we are not in a test, or, if the element is actually visible, then we render it" self drawOn: aCanvas for: aROElement. next chainedDrawOn: aCanvas for: aROElement ] ifFalse: [ "Else, we simply remove from the elementToRenders list in the view" aROElement isRendered ifTrue: [ aROElement allElementsDo: #setAsNotRendered. aROElement attributes at: #childrenAreShadowed put: true ] ]! ! !ROShape methodsFor: 'rendering' stamp: 'AlexandreBergel 4/11/2013 12:10'! absoluteBoundsFor: aROElement ^ (self boundsFor: aROElement) translateBy: aROElement absolutePosition! ! !ROShape methodsFor: 'visitor' stamp: 'VanessaPena 12/27/2012 13:20'! accept: visitor ! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 8/19/2012 11:25'! addLast: aShape "Instance variable 'next' must be a RONullShape to provide the exit condition of this recursive call. This is ensured by instance initialization. The Null Object design pattern is here applied" self addLast: aShape in: self! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 11:43'! addLast: aShape in: elementToAdd next addLast: aShape in: self! ! !ROShape methodsFor: 'testing' stamp: 'AlexandreBergel 9/28/2012 08:21'! boundsFor: aROElement ^ 0 @ 0 extent: aROElement extent! ! !ROShape methodsFor: 'testing' stamp: 'AlexandreBergel 9/25/2012 09:49'! boundsFor: aROElement containsPoint: aPoint "Return true if aPoint is contained in one of the chain of shape" ^ (self boundsFor: aROElement) containsPoint: aPoint! ! !ROShape methodsFor: 'copying' stamp: 'AlexandreBergel 12/11/2012 19:13'! chainedCopy | s current | s := self copy. current := s. self next shapesDo: [:shape | | shapeCopy | shapeCopy := shape copy . current next: shapeCopy. current := shapeCopy ]. ^s ! ! !ROShape methodsFor: 'rendering' stamp: 'AlexandreBergel 6/14/2013 12:18'! chainedDrawOn: aCanvas for: aROElement self drawOn: aCanvas for: aROElement. next chainedDrawOn: aCanvas for: aROElement. ! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 9/27/2012 17:05'! change: aShapeClass for: aShape "Replace a shape per another shape" ^ (self isKindOf: aShapeClass) ifTrue: [ aShape next: self next; yourself ] ifFalse: [ self next: (self next change: aShapeClass for: aShape) ]! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/27/2012 17:05'! color "Color associated to the shape" ^ color! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 11/7/2012 11:35'! color: anObject "Set a color. For practical reason, the color is cached and the cache needs to be reset" color := anObject. colorCache := nil.! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/29/2013 20:39'! colorFor: element "Compute the color of the element" "We use a cache mechanism since computing the cache can be quite slow" colorCache notNil ifTrue: [ ^ colorCache ]. ^ colorCache := color roValue: element. " (element hasAttribute: (#element, self class name) asSymbol) ifTrue: [ ^ element attributeAt: (#element, self class name) asSymbol ]. colorCache := color roValue: element. element attributeAt: (#element, self class name) asSymbol put: colorCache. ^ colorCache"! ! !ROShape methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:35'! compose: aShape self addLast: (aShape ensureInstance)! ! !ROShape methodsFor: 'initialize' stamp: 'JurajKubelka 10/11/2013 17:32'! defaultExtent "Each shape has a minimum size of 5@5" ^ self class defaultExtent! ! !ROShape methodsFor: 'hooks' stamp: 'AlexandreBergel 9/25/2012 20:21'! defaultShape ^ RONullShape new! ! !ROShape methodsFor: 'rendering'! drawOn: aCanvas for: aROElement ! ! !ROShape methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 19:00'! element "Easy way to create element from a shape" ^ self elementOn: nil! ! !ROShape methodsFor: 'looking up elements' stamp: 'AlexandreBergel 9/27/2012 17:25'! elementAt: aPoint forElement: aROElement "Return the element pointed by aPoint for a given element. The coordinate aPoint is local to the element aROElement. This means that aPoint = 0@0 refers to the topLeft of aROElement" "If the point does not refer to myself, then we simply return the view" | subElement | (((0 @ 0) corner: (self extentFor: aROElement)) containsPoint: aPoint) ifFalse: [ ^ aROElement view ]. "The point refers to myself. We now have to check whether a subelement is pointed" subElement := self subElementsAt: aPoint forElement: aROElement. ^ subElement notNil ifTrue: [ subElement elementAt: (aPoint - subElement position) ] ifFalse: [ aROElement ] ! ! !ROShape methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 17:24'! elementExtent: aPoint next elementExtent: aPoint! ! !ROShape methodsFor: 'public' stamp: 'AlexandreBergel 6/9/2012 19:00'! elementOn: object "Easy way to create element from a shape" ^ (ROElement on: object) + self! ! !ROShape methodsFor: 'public' stamp: 'AlexandreBergel 8/11/2013 22:00'! elementsOn: objects "Easy way to create elements from a shape" ^ objects collect: [ :o | self elementOn: o ] ! ! !ROShape methodsFor: 'linking' stamp: 'JurajKubelka 4/19/2013 12:36'! ensureInstance ^ self! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 10/17/2012 08:43'! extent "Return the extent of the shape. Note that the width and height may be block and not immediate value. Use extentFor: to get immediate value" ^ width @ height! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/15/2013 00:50'! extent: anExtentPoint width := anExtentPoint x. height := anExtentPoint y. ! ! !ROShape methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:34'! extentFor: element "Return the extent of element" ^ ((width roValue: element) @ (height roValue: element)) max: (self defaultExtent).! ! !ROShape methodsFor: 'testing' stamp: 'AlexandreBergel 8/19/2012 13:05'! hasNext ^ true! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 10/17/2012 08:58'! height ^ height! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/15/2013 00:50'! height: aNumberOrSymbolOrOneArgBlock height := aNumberOrSymbolOrOneArgBlock ! ! !ROShape methodsFor: 'initialize' stamp: 'AlexandreBergel 10/17/2012 08:44'! initialize super initialize. color := self class defaultColor. next := self defaultShape. self extent: self defaultExtent. ! ! !ROShape methodsFor: 'hooks' stamp: 'JurajKubelka 4/19/2013 12:37'! installedOn: element "This method is meant to be overriden in case a special treatment has to be realized on the element" "self extent: (self preferedExtentFor: element)." "element extent: (element extent max: extent)." self hasNext ifTrue: [self next installedOn: element]! ! !ROShape methodsFor: 'testing' stamp: 'AlexandreBergel 6/10/2013 10:54'! isElementVisible: aROElement inCanvas: aROCanvas "Say whether the element is visible within the canvas. The canvas knows about the camera." ^ (aROCanvas camera virtualToRealRectangle: (self absoluteBoundsFor: aROElement)) intersects: (0 @ 0 extent: aROCanvas camera windowSize)! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 12:09'! isShapedAs: aShapeClass ^ (self isKindOf: aShapeClass) or: [ self next isShapedAs: aShapeClass ]! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/29/2013 21:05'! maxChainedExtentFor: element ^ (self extentFor: element) max: (self next maxChainedExtentFor: element)! ! !ROShape methodsFor: 'events-accessing' stamp: 'JurajKubelka 5/17/2013 12:01'! modelChanged: aROAbstractComponent "do nothing"! ! !ROShape methodsFor: 'accessing'! next ^ next! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 12/11/2012 19:17'! next: aShape next := aShape. ! ! !ROShape methodsFor: 'hooks' stamp: 'AlexandreBergel 9/28/2012 11:15'! preferedExtentFor: element "Override this method is you want the element to have a particular shape" ^ self extentFor: element! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 8/20/2012 08:55'! removeShape: aShapeClass "Remove a shape of the element" ^ (self isKindOf: aShapeClass) ifTrue: [ next ] ifFalse: [ next removeShape: aShapeClass previousShape: self ] ! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 8/20/2012 08:56'! removeShape: aShapeClass previousShape: aShape "Remove a shape of the element. Return the element that has been removed" ^ (self isKindOf: aShapeClass) ifTrue: [ aShape next: next. self ] ifFalse: [ next removeShape: aShapeClass previousShape: next next ]! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 5/7/2012 11:44'! shapeDetect: aBlock (aBlock value: self) ifTrue: [ ^ self ]. ^ self next shapeDetect: aBlock! ! !ROShape methodsFor: 'linking' stamp: 'AlexandreBergel 9/24/2012 11:55'! shapesDo: aBlock aBlock value: self. ^ self next shapesDo: aBlock! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/14/2013 11:48'! size: aNumberOrASymbolOrABlock "Set the size of the shape as a square" self width: aNumberOrASymbolOrABlock. self height: aNumberOrASymbolOrABlock! ! !ROShape methodsFor: 'looking up elements' stamp: 'AlexandreBergel 9/25/2012 10:03'! subElementsAt: aPoint forElement: aROElement "Return one of the direct children element of aROElement pointed by aPoint. Return null if none" "Note that we are here interested only in direct children. The recursion is done later on" "For a shape that is not an abstractchildren one, there is nothing to do." ^ next subElementsAt: aPoint forElement: aROElement! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 10/17/2012 08:59'! width ^ width! ! !ROShape methodsFor: 'accessing' stamp: 'AlexandreBergel 9/15/2013 00:50'! width: aNumberOrSymbolOrOneArgBlock width := aNumberOrSymbolOrOneArgBlock! ! !ROTriangle methodsFor: 'accessing' stamp: 'AlexandreBergel 8/27/2013 21:51'! borderColor ^ borderColor ! ! !ROTriangle methodsFor: 'accessing' stamp: 'AlexandreBergel 8/27/2013 21:51'! borderColor: aBlockOrSymbolOrObject borderColor := aBlockOrSymbolOrObject.! ! !ROTriangle methodsFor: 'accessing' stamp: 'AlexandreBergel 8/27/2013 21:51'! borderWidth ^ borderWidth ! ! !ROTriangle methodsFor: 'accessing' stamp: 'AlexandreBergel 8/27/2013 21:51'! borderWidth: anInteger borderWidth := anInteger. ! ! !ROTriangle methodsFor: 'rendering' stamp: 'AlexandreBergel 8/28/2013 13:55'! drawOn: aCanvas for: aROElement | b w bc c | b := self absoluteBoundsFor: aROElement. w := borderWidth roValue: aROElement. bc := borderColor roValue: aROElement. c := color roValue: aROElement. aCanvas drawPolygon: (Array with: b topCenter with: b bottomRight with: b bottomLeft) color: c borderWidth: w borderColor: bc. " aCanvas line: b topCenter to: b bottomRight width: w color: bc. aCanvas line: b bottomRight to: b bottomLeft width: w color: bc. aCanvas line: b bottomLeft to: b topCenter width: w color: bc. " ! ! !ROTriangle methodsFor: 'initialize' stamp: 'AlexandreBergel 8/29/2013 08:10'! initialize super initialize. borderWidth := 0. borderColor := Color black.! ! !ROViewDisplayer commentStamp: 'AlexandreBergel 8/2/2012 18:07' prior: 34321638! ROViewDisplayer is a shape that is used to display a view. It simply wraps a view into a shape. Instance Variables: view ! !ROMiniMapDisplayer methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 22:19'! camera ^ camera! ! !ROMiniMapDisplayer methodsFor: 'accessing' stamp: 'VanessaPena 12/20/2012 22:19'! camera: anObject camera := anObject! ! !ROMiniMapDisplayer methodsFor: 'initialize' stamp: 'VanessaPena 1/2/2013 17:34'! defaultFactor ^0.2! ! !ROMiniMapDisplayer methodsFor: 'rendering' stamp: 'VanessaPena 1/4/2013 10:44'! drawOn: aCanvas for: aROElement | previousOffset previousCamera rect| previousOffset := aCanvas offset. previousCamera := aCanvas camera. aCanvas offset: (aROElement position). aCanvas camera: camera. canvasWrapper canvas: aCanvas. view drawWithoutSettingCameraElementsOn: canvasWrapper. aCanvas offset: previousOffset. aCanvas camera: previousCamera.! ! !ROMiniMapDisplayer methodsFor: 'accessing' stamp: 'VanessaPena 1/2/2013 17:34'! factor ^factor! ! !ROMiniMapDisplayer methodsFor: 'accessing' stamp: 'VanessaPena 1/2/2013 17:34'! factor: aNumber factor := aNumber! ! !ROMiniMapDisplayer methodsFor: 'initialize' stamp: 'VanessaPena 1/4/2013 10:44'! initialize super initialize. factor := self defaultFactor. canvasWrapper := RONoTextCanvasWrapper new.! ! !ROMiniMapDisplayer methodsFor: 'initialize' stamp: 'VanessaPena 1/5/2013 14:19'! installedOn: element |rect max1 max2 e| super installedOn: element. self setCameraRealExtentFor: element. self setViewAnnouncementsFor: element.! ! !ROMiniMapDisplayer methodsFor: 'initialize' stamp: 'AlexandreBergel 9/15/2013 00:23'! setCameraRealExtentFor: element | rect max1 max2 e | rect := view encompassingRectangle. e := element extent. max1 := e x max: e y. max2 := rect extent x max: rect extent y. camera realExtent: (originalCameraRealExtent * (max1/max2)) asIntegerPoint. ! ! !ROMiniMapDisplayer methodsFor: 'events' stamp: 'VanessaPena 1/5/2013 13:10'! setViewAnnouncementsFor: element view on: ROWindowResized do: [:event | element extent: view camera windowSize. element signalUpdate. ].! ! !ROMiniMapDisplayer methodsFor: 'accessing' stamp: 'VanessaPena 1/5/2013 13:13'! view: aView "Take a roassal view as argument" view := aView. camera := aView camera copy. " camera scale: (1@1) * self factor." originalCameraRealExtent := camera realExtent. ! ! !ROViewDisplayer methodsFor: 'rendering' stamp: 'AlexandreBergel 5/19/2013 19:06'! drawOn: aCanvas for: aROElement | previousOffset| previousOffset := aCanvas offset. aCanvas offset: (aROElement position). view drawElementsOn: aCanvas. view doAnimationCycle. aCanvas offset: previousOffset. ! ! !ROViewDisplayer methodsFor: 'accessing' stamp: 'AlexandreBergel 5/19/2013 19:06'! view: aView "Take a roassal view as argument" view := aView. ! ! !ROShapeCache methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:03'! extent: aPoint extent := aPoint! ! !ROShapeCache methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 15:42'! extentIfAbsentPut: aBlockClosure ^ extent ifNil: [ extent := aBlockClosure value ]! ! !ROShapeCache methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:28'! height: aSmallInteger extent := extent x @ aSmallInteger ! ! !ROShapeCache methodsFor: 'accessing' stamp: 'JurajKubelka 10/11/2013 16:26'! with: aSmallInteger extent := aSmallInteger @ extent y! ! !ROSplineExample methodsFor: 'example' stamp: 'AlexandreBergel 9/14/2013 19:26'! hierarchicalBundleEdgesInMoose " Open this in a Glamour-based Roassal easel " " |bs superclassEdges lastlevel| view shape rectangle width: 5;height:15. view nodes: classGroup. superclassEdges := view edgesFrom: #superclass. view treeLayout userDefinedEdges: superclassEdges. bs := (ROBSplineLine new). bs alpha: 0.85. bs setDiscovery: [ :cls | cls superclass ]. bs color: Color red. view shape: bs. lastlevel := classGroup select:[ :cls | (cls subclassHierarchy size) == 0 ]. view edges: lastlevel from: #yourself toAll: [ :cls | (cls queryAllOutgoingInvocations atTypeScope) select: [:clsa | (clsa subclassHierarchy size) == 0 ]]. "! ! !ROSplineExample methodsFor: 'example' stamp: 'AlexandreBergel 9/23/2013 18:55'! simple " self new simple " | view el1 el2 el3 edge bspline | view := ROView new. el1 := (ROBox green size: 20) element . el2 := (ROBox green size: 20) element . el3 := (ROBox blue size: 20) element . el1 @ RODraggable. el2 @ RODraggable. el3 @ RODraggable. el1 translateTo: 50 @ 50. el2 translateTo: 90 @ 130. el3 translateTo: 250 @ 150. edge := ROEdge from: el1 to: el3. bspline := ROBSplineLine new. bspline color: Color red. bspline addControlElement: el2. edge + bspline. view add: el1; add: el2; add: el3; add: edge. view open! ! !ROSplineExample methodsFor: 'example' stamp: 'AlexandreBergel 9/23/2013 19:01'! simple2 " ROSplineExample new simple2 " | view el1 el2 edge bspline controlPoints | view := ROView new. el1 := (ROBox green size: 20) element. el2 := (ROBox green size: 20) element. el1 @ RODraggable. el2 @ RODraggable. controlPoints := OrderedCollection new. 5 timesRepeat: [ | el | el := (ROBox gray size: 10) element. el @ RODraggable. el translateTo: (200 atRandom @ 200 atRandom). controlPoints add: el ]. el1 translateTo: 50 @ 50. el2 translateTo: 90 @ 130. edge := ROEdge from: el1 to: el2. bspline := ROBSplineLine new. bspline color: Color red. bspline addControlElement: el2. edge + bspline. controlPoints do: [ :el | bspline addControlElement: el ]. view addAll: controlPoints. view add: el1; add: el2; add: edge. view open! ! !ROSplineExample methodsFor: 'example' stamp: 'AlexandreBergel 9/30/2013 18:47'! simple3 " ROSplineExample new simple3 " | view edges bs | view := ROMondrianViewBuilder new. view shape circle size: 10. view nodes: (1 to: 10). edges := view edges: (1 to: 10) from: [ :v | v // 2 ] to: #yourself. view forceBasedLayout userDefinedEdges: edges. bs := ROBSplineLine new. bs setDiscovery: [ :v | v // 2 ]. bs color: Color red. view shape: bs. "view shape line color: Color red." view edgesFromAssociations: (Array with: 5 -> 6 with: 9 -> 4 with: 8 -> 7 with: 4 -> 6). view open! ! !ROTimeOrganizer commentStamp: '' prior: 34321827! Abstract class for the time passing.! !ROMorphicTimeOrganizer class methodsFor: 'as yet unclassified' stamp: 'AlexandreBergel 5/3/2012 16:43'! milliseconds ^ Time now asMilliSeconds! ! !ROTimeOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 5/3/2012 16:42'! current ^ self subclasses first! ! !ROTimeOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 5/3/2012 16:44'! milliseconds "Return the elapsed amount of milliseconds" self subclassResponsibility ! ! !ROTimeOrganizer class methodsFor: 'public' stamp: 'AlexandreBergel 5/3/2012 16:42'! now ^ Time now! ! !ROTreeLayerWrapper commentStamp: '' prior: 34321924! This class holds all figures that belong to the same layer. The class also contains auxiliary information like width and height of the layer. Instance Variables: cachedHeight The height of the layer cachedWidth The widht of the layer figures All figures that belong to this layer ! !ROTreeLayerWrapper methodsFor: 'accessing' stamp: 'miltonmamani 4/17/2013 15:34'! add: aFigure elements add: aFigure! ! !ROTreeLayerWrapper methodsFor: 'accessing' stamp: 'miltonmamani 4/17/2013 15:34'! do: aBlock elements do: aBlock! ! !ROTreeLayerWrapper methodsFor: 'accessing' stamp: 'miltonmamani 4/17/2013 15:34'! height cachedHeight isNil ifTrue: [cachedHeight := 0. elements do: [:aFigure | cachedHeight := cachedHeight max: aFigure height]]. ^cachedHeight! ! !ROTreeLayerWrapper methodsFor: 'initialize-release' stamp: 'miltonmamani 4/17/2013 15:34'! initialize elements := OrderedCollection new. cachedWidth := nil. cachedHeight := nil! ! !ROTreeLayerWrapper methodsFor: 'accessing' stamp: 'miltonmamani 4/17/2013 15:34'! width: gapSize ^ cachedWidth ifNil: [ cachedWidth := 0. elements do: [ :aFigure | cachedWidth := cachedWidth + aFigure width]. cachedWidth := cachedWidth + ((elements size - 1) * gapSize) ].! ! !ROHTMLExporter class methodsFor: 'as yet unclassified' stamp: 'VanessaPena 11/20/2012 09:54'! exportViewAsHTML: view self subclassResponsibility ! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:10'! addDataSet: fileStream visitor :=ROHTMLVisitor new runOn: view. fileStream nextPutAll: 'var dataset = { '; nextPutAll: visitor nodesStream contents ; nextPutAll: visitor linksStream contents ; nextPutAll: ' };'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'declarations' stamp: 'DR 3/25/2013 21:48'! addEllipseDeclaration: fileStream fileStream nextPutAll: ' var nodes = roElements.selectAll("ellipse") .data(function(d) { return getChildrenNodesByParentIDAndShape(d.nodeID, "ROEllipse")}) .enter().append("svg:ellipse") .attr("id", function(d) { return d.nodeID; } ) .attr("stroke", function(d) { return d.nodeBorderColor; } ) .attr("stroke-width", function(d) { return d.nodeBorderWidth; } ) .attr("fill", function(d) { return d.nodeFillColor; } ) .attr("draggable", function(d) { return d.draggable; } ) .attr("cx", function(d) { return d.x + d.nodeWidth/2; }) .attr("cy", function(d) { return d.y + d.nodeHeight/2; }) .attr("rx", function(d) { return d.nodeWidth/2; } ) .attr("ry", function(d) { return d.nodeHeight/2; } ) .attr("nodeParentID", function(d) { return d.nodeParentID } ) .call(drag);'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:10'! addEndBody: fileStream fileStream nextPutAll: ' '; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'VanessaPena 11/30/2012 17:27'! addEndHTML: fileStream fileStream nextPutAll: ''! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:10'! addHeader: fileStream fileStream nextPutAll: ' '; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'declarations' stamp: 'DR 3/25/2013 21:48'! addROElementDeclaration: fileStream fileStream nextPutAll: ' var roElements = vis.selectAll("g").data(dataROElement); roElements.enter().append("g") .attr("id", function(d) { return d.nodeID; } ) .attr("draggable", function(d) { return d.draggable; } ) .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }) .attr("width", function(d) { return d.nodeWidth; } ) .attr("height", function(d) { return d.nodeHeight; } ) .attr("nodeParentID", function(d) { return d.nodeParentID } );'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'declarations' stamp: 'DR 3/25/2013 21:47'! addRectangleDeclaration: fileStream fileStream nextPutAll: ' var roBorders = roElements.selectAll("rect") .data(function(d) { return (getChildrenNodesByParentIDAndShape(d.nodeID, "ROBorder")).concat(getChildrenNodesByParentIDAndShape(d.nodeID, "ROBox")) }) .enter().append("svg:rect") .attr("id", function(d) { return d.nodeID; } ) .attr("stroke", function(d) { return d.nodeBorderColor; } ) .attr("stroke-width", function(d) { return d.nodeBorderWidth; } ) .attr("fill", function(d) { return d.nodeFillColor; } ) .attr("draggable", function(d) { return d.draggable; } ) .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }) .attr("width", function(d) { return d.nodeWidth; } ) .attr("height", function(d) { return d.nodeHeight; } ) .attr("nodeParentID", function(d) { return d.nodeParentID } ) .call(drag);'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:15'! addRenderingEdges: fileStream fileStream nextPutAll: '/***** RENDERING LINKS*****/ var links = dataset.links; var path = vis.selectAll("path") .data(links); path.enter().append("path") .attr("d", elbow) .attr("stroke", function(d) {return d.edgeColor});'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 3/25/2013 21:47'! addRenderingNodes: fileStream self addSelectNodesDeclaration: fileStream. self addROElementDeclaration: fileStream. self addRectangleDeclaration: fileStream. self addEllipseDeclaration: fileStream. self addTextDeclaration: fileStream. fileStream nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:15'! addRenderingPopup: fileStream fileStream nextPutAll: '/*****POPUP*****/ $("svg g").tipsy({ gravity: "w", html: true, title: function() { var d = this.__data__; return d.nodeModel + ""; } });'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:15'! addSVGInitialization: fileStream |extent| extent := view encompassingRectangle extent + view camera extent . fileStream nextPutAll: '/*****INITIALIZATION*****/ var drag = d3.behavior.drag() .origin(Object) .on("dragstart", dragstart) .on("drag", dragmove) .on("dragend", dragend);'; nextPutAll: ('var w = <1p>, h = <2p>;' expandMacrosWith: extent x with: extent y); nextPutAll: 'var vis = d3.select("#chart").append("svg:svg") .attr("width", w) .attr("height", h);'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'declarations' stamp: 'DR 3/25/2013 21:47'! addSelectNodesDeclaration: fileStream fileStream nextPutAll: '/***** RENDERING NODES*****/ var dataROBox = getNodesByShape("ROBorder"); var dataROCircle = getNodesByShape("ROCircle"); var dataROLabel = getNodesByShape("ROLabel"); var dataROElement = getNodesByShape("ROElement");'; nextPutAll: ROPlatform current newLine.! ! !ROHTMLExporter methodsFor: 'html file' stamp: 'DR 1/22/2013 17:14'! addStartBody: fileStream fileStream nextPutAll: '