The Trunk: Morphic-mt.1755.mcz

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

The Trunk: Morphic-mt.1755.mcz

commits-2
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1755.mcz

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

Name: Morphic-mt.1755
Author: mt
Time: 18 April 2021, 7:00:43.878254 pm
UUID: e5705780-2988-a54e-b6c7-21b4194fcd5c
Ancestors: Morphic-mt.1754, Morphic-ct.1659

Fix our two menu-invocating buttons to act on mouse-down and actually look like menus: (1) menu button in system window and (2) change-set button in world-main-docking-bar.

Merges Morphic-ct.1659. Thanks Christoph (ct) for pointing out this issue about menu invocation through buttons. See http://forum.world.st/The-Inbox-Morphic-ct-1659-mcz-tp5116728.html

By example, this commit also adds a menu to the change-set button in the docking bar. This menu lists the latest method and class changes.

To make this work, the following things got addressed:
- Fixes DockingBarUpdatingItemMorph, which missed several changes from DockingBarItemMorph. (Interesting specialization challenge...)
- Let menus #rubberBandCells to allow for changing menu item's widths.
- Adds query about latest changes to #listChangesOn:. (Feel free to improve this. Maybe add preference for number of elements?)

Complements (and depends on) System-mt.1228 and  Tools-mt.1042.

=============== Diff against Morphic-mt.1754 ===============

Item was changed:
  ----- Method: DockingBarMorph>>addUpdatingItem: (in category 'construction') -----
  addUpdatingItem: aBlock
  | item |
  item := DockingBarUpdatingItemMorph new.
  aBlock value: item.
+ item subMenu ifNotNil: [:menu |
+ "Docking bar and protruding menu should appear visually merged."
+ menu morphicLayerNumber: self morphicLayerNumber + 1].
  self addMorphBack: item!

Item was changed:
  ----- Method: DockingBarMorph>>ensureSelectedItem: (in category 'events') -----
  ensureSelectedItem: evt
 
  self selectedItem ifNil: [
  self
  selectItem: (
  self submorphs
+ detect: [ :each | each isMenuItemMorph ]
- detect: [ :each | each isKindOf: DockingBarItemMorph ]
  ifNone: [ ^self ])
  event: evt ]!

Item was changed:
  ----- Method: DockingBarMorph>>filterEvent:for: (in category 'events-processing') -----
  filterEvent: aKeyboardEvent for: anObject
  "Provide keyboard shortcuts."
 
  | index itemToSelect |
 
  aKeyboardEvent controlKeyPressed
  ifFalse: [^ aKeyboardEvent].
 
  aKeyboardEvent isKeystroke
  ifFalse: [^ aKeyboardEvent].
 
  "Search field."
  aKeyboardEvent keyCharacter = $0
  ifTrue: [
  self searchBarMorph ifNotNil: [ :morph |
  morph model activate: aKeyboardEvent in: morph ].
  ^ aKeyboardEvent ignore "hit!!"].
 
  "Select menu items."
  (aKeyboardEvent keyValue
  between: $1 asciiValue
  and: $9 asciiValue)
  ifFalse: [^ aKeyboardEvent].
 
  index := aKeyboardEvent keyValue - $1 asciiValue + 1.
  itemToSelect := (self submorphs select: [ :each |
+ each isMenuItemMorph ])
- each isKindOf: DockingBarItemMorph ])
  at: index
  ifAbsent: [^ aKeyboardEvent].
 
  self activate: aKeyboardEvent.
  self
  selectItem: itemToSelect
  event: aKeyboardEvent.
 
  ^ aKeyboardEvent ignore "hit!!"!

Item was changed:
  ----- Method: DockingBarMorph>>moveSelectionDown:event: (in category 'control') -----
  moveSelectionDown: direction event: evt
  "Move the current selection up or down by one, presumably under keyboard control.
  direction = +/-1"
 
  | index |
  index := (submorphs indexOf: selectedItem ifAbsent: [1-direction]) + direction.
  submorphs do: "Ensure finite"
  [:unused | | m |
  m := submorphs atWrap: index.
+ (m isMenuItemMorph and: [m isEnabled]) ifTrue:
- ((m isKindOf: DockingBarItemMorph) and: [m isEnabled]) ifTrue:
  [^ self selectItem: m event: evt].
  "Keep looking for an enabled item"
  index := index + direction sign].
  ^ self selectItem: nil event: evt!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>adjacentTo (in category 'selecting') -----
+ adjacentTo
+
+ | roundedCornersOffset verticalOffset |
+ roundedCornersOffset := MenuMorph roundedMenuCorners
+ ifTrue: [Morph preferredCornerRadius negated]
+ ifFalse: [0].
+ verticalOffset := 2.
+
+ owner isFloating
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToTop
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToLeft
+ ifTrue: [^ {self bounds topRight + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToBottom
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToRight
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset negated)}].
+ ^ {self bounds bottomLeft + (roundedCornersOffset @ 5)}!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createSubmenu (in category 'private') -----
+ createSubmenu
+
+ ^DockingBarMenuMorph new!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createUpdatingSubmenu (in category 'private') -----
+ createUpdatingSubmenu
+
+ ^DockingBarUpdatingMenuMorph new!

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'world') -----
- ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'as yet unclassified') -----
  decorateOwner
 
  "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawIconOn: (in category 'drawing') -----
+ drawIconOn: aCanvas
+
+ | pos |
+ self hasIcon ifTrue: [
+ | iconForm |
+ iconForm := self iconForm.
+
+ pos := (contents
+ ifEmpty: [self left + (self width - iconForm width // 2)]
+ ifNotEmpty: [self left])
+ @ (self top + (self height - iconForm height // 2)).
+
+ aCanvas
+ translucentImage: iconForm
+ at: pos].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawLabelOn: (in category 'drawing') -----
+ drawLabelOn: aCanvas
+
+ | stringBounds |
+ self contents ifEmpty: [^ self].
+
+ stringBounds := bounds.
+
+ self hasIcon ifTrue: [
+ stringBounds := stringBounds left: stringBounds left + self iconForm width + 2 ].
+
+ "Vertical centering."
+ stringBounds := stringBounds top: stringBounds top + stringBounds bottom - self fontToUse height // 2.
+ "Horizontal centering."
+ stringBounds := stringBounds left: stringBounds left + (stringBounds width - (self fontToUse widthOfString: contents) // 2) abs.
+
+ aCanvas
+ drawString: contents
+ in: stringBounds
+ font: self fontToUse
+ color: self colorToUse.!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawSubMenuMarkerOn: (in category 'drawing') -----
+ drawSubMenuMarkerOn: aCanvas
+ "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseDown: (in category 'events') -----
+ mouseDown: evt
+ "Handle a mouse down event. Menu items get activated when the mouse is over them."
+
+ (evt shiftPressed and:[self wantsKeyboardFocusOnShiftClick]) ifTrue: [ ^super mouseDown: evt ].  "enable label editing"
+ isSelected
+ ifTrue: [
+ owner selectItem: nil event: evt. ]
+ ifFalse: [
+ owner activate: evt. "Redirect to menu for valid transitions"
+ owner selectItem: self event: evt. ]
+ !

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'events') -----
- ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'as yet unclassified') -----
  mouseEnter: evt
  "Do not hover docking bar items directory. Mouse-down required. But if you already see a submenu, support hovering."
 
  owner selectedItem ifNotNil: [owner selectItem: self event: evt]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseUp: (in category 'events') -----
+ mouseUp: evt
+ "Handle a mouse up event. Menu items get activated when the mouse is over them. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
+
+ evt hand mouseFocus == owner ifFalse: [ ^self ].
+ self contentString ifNotNil: [
+ self contents: self contentString withMarkers: true inverse: true.
+ self refreshWorld.
+ (Delay forMilliseconds: 200) wait ].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>select: (in category 'selecting') -----
+ select: evt
+
+ super select: evt.
+ subMenu ifNotNil: [
+ evt hand newKeyboardFocus: subMenu ]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>wantsKeyboardFocusOnShiftClick (in category 'events') -----
+ wantsKeyboardFocusOnShiftClick
+ "set this preference to false to prevent user editing of docking bar menu items"
+ ^Preferences valueOfPreference: #allowMenubarItemEditing ifAbsent: [false]!

Item was added:
+ ----- Method: DockingBarUpdatingMenuMorph>>morphicLayerNumber: (in category 'update') -----
+ morphicLayerNumber: n
+
+ super morphicLayerNumber: n.
+ !

Item was changed:
  ----- Method: MenuMorph>>initialize (in category 'initialization') -----
  initialize
  super initialize.
 
  self setDefaultParameters.
 
  self changeTableLayout.
  self listDirection: #topToBottom.
  self hResizing: #shrinkWrap.
  self vResizing: #shrinkWrap.
+ self rubberBandCells: true.
  self disableLayout: true.
  self morphicLayerNumber: self class menuLayer.
  defaultTarget := nil.
  selectedItem := nil.
  stayUp := false.
  popUpOwner := nil.!

Item was changed:
  ----- Method: SystemWindow>>createMenuBox (in category 'initialization') -----
  createMenuBox
  ^ (self createBox: self class menuBoxImage)
  actionSelector: #offerWindowMenu;
+ setBalloonText: 'window menu' translated;
+ actWhen: #buttonDown;
+ yourself!
- setBalloonText: 'window menu' translated!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'right side') -----
  browseChanges
 
  ChangeSorter open.!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'right side') -----
  browseChangesLabel
  "The project name is the same as the current change set."
 
  ^ Project current name!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>changesMenuOn: (in category 'submenu - changes') -----
+ changesMenuOn: aDockingBar
+
+ aDockingBar addUpdatingItem: [:item |
+ item
+ help: 'Browse this project''s changes' translated;
+ wordingProvider: self
+ wordingSelector: #browseChangesLabel;
+ subMenuUpdater: self
+ selector: #listChangesOn:].!

Item was changed:
  ----- Method: TheWorldMainDockingBar>>fillDockingBar: (in category 'construction') -----
  fillDockingBar: aDockingBar
  "Private - fill the given docking bar"
 
  self menusOn: aDockingBar.
  aDockingBar addSpacer.
+ self changesMenuOn: aDockingBar.
- self projectNameOn: aDockingBar.
  aDockingBar addSpacer.
  self rightSideOn: aDockingBar.
  aDockingBar
  setProperty: #mainDockingBarTimeStamp
  toValue: self class timeStamp.!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>listChangesOn: (in category 'submenu - changes') -----
+ listChangesOn: menu
+
+ | latestMethodChanges latestClassChanges|
+ latestMethodChanges := (Array streamContents: [:s |
+ ChangeSet current changedMethodsDo: [:method :changeType :dateAndTime :category |
+ s nextPut: { dateAndTime. method. changeType. category }]])
+ sorted: [:a :b | a first >= b first].
+
+ 1 to: (10 min: latestMethodChanges size) do: [:index | | spec method |
+ spec := latestMethodChanges at: index.
+ method := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} {2} \{{3}\} \{{4}\}' format: {method methodClass. method selector. spec fourth. method methodClass category}) ;
+ target: ToolSet;
+ balloonText: spec third asString;
+ icon: ((#(remove addedThenRemoved) includes: spec third) ifTrue: [MenuIcons smallDeleteIcon] ifFalse: [
+ spec third = #add ifTrue: [MenuIcons smallNewIcon] ifFalse: [MenuIcons blankIcon]]);
+ selector: (method isInstalled ifTrue: [#browseMethod:] ifFalse: [#browseMethodVersion:]);
+ arguments: {method}]].
+
+ latestClassChanges := (Array streamContents: [:s |
+ ChangeSet current changedClassesDo: [:class :changeTypes :dateAndTime :category |
+ "We are not interested in classes whose method's did only change."
+ changeTypes ifNotEmpty: [s nextPut: { dateAndTime. class. changeTypes. category }]]])
+ sorted: [:a :b | a first >= b first].
+
+ latestClassChanges ifNotEmpty: [menu addLine].
+ 1 to: (10 min: latestClassChanges size) do: [:index | | spec class |
+ spec := latestClassChanges at: index.
+ class := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} \{{2}\}' format: {class name. spec fourth }) ;
+ target: ToolSet;
+ balloonText: (spec third sorted joinSeparatedBy: Character space);
+ icon: ((spec third includesAnyOf: #(remove addedThenRemoved))
+ ifTrue: [MenuIcons smallDeleteIcon]
+ ifFalse: [
+ (spec third includes: #add)
+ ifTrue: [MenuIcons smallNewIcon]
+ ifFalse: [MenuIcons blankIcon]]);
+ selector: ((spec third includes: #remove) ifTrue: [#inspect:] ifFalse: [#browseClass:]);
+ arguments: {class}]].
+
+ menu addLine; addItem: [:item |
+ item
+ contents: 'Browse current change set...' translated;
+ target: self;
+ selector: #browseChanges].!

Item was removed:
- ----- Method: TheWorldMainDockingBar>>projectNameOn: (in category 'right side') -----
- projectNameOn: aDockingBar
-
- aDockingBar addUpdatingItem: [:item |
- item
- help: 'Browse this project''s changes';
- target: self;
- selector: #browseChanges;
- wordingProvider: self
- wordingSelector: #browseChangesLabel].!

Item was changed:
+ (PackageInfo named: 'Morphic') postscript: 'TheWorldMainDockingBar updateInstances.'!
- (PackageInfo named: 'Morphic') postscript: 'Transcript showln: ''[NOTICE] There is a new preference called "Interactive print-it". Please check your preference browser to choose the preferred value.'''!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1755.mcz

marcel.taeumel

Am 18.04.2021 19:01:02 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1755.mcz

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

Name: Morphic-mt.1755
Author: mt
Time: 18 April 2021, 7:00:43.878254 pm
UUID: e5705780-2988-a54e-b6c7-21b4194fcd5c
Ancestors: Morphic-mt.1754, Morphic-ct.1659

Fix our two menu-invocating buttons to act on mouse-down and actually look like menus: (1) menu button in system window and (2) change-set button in world-main-docking-bar.

Merges Morphic-ct.1659. Thanks Christoph (ct) for pointing out this issue about menu invocation through buttons. See http://forum.world.st/The-Inbox-Morphic-ct-1659-mcz-tp5116728.html

By example, this commit also adds a menu to the change-set button in the docking bar. This menu lists the latest method and class changes.

To make this work, the following things got addressed:
- Fixes DockingBarUpdatingItemMorph, which missed several changes from DockingBarItemMorph. (Interesting specialization challenge...)
- Let menus #rubberBandCells to allow for changing menu item's widths.
- Adds query about latest changes to #listChangesOn:. (Feel free to improve this. Maybe add preference for number of elements?)

Complements (and depends on) System-mt.1228 and Tools-mt.1042.

=============== Diff against Morphic-mt.1754 ===============

Item was changed:
----- Method: DockingBarMorph>>addUpdatingItem: (in category 'construction') -----
addUpdatingItem: aBlock
| item |
item := DockingBarUpdatingItemMorph new.
aBlock value: item.
+ item subMenu ifNotNil: [:menu |
+ "Docking bar and protruding menu should appear visually merged."
+ menu morphicLayerNumber: self morphicLayerNumber + 1].
self addMorphBack: item!

Item was changed:
----- Method: DockingBarMorph>>ensureSelectedItem: (in category 'events') -----
ensureSelectedItem: evt

self selectedItem ifNil: [
self
selectItem: (
self submorphs
+ detect: [ :each | each isMenuItemMorph ]
- detect: [ :each | each isKindOf: DockingBarItemMorph ]
ifNone: [ ^self ])
event: evt ]!

Item was changed:
----- Method: DockingBarMorph>>filterEvent:for: (in category 'events-processing') -----
filterEvent: aKeyboardEvent for: anObject
"Provide keyboard shortcuts."

| index itemToSelect |

aKeyboardEvent controlKeyPressed
ifFalse: [^ aKeyboardEvent].

aKeyboardEvent isKeystroke
ifFalse: [^ aKeyboardEvent].

"Search field."
aKeyboardEvent keyCharacter = $0
ifTrue: [
self searchBarMorph ifNotNil: [ :morph |
morph model activate: aKeyboardEvent in: morph ].
^ aKeyboardEvent ignore "hit!!"].

"Select menu items."
(aKeyboardEvent keyValue
between: $1 asciiValue
and: $9 asciiValue)
ifFalse: [^ aKeyboardEvent].

index := aKeyboardEvent keyValue - $1 asciiValue + 1.
itemToSelect := (self submorphs select: [ :each |
+ each isMenuItemMorph ])
- each isKindOf: DockingBarItemMorph ])
at: index
ifAbsent: [^ aKeyboardEvent].

self activate: aKeyboardEvent.
self
selectItem: itemToSelect
event: aKeyboardEvent.

^ aKeyboardEvent ignore "hit!!"!

Item was changed:
----- Method: DockingBarMorph>>moveSelectionDown:event: (in category 'control') -----
moveSelectionDown: direction event: evt
"Move the current selection up or down by one, presumably under keyboard control.
direction = +/-1"

| index |
index := (submorphs indexOf: selectedItem ifAbsent: [1-direction]) + direction.
submorphs do: "Ensure finite"
[:unused | | m |
m := submorphs atWrap: index.
+ (m isMenuItemMorph and: [m isEnabled]) ifTrue:
- ((m isKindOf: DockingBarItemMorph) and: [m isEnabled]) ifTrue:
[^ self selectItem: m event: evt].
"Keep looking for an enabled item"
index := index + direction sign].
^ self selectItem: nil event: evt!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>adjacentTo (in category 'selecting') -----
+ adjacentTo
+
+ | roundedCornersOffset verticalOffset |
+ roundedCornersOffset := MenuMorph roundedMenuCorners
+ ifTrue: [Morph preferredCornerRadius negated]
+ ifFalse: [0].
+ verticalOffset := 2.
+
+ owner isFloating
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToTop
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToLeft
+ ifTrue: [^ {self bounds topRight + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToBottom
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToRight
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset negated)}].
+ ^ {self bounds bottomLeft + (roundedCornersOffset @ 5)}!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createSubmenu (in category 'private') -----
+ createSubmenu
+
+ ^DockingBarMenuMorph new!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createUpdatingSubmenu (in category 'private') -----
+ createUpdatingSubmenu
+
+ ^DockingBarUpdatingMenuMorph new!

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'world') -----
- ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'as yet unclassified') -----
decorateOwner

"Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawIconOn: (in category 'drawing') -----
+ drawIconOn: aCanvas
+
+ | pos |
+ self hasIcon ifTrue: [
+ | iconForm |
+ iconForm := self iconForm.
+
+ pos := (contents
+ ifEmpty: [self left + (self width - iconForm width // 2)]
+ ifNotEmpty: [self left])
+ @ (self top + (self height - iconForm height // 2)).
+
+ aCanvas
+ translucentImage: iconForm
+ at: pos].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawLabelOn: (in category 'drawing') -----
+ drawLabelOn: aCanvas
+
+ | stringBounds |
+ self contents ifEmpty: [^ self].
+
+ stringBounds := bounds.
+
+ self hasIcon ifTrue: [
+ stringBounds := stringBounds left: stringBounds left + self iconForm width + 2 ].
+
+ "Vertical centering."
+ stringBounds := stringBounds top: stringBounds top + stringBounds bottom - self fontToUse height // 2.
+ "Horizontal centering."
+ stringBounds := stringBounds left: stringBounds left + (stringBounds width - (self fontToUse widthOfString: contents) // 2) abs.
+
+ aCanvas
+ drawString: contents
+ in: stringBounds
+ font: self fontToUse
+ color: self colorToUse.!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawSubMenuMarkerOn: (in category 'drawing') -----
+ drawSubMenuMarkerOn: aCanvas
+ "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseDown: (in category 'events') -----
+ mouseDown: evt
+ "Handle a mouse down event. Menu items get activated when the mouse is over them."
+
+ (evt shiftPressed and:[self wantsKeyboardFocusOnShiftClick]) ifTrue: [ ^super mouseDown: evt ]. "enable label editing"
+ isSelected
+ ifTrue: [
+ owner selectItem: nil event: evt. ]
+ ifFalse: [
+ owner activate: evt. "Redirect to menu for valid transitions"
+ owner selectItem: self event: evt. ]
+ !

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'events') -----
- ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'as yet unclassified') -----
mouseEnter: evt
"Do not hover docking bar items directory. Mouse-down required. But if you already see a submenu, support hovering."

owner selectedItem ifNotNil: [owner selectItem: self event: evt]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseUp: (in category 'events') -----
+ mouseUp: evt
+ "Handle a mouse up event. Menu items get activated when the mouse is over them. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
+
+ evt hand mouseFocus == owner ifFalse: [ ^self ].
+ self contentString ifNotNil: [
+ self contents: self contentString withMarkers: true inverse: true.
+ self refreshWorld.
+ (Delay forMilliseconds: 200) wait ].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>select: (in category 'selecting') -----
+ select: evt
+
+ super select: evt.
+ subMenu ifNotNil: [
+ evt hand newKeyboardFocus: subMenu ]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>wantsKeyboardFocusOnShiftClick (in category 'events') -----
+ wantsKeyboardFocusOnShiftClick
+ "set this preference to false to prevent user editing of docking bar menu items"
+ ^Preferences valueOfPreference: #allowMenubarItemEditing ifAbsent: [false]!

Item was added:
+ ----- Method: DockingBarUpdatingMenuMorph>>morphicLayerNumber: (in category 'update') -----
+ morphicLayerNumber: n
+
+ super morphicLayerNumber: n.
+ !

Item was changed:
----- Method: MenuMorph>>initialize (in category 'initialization') -----
initialize
super initialize.

self setDefaultParameters.

self changeTableLayout.
self listDirection: #topToBottom.
self hResizing: #shrinkWrap.
self vResizing: #shrinkWrap.
+ self rubberBandCells: true.
self disableLayout: true.
self morphicLayerNumber: self class menuLayer.
defaultTarget := nil.
selectedItem := nil.
stayUp := false.
popUpOwner := nil.!

Item was changed:
----- Method: SystemWindow>>createMenuBox (in category 'initialization') -----
createMenuBox
^ (self createBox: self class menuBoxImage)
actionSelector: #offerWindowMenu;
+ setBalloonText: 'window menu' translated;
+ actWhen: #buttonDown;
+ yourself!
- setBalloonText: 'window menu' translated!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'right side') -----
browseChanges

ChangeSorter open.!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'right side') -----
browseChangesLabel
"The project name is the same as the current change set."

^ Project current name!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>changesMenuOn: (in category 'submenu - changes') -----
+ changesMenuOn: aDockingBar
+
+ aDockingBar addUpdatingItem: [:item |
+ item
+ help: 'Browse this project''s changes' translated;
+ wordingProvider: self
+ wordingSelector: #browseChangesLabel;
+ subMenuUpdater: self
+ selector: #listChangesOn:].!

Item was changed:
----- Method: TheWorldMainDockingBar>>fillDockingBar: (in category 'construction') -----
fillDockingBar: aDockingBar
"Private - fill the given docking bar"

self menusOn: aDockingBar.
aDockingBar addSpacer.
+ self changesMenuOn: aDockingBar.
- self projectNameOn: aDockingBar.
aDockingBar addSpacer.
self rightSideOn: aDockingBar.
aDockingBar
setProperty: #mainDockingBarTimeStamp
toValue: self class timeStamp.!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>listChangesOn: (in category 'submenu - changes') -----
+ listChangesOn: menu
+
+ | latestMethodChanges latestClassChanges|
+ latestMethodChanges := (Array streamContents: [:s |
+ ChangeSet current changedMethodsDo: [:method :changeType :dateAndTime :category |
+ s nextPut: { dateAndTime. method. changeType. category }]])
+ sorted: [:a :b | a first >= b first].
+
+ 1 to: (10 min: latestMethodChanges size) do: [:index | | spec method |
+ spec := latestMethodChanges at: index.
+ method := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} {2} \{{3}\} \{{4}\}' format: {method methodClass. method selector. spec fourth. method methodClass category}) ;
+ target: ToolSet;
+ balloonText: spec third asString;
+ icon: ((#(remove addedThenRemoved) includes: spec third) ifTrue: [MenuIcons smallDeleteIcon] ifFalse: [
+ spec third = #add ifTrue: [MenuIcons smallNewIcon] ifFalse: [MenuIcons blankIcon]]);
+ selector: (method isInstalled ifTrue: [#browseMethod:] ifFalse: [#browseMethodVersion:]);
+ arguments: {method}]].
+
+ latestClassChanges := (Array streamContents: [:s |
+ ChangeSet current changedClassesDo: [:class :changeTypes :dateAndTime :category |
+ "We are not interested in classes whose method's did only change."
+ changeTypes ifNotEmpty: [s nextPut: { dateAndTime. class. changeTypes. category }]]])
+ sorted: [:a :b | a first >= b first].
+
+ latestClassChanges ifNotEmpty: [menu addLine].
+ 1 to: (10 min: latestClassChanges size) do: [:index | | spec class |
+ spec := latestClassChanges at: index.
+ class := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} \{{2}\}' format: {class name. spec fourth }) ;
+ target: ToolSet;
+ balloonText: (spec third sorted joinSeparatedBy: Character space);
+ icon: ((spec third includesAnyOf: #(remove addedThenRemoved))
+ ifTrue: [MenuIcons smallDeleteIcon]
+ ifFalse: [
+ (spec third includes: #add)
+ ifTrue: [MenuIcons smallNewIcon]
+ ifFalse: [MenuIcons blankIcon]]);
+ selector: ((spec third includes: #remove) ifTrue: [#inspect:] ifFalse: [#browseClass:]);
+ arguments: {class}]].
+
+ menu addLine; addItem: [:item |
+ item
+ contents: 'Browse current change set...' translated;
+ target: self;
+ selector: #browseChanges].!

Item was removed:
- ----- Method: TheWorldMainDockingBar>>projectNameOn: (in category 'right side') -----
- projectNameOn: aDockingBar
-
- aDockingBar addUpdatingItem: [:item |
- item
- help: 'Browse this project''s changes';
- target: self;
- selector: #browseChanges;
- wordingProvider: self
- wordingSelector: #browseChangesLabel].!

Item was changed:
+ (PackageInfo named: 'Morphic') postscript: 'TheWorldMainDockingBar updateInstances.'!
- (PackageInfo named: 'Morphic') postscript: 'Transcript showln: ''[NOTICE] There is a new preference called "Interactive print-it". Please check your preference browser to choose the preferred value.'''!




Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1755.mcz

Christoph Thiede

Hi Marcel,


interesting concept, I will try out the usability the next time! Some first thoughts:


  • I very often used this button to open a change sorter window. (The new menu is not bad, but of course, it only offers a subset of all functionalities of a change sorter). Can we maybe move the "Browse" item to the top of the menu?
  • Also, we might want to add a link to the DualChangeSorter there. I use that tool very often and I think this would be a way to access it even faster.

Best,
Christoph



Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Sonntag, 18. April 2021 19:05 Uhr
An: squeak-dev
Betreff: Re: [squeak-dev] The Trunk: Morphic-mt.1755.mcz
 

Am 18.04.2021 19:01:02 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1755.mcz

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

Name: Morphic-mt.1755
Author: mt
Time: 18 April 2021, 7:00:43.878254 pm
UUID: e5705780-2988-a54e-b6c7-21b4194fcd5c
Ancestors: Morphic-mt.1754, Morphic-ct.1659

Fix our two menu-invocating buttons to act on mouse-down and actually look like menus: (1) menu button in system window and (2) change-set button in world-main-docking-bar.

Merges Morphic-ct.1659. Thanks Christoph (ct) for pointing out this issue about menu invocation through buttons. See http://forum.world.st/The-Inbox-Morphic-ct-1659-mcz-tp5116728.html

By example, this commit also adds a menu to the change-set button in the docking bar. This menu lists the latest method and class changes.

To make this work, the following things got addressed:
- Fixes DockingBarUpdatingItemMorph, which missed several changes from DockingBarItemMorph. (Interesting specialization challenge...)
- Let menus #rubberBandCells to allow for changing menu item's widths.
- Adds query about latest changes to #listChangesOn:. (Feel free to improve this. Maybe add preference for number of elements?)

Complements (and depends on) System-mt.1228 and Tools-mt.1042.

=============== Diff against Morphic-mt.1754 ===============

Item was changed:
----- Method: DockingBarMorph>>addUpdatingItem: (in category 'construction') -----
addUpdatingItem: aBlock
| item |
item := DockingBarUpdatingItemMorph new.
aBlock value: item.
+ item subMenu ifNotNil: [:menu |
+ "Docking bar and protruding menu should appear visually merged."
+ menu morphicLayerNumber: self morphicLayerNumber + 1].
self addMorphBack: item!

Item was changed:
----- Method: DockingBarMorph>>ensureSelectedItem: (in category 'events') -----
ensureSelectedItem: evt

self selectedItem ifNil: [
self
selectItem: (
self submorphs
+ detect: [ :each | each isMenuItemMorph ]
- detect: [ :each | each isKindOf: DockingBarItemMorph ]
ifNone: [ ^self ])
event: evt ]!

Item was changed:
----- Method: DockingBarMorph>>filterEvent:for: (in category 'events-processing') -----
filterEvent: aKeyboardEvent for: anObject
"Provide keyboard shortcuts."

| index itemToSelect |

aKeyboardEvent controlKeyPressed
ifFalse: [^ aKeyboardEvent].

aKeyboardEvent isKeystroke
ifFalse: [^ aKeyboardEvent].

"Search field."
aKeyboardEvent keyCharacter = $0
ifTrue: [
self searchBarMorph ifNotNil: [ :morph |
morph model activate: aKeyboardEvent in: morph ].
^ aKeyboardEvent ignore "hit!!"].

"Select menu items."
(aKeyboardEvent keyValue
between: $1 asciiValue
and: $9 asciiValue)
ifFalse: [^ aKeyboardEvent].

index := aKeyboardEvent keyValue - $1 asciiValue + 1.
itemToSelect := (self submorphs select: [ :each |
+ each isMenuItemMorph ])
- each isKindOf: DockingBarItemMorph ])
at: index
ifAbsent: [^ aKeyboardEvent].

self activate: aKeyboardEvent.
self
selectItem: itemToSelect
event: aKeyboardEvent.

^ aKeyboardEvent ignore "hit!!"!

Item was changed:
----- Method: DockingBarMorph>>moveSelectionDown:event: (in category 'control') -----
moveSelectionDown: direction event: evt
"Move the current selection up or down by one, presumably under keyboard control.
direction = +/-1"

| index |
index := (submorphs indexOf: selectedItem ifAbsent: [1-direction]) + direction.
submorphs do: "Ensure finite"
[:unused | | m |
m := submorphs atWrap: index.
+ (m isMenuItemMorph and: [m isEnabled]) ifTrue:
- ((m isKindOf: DockingBarItemMorph) and: [m isEnabled]) ifTrue:
[^ self selectItem: m event: evt].
"Keep looking for an enabled item"
index := index + direction sign].
^ self selectItem: nil event: evt!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>adjacentTo (in category 'selecting') -----
+ adjacentTo
+
+ | roundedCornersOffset verticalOffset |
+ roundedCornersOffset := MenuMorph roundedMenuCorners
+ ifTrue: [Morph preferredCornerRadius negated]
+ ifFalse: [0].
+ verticalOffset := 2.
+
+ owner isFloating
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToTop
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToLeft
+ ifTrue: [^ {self bounds topRight + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToBottom
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToRight
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset negated)}].
+ ^ {self bounds bottomLeft + (roundedCornersOffset @ 5)}!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createSubmenu (in category 'private') -----
+ createSubmenu
+
+ ^DockingBarMenuMorph new!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createUpdatingSubmenu (in category 'private') -----
+ createUpdatingSubmenu
+
+ ^DockingBarUpdatingMenuMorph new!

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'world') -----
- ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'as yet unclassified') -----
decorateOwner

"Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawIconOn: (in category 'drawing') -----
+ drawIconOn: aCanvas
+
+ | pos |
+ self hasIcon ifTrue: [
+ | iconForm |
+ iconForm := self iconForm.
+
+ pos := (contents
+ ifEmpty: [self left + (self width - iconForm width // 2)]
+ ifNotEmpty: [self left])
+ @ (self top + (self height - iconForm height // 2)).
+
+ aCanvas
+ translucentImage: iconForm
+ at: pos].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawLabelOn: (in category 'drawing') -----
+ drawLabelOn: aCanvas
+
+ | stringBounds |
+ self contents ifEmpty: [^ self].
+
+ stringBounds := bounds.
+
+ self hasIcon ifTrue: [
+ stringBounds := stringBounds left: stringBounds left + self iconForm width + 2 ].
+
+ "Vertical centering."
+ stringBounds := stringBounds top: stringBounds top + stringBounds bottom - self fontToUse height // 2.
+ "Horizontal centering."
+ stringBounds := stringBounds left: stringBounds left + (stringBounds width - (self fontToUse widthOfString: contents) // 2) abs.
+
+ aCanvas
+ drawString: contents
+ in: stringBounds
+ font: self fontToUse
+ color: self colorToUse.!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawSubMenuMarkerOn: (in category 'drawing') -----
+ drawSubMenuMarkerOn: aCanvas
+ "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseDown: (in category 'events') -----
+ mouseDown: evt
+ "Handle a mouse down event. Menu items get activated when the mouse is over them."
+
+ (evt shiftPressed and:[self wantsKeyboardFocusOnShiftClick]) ifTrue: [ ^super mouseDown: evt ]. "enable label editing"
+ isSelected
+ ifTrue: [
+ owner selectItem: nil event: evt. ]
+ ifFalse: [
+ owner activate: evt. "Redirect to menu for valid transitions"
+ owner selectItem: self event: evt. ]
+ !

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'events') -----
- ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'as yet unclassified') -----
mouseEnter: evt
"Do not hover docking bar items directory. Mouse-down required. But if you already see a submenu, support hovering."

owner selectedItem ifNotNil: [owner selectItem: self event: evt]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseUp: (in category 'events') -----
+ mouseUp: evt
+ "Handle a mouse up event. Menu items get activated when the mouse is over them. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
+
+ evt hand mouseFocus == owner ifFalse: [ ^self ].
+ self contentString ifNotNil: [
+ self contents: self contentString withMarkers: true inverse: true.
+ self refreshWorld.
+ (Delay forMilliseconds: 200) wait ].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>select: (in category 'selecting') -----
+ select: evt
+
+ super select: evt.
+ subMenu ifNotNil: [
+ evt hand newKeyboardFocus: subMenu ]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>wantsKeyboardFocusOnShiftClick (in category 'events') -----
+ wantsKeyboardFocusOnShiftClick
+ "set this preference to false to prevent user editing of docking bar menu items"
+ ^Preferences valueOfPreference: #allowMenubarItemEditing ifAbsent: [false]!

Item was added:
+ ----- Method: DockingBarUpdatingMenuMorph>>morphicLayerNumber: (in category 'update') -----
+ morphicLayerNumber: n
+
+ super morphicLayerNumber: n.
+ !

Item was changed:
----- Method: MenuMorph>>initialize (in category 'initialization') -----
initialize
super initialize.

self setDefaultParameters.

self changeTableLayout.
self listDirection: #topToBottom.
self hResizing: #shrinkWrap.
self vResizing: #shrinkWrap.
+ self rubberBandCells: true.
self disableLayout: true.
self morphicLayerNumber: self class menuLayer.
defaultTarget := nil.
selectedItem := nil.
stayUp := false.
popUpOwner := nil.!

Item was changed:
----- Method: SystemWindow>>createMenuBox (in category 'initialization') -----
createMenuBox
^ (self createBox: self class menuBoxImage)
actionSelector: #offerWindowMenu;
+ setBalloonText: 'window menu' translated;
+ actWhen: #buttonDown;
+ yourself!
- setBalloonText: 'window menu' translated!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'right side') -----
browseChanges

ChangeSorter open.!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'right side') -----
browseChangesLabel
"The project name is the same as the current change set."

^ Project current name!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>changesMenuOn: (in category 'submenu - changes') -----
+ changesMenuOn: aDockingBar
+
+ aDockingBar addUpdatingItem: [:item |
+ item
+ help: 'Browse this project''s changes' translated;
+ wordingProvider: self
+ wordingSelector: #browseChangesLabel;
+ subMenuUpdater: self
+ selector: #listChangesOn:].!

Item was changed:
----- Method: TheWorldMainDockingBar>>fillDockingBar: (in category 'construction') -----
fillDockingBar: aDockingBar
"Private - fill the given docking bar"

self menusOn: aDockingBar.
aDockingBar addSpacer.
+ self changesMenuOn: aDockingBar.
- self projectNameOn: aDockingBar.
aDockingBar addSpacer.
self rightSideOn: aDockingBar.
aDockingBar
setProperty: #mainDockingBarTimeStamp
toValue: self class timeStamp.!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>listChangesOn: (in category 'submenu - changes') -----
+ listChangesOn: menu
+
+ | latestMethodChanges latestClassChanges|
+ latestMethodChanges := (Array streamContents: [:s |
+ ChangeSet current changedMethodsDo: [:method :changeType :dateAndTime :category |
+ s nextPut: { dateAndTime. method. changeType. category }]])
+ sorted: [:a :b | a first >= b first].
+
+ 1 to: (10 min: latestMethodChanges size) do: [:index | | spec method |
+ spec := latestMethodChanges at: index.
+ method := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} {2} \{{3}\} \{{4}\}' format: {method methodClass. method selector. spec fourth. method methodClass category}) ;
+ target: ToolSet;
+ balloonText: spec third asString;
+ icon: ((#(remove addedThenRemoved) includes: spec third) ifTrue: [MenuIcons smallDeleteIcon] ifFalse: [
+ spec third = #add ifTrue: [MenuIcons smallNewIcon] ifFalse: [MenuIcons blankIcon]]);
+ selector: (method isInstalled ifTrue: [#browseMethod:] ifFalse: [#browseMethodVersion:]);
+ arguments: {method}]].
+
+ latestClassChanges := (Array streamContents: [:s |
+ ChangeSet current changedClassesDo: [:class :changeTypes :dateAndTime :category |
+ "We are not interested in classes whose method's did only change."
+ changeTypes ifNotEmpty: [s nextPut: { dateAndTime. class. changeTypes. category }]]])
+ sorted: [:a :b | a first >= b first].
+
+ latestClassChanges ifNotEmpty: [menu addLine].
+ 1 to: (10 min: latestClassChanges size) do: [:index | | spec class |
+ spec := latestClassChanges at: index.
+ class := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} \{{2}\}' format: {class name. spec fourth }) ;
+ target: ToolSet;
+ balloonText: (spec third sorted joinSeparatedBy: Character space);
+ icon: ((spec third includesAnyOf: #(remove addedThenRemoved))
+ ifTrue: [MenuIcons smallDeleteIcon]
+ ifFalse: [
+ (spec third includes: #add)
+ ifTrue: [MenuIcons smallNewIcon]
+ ifFalse: [MenuIcons blankIcon]]);
+ selector: ((spec third includes: #remove) ifTrue: [#inspect:] ifFalse: [#browseClass:]);
+ arguments: {class}]].
+
+ menu addLine; addItem: [:item |
+ item
+ contents: 'Browse current change set...' translated;
+ target: self;
+ selector: #browseChanges].!

Item was removed:
- ----- Method: TheWorldMainDockingBar>>projectNameOn: (in category 'right side') -----
- projectNameOn: aDockingBar
-
- aDockingBar addUpdatingItem: [:item |
- item
- help: 'Browse this project''s changes';
- target: self;
- selector: #browseChanges;
- wordingProvider: self
- wordingSelector: #browseChangesLabel].!

Item was changed:
+ (PackageInfo named: 'Morphic') postscript: 'TheWorldMainDockingBar updateInstances.'!
- (PackageInfo named: 'Morphic') postscript: 'Transcript showln: ''[NOTICE] There is a new preference called "Interactive print-it". Please check your preference browser to choose the preferred value.'''!




Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1755.mcz

marcel.taeumel
*scnr* https://xkcd.com/1172/ ^__^

Please report whether that list of recent changes makes you (want to) open the (dual) change sorter less often.

Best,
Marcel

Am 19.04.2021 12:58:05 schrieb Thiede, Christoph <[hidden email]>:

Hi Marcel,


interesting concept, I will try out the usability the next time! Some first thoughts:


  • I very often used this button to open a change sorter window. (The new menu is not bad, but of course, it only offers a subset of all functionalities of a change sorter). Can we maybe move the "Browse" item to the top of the menu?
  • Also, we might want to add a link to the DualChangeSorter there. I use that tool very often and I think this would be a way to access it even faster.

Best,
Christoph



Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Sonntag, 18. April 2021 19:05 Uhr
An: squeak-dev
Betreff: Re: [squeak-dev] The Trunk: Morphic-mt.1755.mcz
 

Am 18.04.2021 19:01:02 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1755.mcz

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

Name: Morphic-mt.1755
Author: mt
Time: 18 April 2021, 7:00:43.878254 pm
UUID: e5705780-2988-a54e-b6c7-21b4194fcd5c
Ancestors: Morphic-mt.1754, Morphic-ct.1659

Fix our two menu-invocating buttons to act on mouse-down and actually look like menus: (1) menu button in system window and (2) change-set button in world-main-docking-bar.

Merges Morphic-ct.1659. Thanks Christoph (ct) for pointing out this issue about menu invocation through buttons. See http://forum.world.st/The-Inbox-Morphic-ct-1659-mcz-tp5116728.html

By example, this commit also adds a menu to the change-set button in the docking bar. This menu lists the latest method and class changes.

To make this work, the following things got addressed:
- Fixes DockingBarUpdatingItemMorph, which missed several changes from DockingBarItemMorph. (Interesting specialization challenge...)
- Let menus #rubberBandCells to allow for changing menu item's widths.
- Adds query about latest changes to #listChangesOn:. (Feel free to improve this. Maybe add preference for number of elements?)

Complements (and depends on) System-mt.1228 and Tools-mt.1042.

=============== Diff against Morphic-mt.1754 ===============

Item was changed:
----- Method: DockingBarMorph>>addUpdatingItem: (in category 'construction') -----
addUpdatingItem: aBlock
| item |
item := DockingBarUpdatingItemMorph new.
aBlock value: item.
+ item subMenu ifNotNil: [:menu |
+ "Docking bar and protruding menu should appear visually merged."
+ menu morphicLayerNumber: self morphicLayerNumber + 1].
self addMorphBack: item!

Item was changed:
----- Method: DockingBarMorph>>ensureSelectedItem: (in category 'events') -----
ensureSelectedItem: evt

self selectedItem ifNil: [
self
selectItem: (
self submorphs
+ detect: [ :each | each isMenuItemMorph ]
- detect: [ :each | each isKindOf: DockingBarItemMorph ]
ifNone: [ ^self ])
event: evt ]!

Item was changed:
----- Method: DockingBarMorph>>filterEvent:for: (in category 'events-processing') -----
filterEvent: aKeyboardEvent for: anObject
"Provide keyboard shortcuts."

| index itemToSelect |

aKeyboardEvent controlKeyPressed
ifFalse: [^ aKeyboardEvent].

aKeyboardEvent isKeystroke
ifFalse: [^ aKeyboardEvent].

"Search field."
aKeyboardEvent keyCharacter = $0
ifTrue: [
self searchBarMorph ifNotNil: [ :morph |
morph model activate: aKeyboardEvent in: morph ].
^ aKeyboardEvent ignore "hit!!"].

"Select menu items."
(aKeyboardEvent keyValue
between: $1 asciiValue
and: $9 asciiValue)
ifFalse: [^ aKeyboardEvent].

index := aKeyboardEvent keyValue - $1 asciiValue + 1.
itemToSelect := (self submorphs select: [ :each |
+ each isMenuItemMorph ])
- each isKindOf: DockingBarItemMorph ])
at: index
ifAbsent: [^ aKeyboardEvent].

self activate: aKeyboardEvent.
self
selectItem: itemToSelect
event: aKeyboardEvent.

^ aKeyboardEvent ignore "hit!!"!

Item was changed:
----- Method: DockingBarMorph>>moveSelectionDown:event: (in category 'control') -----
moveSelectionDown: direction event: evt
"Move the current selection up or down by one, presumably under keyboard control.
direction = +/-1"

| index |
index := (submorphs indexOf: selectedItem ifAbsent: [1-direction]) + direction.
submorphs do: "Ensure finite"
[:unused | | m |
m := submorphs atWrap: index.
+ (m isMenuItemMorph and: [m isEnabled]) ifTrue:
- ((m isKindOf: DockingBarItemMorph) and: [m isEnabled]) ifTrue:
[^ self selectItem: m event: evt].
"Keep looking for an enabled item"
index := index + direction sign].
^ self selectItem: nil event: evt!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>adjacentTo (in category 'selecting') -----
+ adjacentTo
+
+ | roundedCornersOffset verticalOffset |
+ roundedCornersOffset := MenuMorph roundedMenuCorners
+ ifTrue: [Morph preferredCornerRadius negated]
+ ifFalse: [0].
+ verticalOffset := 2.
+
+ owner isFloating
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToTop
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToLeft
+ ifTrue: [^ {self bounds topRight + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToBottom
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToRight
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset negated)}].
+ ^ {self bounds bottomLeft + (roundedCornersOffset @ 5)}!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createSubmenu (in category 'private') -----
+ createSubmenu
+
+ ^DockingBarMenuMorph new!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createUpdatingSubmenu (in category 'private') -----
+ createUpdatingSubmenu
+
+ ^DockingBarUpdatingMenuMorph new!

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'world') -----
- ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'as yet unclassified') -----
decorateOwner

"Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawIconOn: (in category 'drawing') -----
+ drawIconOn: aCanvas
+
+ | pos |
+ self hasIcon ifTrue: [
+ | iconForm |
+ iconForm := self iconForm.
+
+ pos := (contents
+ ifEmpty: [self left + (self width - iconForm width // 2)]
+ ifNotEmpty: [self left])
+ @ (self top + (self height - iconForm height // 2)).
+
+ aCanvas
+ translucentImage: iconForm
+ at: pos].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawLabelOn: (in category 'drawing') -----
+ drawLabelOn: aCanvas
+
+ | stringBounds |
+ self contents ifEmpty: [^ self].
+
+ stringBounds := bounds.
+
+ self hasIcon ifTrue: [
+ stringBounds := stringBounds left: stringBounds left + self iconForm width + 2 ].
+
+ "Vertical centering."
+ stringBounds := stringBounds top: stringBounds top + stringBounds bottom - self fontToUse height // 2.
+ "Horizontal centering."
+ stringBounds := stringBounds left: stringBounds left + (stringBounds width - (self fontToUse widthOfString: contents) // 2) abs.
+
+ aCanvas
+ drawString: contents
+ in: stringBounds
+ font: self fontToUse
+ color: self colorToUse.!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawSubMenuMarkerOn: (in category 'drawing') -----
+ drawSubMenuMarkerOn: aCanvas
+ "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseDown: (in category 'events') -----
+ mouseDown: evt
+ "Handle a mouse down event. Menu items get activated when the mouse is over them."
+
+ (evt shiftPressed and:[self wantsKeyboardFocusOnShiftClick]) ifTrue: [ ^super mouseDown: evt ]. "enable label editing"
+ isSelected
+ ifTrue: [
+ owner selectItem: nil event: evt. ]
+ ifFalse: [
+ owner activate: evt. "Redirect to menu for valid transitions"
+ owner selectItem: self event: evt. ]
+ !

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'events') -----
- ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'as yet unclassified') -----
mouseEnter: evt
"Do not hover docking bar items directory. Mouse-down required. But if you already see a submenu, support hovering."

owner selectedItem ifNotNil: [owner selectItem: self event: evt]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseUp: (in category 'events') -----
+ mouseUp: evt
+ "Handle a mouse up event. Menu items get activated when the mouse is over them. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
+
+ evt hand mouseFocus == owner ifFalse: [ ^self ].
+ self contentString ifNotNil: [
+ self contents: self contentString withMarkers: true inverse: true.
+ self refreshWorld.
+ (Delay forMilliseconds: 200) wait ].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>select: (in category 'selecting') -----
+ select: evt
+
+ super select: evt.
+ subMenu ifNotNil: [
+ evt hand newKeyboardFocus: subMenu ]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>wantsKeyboardFocusOnShiftClick (in category 'events') -----
+ wantsKeyboardFocusOnShiftClick
+ "set this preference to false to prevent user editing of docking bar menu items"
+ ^Preferences valueOfPreference: #allowMenubarItemEditing ifAbsent: [false]!

Item was added:
+ ----- Method: DockingBarUpdatingMenuMorph>>morphicLayerNumber: (in category 'update') -----
+ morphicLayerNumber: n
+
+ super morphicLayerNumber: n.
+ !

Item was changed:
----- Method: MenuMorph>>initialize (in category 'initialization') -----
initialize
super initialize.

self setDefaultParameters.

self changeTableLayout.
self listDirection: #topToBottom.
self hResizing: #shrinkWrap.
self vResizing: #shrinkWrap.
+ self rubberBandCells: true.
self disableLayout: true.
self morphicLayerNumber: self class menuLayer.
defaultTarget := nil.
selectedItem := nil.
stayUp := false.
popUpOwner := nil.!

Item was changed:
----- Method: SystemWindow>>createMenuBox (in category 'initialization') -----
createMenuBox
^ (self createBox: self class menuBoxImage)
actionSelector: #offerWindowMenu;
+ setBalloonText: 'window menu' translated;
+ actWhen: #buttonDown;
+ yourself!
- setBalloonText: 'window menu' translated!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'right side') -----
browseChanges

ChangeSorter open.!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'right side') -----
browseChangesLabel
"The project name is the same as the current change set."

^ Project current name!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>changesMenuOn: (in category 'submenu - changes') -----
+ changesMenuOn: aDockingBar
+
+ aDockingBar addUpdatingItem: [:item |
+ item
+ help: 'Browse this project''s changes' translated;
+ wordingProvider: self
+ wordingSelector: #browseChangesLabel;
+ subMenuUpdater: self
+ selector: #listChangesOn:].!

Item was changed:
----- Method: TheWorldMainDockingBar>>fillDockingBar: (in category 'construction') -----
fillDockingBar: aDockingBar
"Private - fill the given docking bar"

self menusOn: aDockingBar.
aDockingBar addSpacer.
+ self changesMenuOn: aDockingBar.
- self projectNameOn: aDockingBar.
aDockingBar addSpacer.
self rightSideOn: aDockingBar.
aDockingBar
setProperty: #mainDockingBarTimeStamp
toValue: self class timeStamp.!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>listChangesOn: (in category 'submenu - changes') -----
+ listChangesOn: menu
+
+ | latestMethodChanges latestClassChanges|
+ latestMethodChanges := (Array streamContents: [:s |
+ ChangeSet current changedMethodsDo: [:method :changeType :dateAndTime :category |
+ s nextPut: { dateAndTime. method. changeType. category }]])
+ sorted: [:a :b | a first >= b first].
+
+ 1 to: (10 min: latestMethodChanges size) do: [:index | | spec method |
+ spec := latestMethodChanges at: index.
+ method := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} {2} \{{3}\} \{{4}\}' format: {method methodClass. method selector. spec fourth. method methodClass category}) ;
+ target: ToolSet;
+ balloonText: spec third asString;
+ icon: ((#(remove addedThenRemoved) includes: spec third) ifTrue: [MenuIcons smallDeleteIcon] ifFalse: [
+ spec third = #add ifTrue: [MenuIcons smallNewIcon] ifFalse: [MenuIcons blankIcon]]);
+ selector: (method isInstalled ifTrue: [#browseMethod:] ifFalse: [#browseMethodVersion:]);
+ arguments: {method}]].
+
+ latestClassChanges := (Array streamContents: [:s |
+ ChangeSet current changedClassesDo: [:class :changeTypes :dateAndTime :category |
+ "We are not interested in classes whose method's did only change."
+ changeTypes ifNotEmpty: [s nextPut: { dateAndTime. class. changeTypes. category }]]])
+ sorted: [:a :b | a first >= b first].
+
+ latestClassChanges ifNotEmpty: [menu addLine].
+ 1 to: (10 min: latestClassChanges size) do: [:index | | spec class |
+ spec := latestClassChanges at: index.
+ class := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} \{{2}\}' format: {class name. spec fourth }) ;
+ target: ToolSet;
+ balloonText: (spec third sorted joinSeparatedBy: Character space);
+ icon: ((spec third includesAnyOf: #(remove addedThenRemoved))
+ ifTrue: [MenuIcons smallDeleteIcon]
+ ifFalse: [
+ (spec third includes: #add)
+ ifTrue: [MenuIcons smallNewIcon]
+ ifFalse: [MenuIcons blankIcon]]);
+ selector: ((spec third includes: #remove) ifTrue: [#inspect:] ifFalse: [#browseClass:]);
+ arguments: {class}]].
+
+ menu addLine; addItem: [:item |
+ item
+ contents: 'Browse current change set...' translated;
+ target: self;
+ selector: #browseChanges].!

Item was removed:
- ----- Method: TheWorldMainDockingBar>>projectNameOn: (in category 'right side') -----
- projectNameOn: aDockingBar
-
- aDockingBar addUpdatingItem: [:item |
- item
- help: 'Browse this project''s changes';
- target: self;
- selector: #browseChanges;
- wordingProvider: self
- wordingSelector: #browseChangesLabel].!

Item was changed:
+ (PackageInfo named: 'Morphic') postscript: 'TheWorldMainDockingBar updateInstances.'!
- (PackageInfo named: 'Morphic') postscript: 'Transcript showln: ''[NOTICE] There is a new preference called "Interactive print-it". Please check your preference browser to choose the preferred value.'''!




Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1755.mcz

Christoph Thiede

Fair point and nice comic! :-) I will keep this in mind and report back later ...


Maybe we could need some kind of telemetry solution to make such evaluation more efficient. :D


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Dienstag, 20. April 2021 10:15:31
An: squeak-dev
Betreff: Re: [squeak-dev] The Trunk: Morphic-mt.1755.mcz
 
*scnr* https://xkcd.com/1172/ ^__^

Please report whether that list of recent changes makes you (want to) open the (dual) change sorter less often.

Best,
Marcel

Am 19.04.2021 12:58:05 schrieb Thiede, Christoph <[hidden email]>:

Hi Marcel,


interesting concept, I will try out the usability the next time! Some first thoughts:


  • I very often used this button to open a change sorter window. (The new menu is not bad, but of course, it only offers a subset of all functionalities of a change sorter). Can we maybe move the "Browse" item to the top of the menu?
  • Also, we might want to add a link to the DualChangeSorter there. I use that tool very often and I think this would be a way to access it even faster.

Best,
Christoph



Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Sonntag, 18. April 2021 19:05 Uhr
An: squeak-dev
Betreff: Re: [squeak-dev] The Trunk: Morphic-mt.1755.mcz
 

Am 18.04.2021 19:01:02 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1755.mcz

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

Name: Morphic-mt.1755
Author: mt
Time: 18 April 2021, 7:00:43.878254 pm
UUID: e5705780-2988-a54e-b6c7-21b4194fcd5c
Ancestors: Morphic-mt.1754, Morphic-ct.1659

Fix our two menu-invocating buttons to act on mouse-down and actually look like menus: (1) menu button in system window and (2) change-set button in world-main-docking-bar.

Merges Morphic-ct.1659. Thanks Christoph (ct) for pointing out this issue about menu invocation through buttons. See http://forum.world.st/The-Inbox-Morphic-ct-1659-mcz-tp5116728.html

By example, this commit also adds a menu to the change-set button in the docking bar. This menu lists the latest method and class changes.

To make this work, the following things got addressed:
- Fixes DockingBarUpdatingItemMorph, which missed several changes from DockingBarItemMorph. (Interesting specialization challenge...)
- Let menus #rubberBandCells to allow for changing menu item's widths.
- Adds query about latest changes to #listChangesOn:. (Feel free to improve this. Maybe add preference for number of elements?)

Complements (and depends on) System-mt.1228 and Tools-mt.1042.

=============== Diff against Morphic-mt.1754 ===============

Item was changed:
----- Method: DockingBarMorph>>addUpdatingItem: (in category 'construction') -----
addUpdatingItem: aBlock
| item |
item := DockingBarUpdatingItemMorph new.
aBlock value: item.
+ item subMenu ifNotNil: [:menu |
+ "Docking bar and protruding menu should appear visually merged."
+ menu morphicLayerNumber: self morphicLayerNumber + 1].
self addMorphBack: item!

Item was changed:
----- Method: DockingBarMorph>>ensureSelectedItem: (in category 'events') -----
ensureSelectedItem: evt

self selectedItem ifNil: [
self
selectItem: (
self submorphs
+ detect: [ :each | each isMenuItemMorph ]
- detect: [ :each | each isKindOf: DockingBarItemMorph ]
ifNone: [ ^self ])
event: evt ]!

Item was changed:
----- Method: DockingBarMorph>>filterEvent:for: (in category 'events-processing') -----
filterEvent: aKeyboardEvent for: anObject
"Provide keyboard shortcuts."

| index itemToSelect |

aKeyboardEvent controlKeyPressed
ifFalse: [^ aKeyboardEvent].

aKeyboardEvent isKeystroke
ifFalse: [^ aKeyboardEvent].

"Search field."
aKeyboardEvent keyCharacter = $0
ifTrue: [
self searchBarMorph ifNotNil: [ :morph |
morph model activate: aKeyboardEvent in: morph ].
^ aKeyboardEvent ignore "hit!!"].

"Select menu items."
(aKeyboardEvent keyValue
between: $1 asciiValue
and: $9 asciiValue)
ifFalse: [^ aKeyboardEvent].

index := aKeyboardEvent keyValue - $1 asciiValue + 1.
itemToSelect := (self submorphs select: [ :each |
+ each isMenuItemMorph ])
- each isKindOf: DockingBarItemMorph ])
at: index
ifAbsent: [^ aKeyboardEvent].

self activate: aKeyboardEvent.
self
selectItem: itemToSelect
event: aKeyboardEvent.

^ aKeyboardEvent ignore "hit!!"!

Item was changed:
----- Method: DockingBarMorph>>moveSelectionDown:event: (in category 'control') -----
moveSelectionDown: direction event: evt
"Move the current selection up or down by one, presumably under keyboard control.
direction = +/-1"

| index |
index := (submorphs indexOf: selectedItem ifAbsent: [1-direction]) + direction.
submorphs do: "Ensure finite"
[:unused | | m |
m := submorphs atWrap: index.
+ (m isMenuItemMorph and: [m isEnabled]) ifTrue:
- ((m isKindOf: DockingBarItemMorph) and: [m isEnabled]) ifTrue:
[^ self selectItem: m event: evt].
"Keep looking for an enabled item"
index := index + direction sign].
^ self selectItem: nil event: evt!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>adjacentTo (in category 'selecting') -----
+ adjacentTo
+
+ | roundedCornersOffset verticalOffset |
+ roundedCornersOffset := MenuMorph roundedMenuCorners
+ ifTrue: [Morph preferredCornerRadius negated]
+ ifFalse: [0].
+ verticalOffset := 2.
+
+ owner isFloating
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToTop
+ ifTrue: [^ {self bounds bottomLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToLeft
+ ifTrue: [^ {self bounds topRight + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToBottom
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset)}].
+ owner isAdheringToRight
+ ifTrue: [^ {self bounds topLeft + (roundedCornersOffset @ verticalOffset negated)}].
+ ^ {self bounds bottomLeft + (roundedCornersOffset @ 5)}!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createSubmenu (in category 'private') -----
+ createSubmenu
+
+ ^DockingBarMenuMorph new!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>createUpdatingSubmenu (in category 'private') -----
+ createUpdatingSubmenu
+
+ ^DockingBarUpdatingMenuMorph new!

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'world') -----
- ----- Method: DockingBarUpdatingItemMorph>>decorateOwner (in category 'as yet unclassified') -----
decorateOwner

"Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawIconOn: (in category 'drawing') -----
+ drawIconOn: aCanvas
+
+ | pos |
+ self hasIcon ifTrue: [
+ | iconForm |
+ iconForm := self iconForm.
+
+ pos := (contents
+ ifEmpty: [self left + (self width - iconForm width // 2)]
+ ifNotEmpty: [self left])
+ @ (self top + (self height - iconForm height // 2)).
+
+ aCanvas
+ translucentImage: iconForm
+ at: pos].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawLabelOn: (in category 'drawing') -----
+ drawLabelOn: aCanvas
+
+ | stringBounds |
+ self contents ifEmpty: [^ self].
+
+ stringBounds := bounds.
+
+ self hasIcon ifTrue: [
+ stringBounds := stringBounds left: stringBounds left + self iconForm width + 2 ].
+
+ "Vertical centering."
+ stringBounds := stringBounds top: stringBounds top + stringBounds bottom - self fontToUse height // 2.
+ "Horizontal centering."
+ stringBounds := stringBounds left: stringBounds left + (stringBounds width - (self fontToUse widthOfString: contents) // 2) abs.
+
+ aCanvas
+ drawString: contents
+ in: stringBounds
+ font: self fontToUse
+ color: self colorToUse.!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>drawSubMenuMarkerOn: (in category 'drawing') -----
+ drawSubMenuMarkerOn: aCanvas
+ "Ignore."!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseDown: (in category 'events') -----
+ mouseDown: evt
+ "Handle a mouse down event. Menu items get activated when the mouse is over them."
+
+ (evt shiftPressed and:[self wantsKeyboardFocusOnShiftClick]) ifTrue: [ ^super mouseDown: evt ]. "enable label editing"
+ isSelected
+ ifTrue: [
+ owner selectItem: nil event: evt. ]
+ ifFalse: [
+ owner activate: evt. "Redirect to menu for valid transitions"
+ owner selectItem: self event: evt. ]
+ !

Item was changed:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'events') -----
- ----- Method: DockingBarUpdatingItemMorph>>mouseEnter: (in category 'as yet unclassified') -----
mouseEnter: evt
"Do not hover docking bar items directory. Mouse-down required. But if you already see a submenu, support hovering."

owner selectedItem ifNotNil: [owner selectItem: self event: evt]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>mouseUp: (in category 'events') -----
+ mouseUp: evt
+ "Handle a mouse up event. Menu items get activated when the mouse is over them. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
+
+ evt hand mouseFocus == owner ifFalse: [ ^self ].
+ self contentString ifNotNil: [
+ self contents: self contentString withMarkers: true inverse: true.
+ self refreshWorld.
+ (Delay forMilliseconds: 200) wait ].!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>select: (in category 'selecting') -----
+ select: evt
+
+ super select: evt.
+ subMenu ifNotNil: [
+ evt hand newKeyboardFocus: subMenu ]!

Item was added:
+ ----- Method: DockingBarUpdatingItemMorph>>wantsKeyboardFocusOnShiftClick (in category 'events') -----
+ wantsKeyboardFocusOnShiftClick
+ "set this preference to false to prevent user editing of docking bar menu items"
+ ^Preferences valueOfPreference: #allowMenubarItemEditing ifAbsent: [false]!

Item was added:
+ ----- Method: DockingBarUpdatingMenuMorph>>morphicLayerNumber: (in category 'update') -----
+ morphicLayerNumber: n
+
+ super morphicLayerNumber: n.
+ !

Item was changed:
----- Method: MenuMorph>>initialize (in category 'initialization') -----
initialize
super initialize.

self setDefaultParameters.

self changeTableLayout.
self listDirection: #topToBottom.
self hResizing: #shrinkWrap.
self vResizing: #shrinkWrap.
+ self rubberBandCells: true.
self disableLayout: true.
self morphicLayerNumber: self class menuLayer.
defaultTarget := nil.
selectedItem := nil.
stayUp := false.
popUpOwner := nil.!

Item was changed:
----- Method: SystemWindow>>createMenuBox (in category 'initialization') -----
createMenuBox
^ (self createBox: self class menuBoxImage)
actionSelector: #offerWindowMenu;
+ setBalloonText: 'window menu' translated;
+ actWhen: #buttonDown;
+ yourself!
- setBalloonText: 'window menu' translated!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChanges (in category 'right side') -----
browseChanges

ChangeSorter open.!

Item was changed:
+ ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'submenu - changes') -----
- ----- Method: TheWorldMainDockingBar>>browseChangesLabel (in category 'right side') -----
browseChangesLabel
"The project name is the same as the current change set."

^ Project current name!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>changesMenuOn: (in category 'submenu - changes') -----
+ changesMenuOn: aDockingBar
+
+ aDockingBar addUpdatingItem: [:item |
+ item
+ help: 'Browse this project''s changes' translated;
+ wordingProvider: self
+ wordingSelector: #browseChangesLabel;
+ subMenuUpdater: self
+ selector: #listChangesOn:].!

Item was changed:
----- Method: TheWorldMainDockingBar>>fillDockingBar: (in category 'construction') -----
fillDockingBar: aDockingBar
"Private - fill the given docking bar"

self menusOn: aDockingBar.
aDockingBar addSpacer.
+ self changesMenuOn: aDockingBar.
- self projectNameOn: aDockingBar.
aDockingBar addSpacer.
self rightSideOn: aDockingBar.
aDockingBar
setProperty: #mainDockingBarTimeStamp
toValue: self class timeStamp.!

Item was added:
+ ----- Method: TheWorldMainDockingBar>>listChangesOn: (in category 'submenu - changes') -----
+ listChangesOn: menu
+
+ | latestMethodChanges latestClassChanges|
+ latestMethodChanges := (Array streamContents: [:s |
+ ChangeSet current changedMethodsDo: [:method :changeType :dateAndTime :category |
+ s nextPut: { dateAndTime. method. changeType. category }]])
+ sorted: [:a :b | a first >= b first].
+
+ 1 to: (10 min: latestMethodChanges size) do: [:index | | spec method |
+ spec := latestMethodChanges at: index.
+ method := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} {2} \{{3}\} \{{4}\}' format: {method methodClass. method selector. spec fourth. method methodClass category}) ;
+ target: ToolSet;
+ balloonText: spec third asString;
+ icon: ((#(remove addedThenRemoved) includes: spec third) ifTrue: [MenuIcons smallDeleteIcon] ifFalse: [
+ spec third = #add ifTrue: [MenuIcons smallNewIcon] ifFalse: [MenuIcons blankIcon]]);
+ selector: (method isInstalled ifTrue: [#browseMethod:] ifFalse: [#browseMethodVersion:]);
+ arguments: {method}]].
+
+ latestClassChanges := (Array streamContents: [:s |
+ ChangeSet current changedClassesDo: [:class :changeTypes :dateAndTime :category |
+ "We are not interested in classes whose method's did only change."
+ changeTypes ifNotEmpty: [s nextPut: { dateAndTime. class. changeTypes. category }]]])
+ sorted: [:a :b | a first >= b first].
+
+ latestClassChanges ifNotEmpty: [menu addLine].
+ 1 to: (10 min: latestClassChanges size) do: [:index | | spec class |
+ spec := latestClassChanges at: index.
+ class := spec second.
+ menu addItem: [:item |
+ item
+ contents: ('{1} \{{2}\}' format: {class name. spec fourth }) ;
+ target: ToolSet;
+ balloonText: (spec third sorted joinSeparatedBy: Character space);
+ icon: ((spec third includesAnyOf: #(remove addedThenRemoved))
+ ifTrue: [MenuIcons smallDeleteIcon]
+ ifFalse: [
+ (spec third includes: #add)
+ ifTrue: [MenuIcons smallNewIcon]
+ ifFalse: [MenuIcons blankIcon]]);
+ selector: ((spec third includes: #remove) ifTrue: [#inspect:] ifFalse: [#browseClass:]);
+ arguments: {class}]].
+
+ menu addLine; addItem: [:item |
+ item
+ contents: 'Browse current change set...' translated;
+ target: self;
+ selector: #browseChanges].!

Item was removed:
- ----- Method: TheWorldMainDockingBar>>projectNameOn: (in category 'right side') -----
- projectNameOn: aDockingBar
-
- aDockingBar addUpdatingItem: [:item |
- item
- help: 'Browse this project''s changes';
- target: self;
- selector: #browseChanges;
- wordingProvider: self
- wordingSelector: #browseChangesLabel].!

Item was changed:
+ (PackageInfo named: 'Morphic') postscript: 'TheWorldMainDockingBar updateInstances.'!
- (PackageInfo named: 'Morphic') postscript: 'Transcript showln: ''[NOTICE] There is a new preference called "Interactive print-it". Please check your preference browser to choose the preferred value.'''!




Carpe Squeak!