[squeak-dev] The Inbox: Morphic-phite.431.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Apr 26 20:29:18 UTC 2010


A new version of Morphic was added to project The Inbox:
http://source.squeak.org/inbox/Morphic-phite.431.mcz

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

Name: Morphic-phite.431
Author: phite
Time: 26 April 2010, 10:28:00.807 pm
UUID: 370cdcdb-18cf-2d4a-a04e-509206840fac
Ancestors: Morphic-phite.429, Morphic-laza.430

Refactored the DockingBar and the WorldMenu to add custom self-defined menus. (See class comment of MenuEntrySpec)
MenuEntries may be added pasiv (during the DockingBar/WorldMenu creation) or active (by TheWorldMainDockingBar installSpec: a MenuEntrySpec).

Changed Class comments of TheWorldMenu and TheWorldMainDockingBar. They now reference MenuEntrySpec to explain how new menu entries may be added.

=============== Diff against Morphic-phite.429 ===============

Item was added:
+ ----- Method: DockingBarMorph>>install: (in category 'menus') -----
+ install: aMenuEntrySpec
+ 	"Install a menu entry corresponding to the given spec on me."
+ 
+ 	aMenuEntrySpec installOn: self.!

Item was added:
+ ----- Method: MenuEntrySpec>>findMenuAt:In: (in category 'menu-installation') -----
+ findMenuAt: aLocation In: aMenu
+ 	"find the menu the location points at relative from the given menu."
+ 
+ 	| currentMenu |
+ 	aLocation size = 0 ifTrue: [ ^ aMenu ].
+ 	currentMenu := aMenu.
+ 	(1 to: aLocation size) do: [ :i |
+ 		currentMenu := currentMenu menus detect: [ :m | m contents = (aLocation at: i) ]].
+ 	^ currentMenu!

Item was changed:
+ ----- Method: MenuEntrySpec>>installOn: (in category 'menu-installation') -----
- ----- Method: MenuEntrySpec>>installOn: (in category 'menu-creation') -----
  installOn: aMenu
  	"Installs a menuEntry corresponding to this specification into the given menu"
  
  	| menu |
  	menu := self findOrCreateLocationIn: aMenu.
  	menu subMenu ifNil: [ menu addSubMenu: [:subMenu |] ].
  	menu subMenu addItem: [ :item |
  		item
  			contents: self contents;
  			help: self help;
  			icon: self icon;
  			target: self target;
  			selector: self selector;
  			arguments: self arguments.
  		(item respondsTo: #selectedIcon:) ifTrue: [ item selectedIcon: self selectedIcon ].]
  		at: self position.!

Item was changed:
  ----- Method: TheWorldMainDockingBar>>listWindowsOn: (in category 'submenu - windows') -----
  listWindowsOn: menu
  
  	| windows |
  	windows := SortedCollection sortBlock: [:winA :winB |
  		winA model name = winB model name
  			ifTrue: [winA label < winB label]
  			ifFalse: [winA model name < winB model name]].
  	windows addAll: self allVisibleWindows.
  	windows ifEmpty: [ 
  		menu addItem: [ :item | 
  			item
  				contents: 'No Windows' translated;
  				isEnabled: false ] ].
  	windows do: [ :each |
  		menu addItem: [ :item |
  			item 
  				contents: (self windowMenuItemLabelFor: each);
+ 				icon: (self colorIcon: each model defaultBackgroundColor);
- 				icon: (self colorIcon: each paneColor);
  				target: each;
  				selector: #comeToFront;
  				subMenuUpdater: self
  				selector: #windowMenuFor:on:
  				arguments: { each };
  				action: [ each activateAndForceLabelToShow; expand ] ] ].!

Item was added:
+ ----- Method: DockingBarMorph>>uninstall: (in category 'menus') -----
+ uninstall: aMenuEntrySpec
+ 	"Uninstall the menu entry described by the given spec off me."
+ 
+ 	aMenuEntrySpec uninstallOn: self.!

Item was added:
+ ----- Method: MorphicProject>>dockingBarInstallMenu: (in category 'docking bars support') -----
+ dockingBarInstallMenu: menuEntrySpec
+ 	"installs a menu entry corresponding to the given spec in all docking bars."
+ 	self world mainDockingBars
+ 		do: [:each | each install: menuEntrySpec]!

Item was added:
+ ----- Method: MenuEntrySpec>>uninstallOn: (in category 'menu-installation') -----
+ uninstallOn: aMenu
+ 	"uninstalls a menuEntry corresponding to this specification from the given menu"
+ 
+ 	| menu entry |
+ 	menu := self findOrCreateLocationIn: aMenu.
+ 	entry := menu menus detect: [ :m | m contents = self contents] ifNone: [ nil ].
+ 	entry ifNotNil: [menu subMenu removeMorph: entry ].
+ 	self removeEmptySubMenusRecursivelyFrom: self location UpTo: aMenu.!

Item was added:
+ ----- Method: MorphicProject>>dockingBarUninstallMenu: (in category 'docking bars support') -----
+ dockingBarUninstallMenu: menuEntrySpec
+ 	"uninstalls the menu entry that matches the given menuEntrySpec from all docking bars."
+ 	self world mainDockingBars
+ 		do: [:each | each uninstall: menuEntrySpec]!

Item was changed:
  ----- Method: DockingBarMorph>>addMenu:atPosition: (in category 'construction') -----
  addMenu: item atPosition: position
  	"adds the Menu at the given position. Position is an Array of the form
  		{#last}, {#first}, {#before . 'Help'}, {#after . 'Tools'}"
  
  	((position at: 1) = #first) ifTrue: [ ^ self addMorphFront: item ].
  	((position at: 1) = #before) ifTrue: [ ^ self addMorph: item inFrontOf:
  		(self menus detect: [ :menu | menu contents = (position at: 2) ]) ].
  	((position at: 1) = #after) ifTrue: [ ^ self addMorph: item behind:
  		(self menus detect: [ :menu | menu contents = (position at: 2) ]) ].
+ 	"#last - add after last menu in case I have other morphs like a SearchBar"
+ 	(self menus size > 0)
+ 		ifTrue: [ self addMorph: item behind: (self menus at: self menus size) ]
+ 		ifFalse: [ self addMorphBack: item ].!
- 	"#last"
- 	self addMorphBack: item.!

Item was added:
+ ----- Method: TheWorldMainDockingBar class>>installSpec: (in category 'as yet unclassified') -----
+ installSpec: aMenuEntrySpec
+ 	"Installs the menu entry spec on the docking bar."
+ 
+ 	Project current dockingBarInstallMenu: aMenuEntrySpec.!

Item was changed:
+ ----- Method: MenuEntrySpec>>findOrCreateLocationIn: (in category 'menu-installation') -----
- ----- Method: MenuEntrySpec>>findOrCreateLocationIn: (in category 'menu-creation') -----
  findOrCreateLocationIn: aMenu
  	"find the menu my location points at - create it, if it does not exist."
  
  	| currentMenu |
  	location size = 0 ifTrue: [ ^ aMenu ].
  	currentMenu := aMenu.
  	(1 to: location size) do: [ :i |
  		currentMenu := currentMenu menus detect:
  		[ :m | m contents = (location at: i) ]
  		ifNone: [
  			currentMenu subMenu ifNil: [ currentMenu addSubMenu:[:subMenu| ]].
  			currentMenu subMenu addItem: [:item|
  				item contents: (location at: i)].
  			currentMenu menus detect: [ :m | m contents = (location at: i) ]]].
  	^ currentMenu!

Item was changed:
  Object subclass: #TheWorldMainDockingBar
  	instanceVariableNames: ''
  	classVariableNames: 'Instance TS'
  	poolDictionaries: ''
  	category: 'Morphic-Kernel'!
  
+ !TheWorldMainDockingBar commentStamp: 'phite 4/26/2010 21:30' prior: 0!
- !TheWorldMainDockingBar commentStamp: 'phite 4/26/2010 09:48' prior: 0!
  TheWorldMainDockingBar serves to present a Squeak menu which is always visible whithin a World.
  
+ It is possible to add custom menu entries to the WorldMenu. Please have a look at the MenuEntrySpec comments for examples.
+ Additionally you may add and remove menus dynamically by:
+ 	| spec |
+ 	spec := MenuEntrySpec newForDockingBarFrom: (Dictionary newFromPairs: #(
+ 		#contents 'Hello?'
+ 		#location #('Help' 'a subMenu' 'another subMenu')
+ 		#target MenuMorph #selector #inform: #arguments #('Hello World!!'))).
+ 	TheWorldMainDockingBar installSpec: spec.
+ 	TheWorldMainDockingBar uninstallSpec: spec.
+ 	!
- It is possible to add custom menu entries to the WorldMenu. Please have a look at the MenuEntrySpec comments for examples.!

Item was changed:
  ----- Method: TheWorldMainDockingBar>>colorIcon: (in category 'private') -----
  colorIcon: aColor
  
+ 	"Guess if 'uniform window colors' are used and avoid all icons to be just gray"
+ 	(aColor = Preferences uniformWindowColor or: [Preferences tinyDisplay]) ifTrue: [ ^nil ].
- 	Preferences tinyDisplay ifTrue: [ ^nil ].
  	^(aColor iconOrThumbnailOfSize: 14)
  		borderWidth: 3 color: Preferences menuColor muchDarker;
  		borderWidth: 2 color: Color transparent!

Item was changed:
(excessive method size, no diff calculated)

Item was added:
+ ----- Method: MenuEntrySpec>>whenEmptyRemove:From: (in category 'menu-installation') -----
+ whenEmptyRemove: menu From: parentMenu
+ 	"Removes the given menu if its submenu is nil or empty"
+ 	menu ifNil: [ ^ self ].
+ 	menu menus size = 0
+ 		ifTrue: [ parentMenu subMenu removeMorph: menu ].!

Item was added:
+ ----- Method: TheWorldMainDockingBar class>>uninstallSpec: (in category 'as yet unclassified') -----
+ uninstallSpec: aMenuEntrySpec
+ 	"Uninstalls the menu entry spec from the docking bar."
+ 
+ 	Project current dockingBarUninstallMenu: aMenuEntrySpec.!

Item was added:
+ ----- Method: MenuEntrySpec>>removeEmptySubMenusRecursivelyFrom:UpTo: (in category 'menu-installation') -----
+ removeEmptySubMenusRecursivelyFrom: aLocation UpTo: rootMenu
+ 	"Removes empty submenus from the given menu location up to the top-level menu"
+ 	| loc |
+ 	loc := aLocation copy.
+ 	(1 to: (aLocation size)) do: [ :i || parentMenu menu |
+ 		parentMenu := self findMenuAt: loc allButLast In: rootMenu.
+ 		menu := self findMenuAt: loc In: rootMenu.
+ 		self whenEmptyRemove: menu From: parentMenu.
+ 		loc := loc allButLast ].!

Item was changed:
  Object subclass: #MenuEntrySpec
  	instanceVariableNames: 'contents help icon selectedIcon target selector location arguments position dockingBar worldMenu'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Morphic-Menus'!
  
+ !MenuEntrySpec commentStamp: 'phite 4/26/2010 22:16' prior: 0!
- !MenuEntrySpec commentStamp: 'phite 4/26/2010 10:20' prior: 0!
  You may define MenuEntrySpecs to add custom menus to TheWorldMainDockingBar or TheWorldMenu.
  
+ To add custom menu entries your class needs to answer to #menuEntrySpecification.
- To add add custom menu entries your class needs to answer to #menuEntrySpecification.
  #menuEntrySpecification may answer an instance of MenuEntrySpec or an array of MenuEntrySpecs for multiple menus.
  
  Example:
  MenuEntrySpec newForDockingBarFrom: (Dictionary newFromPairs: #(
  		#contents 'Hello?'
  		#location #('Help' 'a subMenu' 'another subMenu')
  		#target MenuMorph #selector #inform: #arguments #('Hello World!!')
  		))
+ Rebuild the DockingBar (Extras - Rebuild Menus)
  
  The example above creates a MenuEntrySpec called 'Hello?' located in the Help-menu within some submenus. As you may see MenuEntrySpecs can be created with the help of an options dictionary. The options are explained later. Remember: You do not need to specify option you do not need.
  
+ MenuEntrySpec newForDockingBarFrom:  a Dictionary - creates a menu entry for the DockingBar
- MenuEntrySpec newForDockingBarFrom:  a Dictionary - created a menu entry for the DockingBar
  MenuEntrySpec newForWorldMenuFrom: a Dictionary - creates a menu entry for the WorldMenu
  MenuEntrySpec newFrom: a Dictionary - creates a menu entry for both
  
  Possible options:
  #contents
  	A String that is the visible label the user should click on
  #help
  	A String that may be shown in a bubble near the menu entry for the user's help
  #icon
  	A Form which is displayed near the label
  #selectedIcon
  	A Form which is displayed instead of the icon when the menuEntry is selected
  #target
  	An Object which is called when the user clicks on the menu entry
  #selector
  	A Symol which is sent the the target
  #argument
  	An Array of Arguments which are sent with the selector
  #location
  	An Arrray of Strings which describes the place the menuEntry should be displayed.
  	#location -> nil or #() creates the menu entry in the top-level of the menu
  	#location -> #('Help') creates the menu entry in the Help-menu
  	#location -> #('Help' 'mySubMenu') creates the entry in a submenu of the Help-menu. If the submenu 'mySubMenu' does not exist it will be created
  #position
  	A Symbol or Array describing the position of the menu entry within a menu.
  	#position -> #first creates the entry in the first slot of a menu
  	#position -> #last creates the entry in the last slot
  	#position -> #(#before 'Help') creates the entry just before the Help-menu
  	#position -> #(#after 'Help') creates the entry just after the Help-menu
  	If you reference a menu entry with #before or #after, be sure the menu entry exists.
  #dockingBar
  	A Boolean that defines whether the menu entry should be displayed in the DockingBar.
  	This is always true if you use MenuEntrySpec newForDockingBarFrom:  a Dictionary
  #worldMenu
  	A Boolean that defines whether the menu entry should be displayed in the WorldMenu.
+ 	This is always true if you use MenuEntrySpec newForWorldMenuFrom:  a Dictionary
+ 	
+ It is possible to add MenuEntrySpecs dynamically to the DockingBar (you see the change without rebuilding the menu):
+ 	TheWorldMainDockingBar installSpec: a MenuEntrySpec.
+ 	TheWorldMainDockingBar uninstallSpec: a MenuEntrySpec
+ 	
+ Dynamically addind rentries to TheWorldMenu just happens by implementing #menuEntrySpecification as described above as a new one is generated every time the menu opens.!
- 	This is always true if you use MenuEntrySpec newForWorldMenuFrom:  a Dictionary!




More information about the Squeak-dev mailing list