The Trunk: Morphic-kb.234.mcz

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

The Trunk: Morphic-kb.234.mcz

commits-2
Andreas Raab uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-kb.234.mcz

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

Name: Morphic-kb.234
Author: kb
Time: 17 November 2009, 3:33:35 am
UUID: 4ee0d3b4-ba97-7e44-89fb-c563943622ad
Ancestors: Morphic-kb.233

 - fix: there was a bug in Morphic-kb.232 concerning the newly introduced behaviour: "A menu item with a submenu releases its selection only if the mouse doesn't move towards the submenu."

=============== Diff against Morphic-nice.231 ===============

Item was changed:
  StringMorph subclass: #MenuItemMorph
+ instanceVariableNames: 'isEnabled subMenu isSelected target selector arguments icon lastMousePosition'
- instanceVariableNames: 'isEnabled subMenu isSelected target selector arguments icon'
  classVariableNames: 'SubMenuMarker'
  poolDictionaries: ''
  category: 'Morphic-Menus'!
 
  !MenuItemMorph commentStamp: '<historical>' prior: 0!
  I represent an item in a menu.
 
  Instance variables:
  isEnabled <Boolean> True if the menu item can be executed.
  subMenu <MenuMorph | nil> The submenu to activate automatically when the user mouses over the item.
  isSelected <Boolean> True if the item is currently selected.
  target <Object> The target of the associated action.
  selector <Symbol> The associated action.
  arguments <Array> The arguments for the associated action.
  icon <Form | nil> An optional icon form to be displayed to my left.
 
  If I have a dynamic marker, created by strings like <yes> or <no> in my contents, it will be installed as a submorph.!

Item was added:
+ ----- Method: MenuMorph>>handleMouseMove: (in category 'events') -----
+ handleMouseMove: evt
+ " If the mouse moves over an item not selected, we try to set it as selected.
+ If this happens depends on that the current selected item wants to release
+ its selection. "
+
+ self selectedItem ifNil: [ ^super handleMouseMove: evt ].
+ (self selectedItem containsPoint: evt position) ifTrue: [ ^super handleMouseMove: evt ].
+ self
+ selectItem: (
+ self items
+ detect: [ :each | each containsPoint: evt position ]
+ ifNone: [ ^super handleMouseMove: evt ])
+ event: evt.
+ super handleMouseMove: evt!

Item was changed:
  ----- Method: MenuItemMorph>>mouseLeaveDragging: (in category 'events') -----
  mouseLeaveDragging: evt
  "The mouse left the receiver. Do nothing if we're not in a 'valid menu transition', meaning that the current hand focus must be aimed at the owning menu."
 
  owner ifNil: [^self].
  evt hand mouseFocus == owner ifFalse: [^self].
  "If we have a submenu, make sure we've got some time to enter it before actually leaving the menu item"
+ subMenu isNil ifTrue: [ owner selectItem: nil event: evt ]!
- subMenu isNil
- ifTrue: [owner selectItem: nil event: evt]
- ifFalse:
- [self
- addAlarm: #deselectTimeOut:
- with: evt
- after: 500]!

Item was added:
+ ----- Method: MenuItemMorph>>triangle:containsPoint: (in category 'geometry-testing') -----
+ triangle: points containsPoint: p
+ " Computes if p is in the triangle defined by points.
+ p should be a Point, and points should be an array with three Points.
+ I took the algorithm from the bottom of this page:
+ http://www.blackpawn.com/texts/pointinpoly/default.html "
+
+ | a b c v0 v1 v2 dot00 dot01 dot02 dot11 dot12 denom invDenom u v |
+ a := points first.
+ b := points second.
+ c := points third.
+ " Compute vectors "
+ v0 := c - a.
+ v1 := b - a.
+ v2 := p - a.
+ " Compute dot products "
+ dot00 := v0 dotProduct: v0.
+ dot01 := v0 dotProduct: v1.
+ dot02 := v0 dotProduct: v2.
+ dot11 := v1 dotProduct: v1.
+ dot12 := v1 dotProduct: v2.
+ " Compute barycentric coordinates "
+ denom := dot00 * dot11 - (dot01 * dot01).
+ denom = 0 ifTrue: [ ^false ].
+ invDenom := 1 / denom.
+ u := (dot11 * dot02 - (dot01 * dot12)) * invDenom.
+ v := (dot00 * dot12 - (dot01 * dot02)) * invDenom.
+ " Check if point is in triangle "
+ ^u >= 0 and: [ v >= 0 and: [ u + v <= 1 ] ]!

Item was changed:
  ----- Method: MenuMorph>>selectItem:event: (in category 'control') -----
  selectItem: aMenuItem event: anEvent
+
+ " Change the selected item, but first ask the currently selected item
+ if it want to release it. "
+ (self releasesSelection: anEvent) ifFalse: [ ^self ].
  selectedItem ifNotNil:[selectedItem deselect: anEvent].
  selectedItem := aMenuItem.
  selectedItem ifNotNil:[selectedItem select: anEvent].!

Item was added:
+ ----- Method: MenuItemMorph>>releasesSelection: (in category 'events') -----
+ releasesSelection: evt
+ " Returns a boolean indicating that this menu item is ready to go deselected.
+ It answers false if the mouse is moving towards its submenu.
+ We check this by testing that the current mouse position lays in the triangle of
+ the last mouse position and the two corners of the submenu facing our menu item. "
+
+ | triangle submenuIsOnTheRightSide |
+ self hasSubMenu ifFalse: [
+ lastMousePosition := nil.
+ ^true ].
+ lastMousePosition ifNil: [
+ lastMousePosition := evt position.
+ ^false ].
+ submenuIsOnTheRightSide := self left < subMenu left.
+ triangle := {
+ lastMousePosition.
+ submenuIsOnTheRightSide
+ ifTrue: [ subMenu topLeft ]
+ ifFalse: [ subMenu topRight ].
+ submenuIsOnTheRightSide
+ ifTrue: [ subMenu bottomLeft ]
+ ifFalse: [ subMenu bottomRight ] }.
+ lastMousePosition := evt position.
+ (self triangle: triangle containsPoint: evt position)
+ ifTrue: [ ^false ]
+ ifFalse: [
+ lastMousePosition := nil.
+ ^true ]!

Item was changed:
  ----- Method: MenuItemMorph>>veryDeepInner: (in category 'copying') -----
  veryDeepInner: deepCopier
  "Copy all of my instance variables. Some need to be not copied  
  at all, but shared. Warning!!!! Every instance variable defined in  
  this class must be handled. We must also implement  
  veryDeepFixupWith:. See DeepCopier class comment."
  super veryDeepInner: deepCopier.
  isEnabled := isEnabled veryDeepCopyWith: deepCopier.
  subMenu := subMenu veryDeepCopyWith: deepCopier.
  isSelected := isSelected veryDeepCopyWith: deepCopier.
  icon := icon veryDeepCopyWith: deepCopier.
  "target := target. Weakly copied"
  "selector := selector. a Symbol"
+ arguments := arguments.
+ lastMousePosition := nil!
- arguments := arguments!

Item was added:
+ ----- Method: MenuMorph>>releasesSelection: (in category 'events') -----
+ releasesSelection: evt
+ " The MenuMorph releases its selection if the selected item releases it.
+ Used in #selectItem:event: "
+
+ self selectedItem ifNil: [ ^true ].
+ (self selectedItem containsPoint: evt position) ifTrue: [ ^true ].
+ ^self selectedItem releasesSelection: evt!